i draw table as it: Draw custom borders for table with more flexibility in itext7
But i But with big data the table is badly drawn height cell in table.
PdfDocument pdfDoc = new PdfDocument(new PdfWriter("_testPd/dashed_underline.pdf"));
Document doc = new Document(pdfDoc, PageSize.A5);
Table table = new Table(3).useAllAvailableWidth().setFixedLayout();
table.addCell("Highway System that runs east from the Indiana state line near Lake Michigan through the southern Lower Peninsula to Detroit, then n");
table.addCell("Highway System that runs east from the Indiana state line near Lake Michigan through the southern Lower Peninsula to Detroit, then n");
table.addCell("Highway System that runs east from the Indiana state line near Lake Michigan through the southern Lower Peninsula to Detroit, then n");
table.addCell("Pell morbi tristique senectus et netus et malesuada fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae, ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam egestas semper. Aenean ultricies mi vitae est. Mauris placerat eleifend leo. Quisque sit amet est et sapien ullamcorper pharetra. Vestibulum erat wisi, condimentum sed, commodo vitae, ornare sit amet, wisi. Aenean fermentum, elit eget tincidunt condimentum, eros ipsum rutrum orci, sagittis tempus lacus enim ac dui. Donec non enim in turpis pulvinar facilisis. Ut felis. Praesent dapibus, neque id cursus faucibus, tortor neque egestas augue, eu vulputate magna eros eu erat. Aliquam erat volutpat. Nam dui mi, tincidunt quis, accumsan porttitor, facilisis luctus, metus");
table.setNextRenderer(new CustomTableRenderer(table));
doc.add(table);
doc.close();
also one example:
Table table = new Table(3);
table.addCell("hello1 ");
table.addCell("hello2 ");
table.addCell("hello3 ");
table.addCell("hello4\nWord ");
table.addCell("hello5 ");
There is a minor mistake in your custom renderer: the items of heights list represent rows from the highest to the lowest, but you're drawing the borders from the lowest to the highest.
The following code should be used to draw horizontal lines:
// Draw horizontal lines
float curY = getOccupiedAreaBBox().getTop();
for (int i = 0; i <= heights.size(); i++) {
canvas.moveTo(getOccupiedAreaBBox().getLeft() - 3, curY);
canvas.lineTo(getOccupiedAreaBBox().getRight() + 3, curY + r.nextInt(4));
if (i < heights.size()) {
float curHeight = heights.get(i);
curY -= curHeight;
}
}
Related
I am trying to stitch together multiple multi-line strings together to create the effect of several columns of text. Consider the three text blocks below:
Lorem ipsum dolor si
t amet, consectetur
adipiscing elit, sed
do eiusmod tempor in
cididunt ut labore e
t dolore magna aliqu
a.
Volutpat consequat m
auris nunc congue ni
si vitae. Sed risus
ultricies tristique
nulla aliquet enim t
ortor at auctor.
Urna porttitor rhonc
us dolor purus non.
Interdum varius sit
amet mattis vulputat
e enim nulla.
The block width is fixed at 20 characters. Ignore the wrapping of words.
What I want to do is stitch or append these separate multi-line strings together to produce the following:
Lorem ipsum dolor si Volutpat consequat m Urna porttitor rhonc
t amet, consectetur auris nunc congue ni us dolor purus non.
adipiscing elit, sed si vitae. Sed risus Interdum varius sit
do eiusmod tempor in ultricies tristique amet mattis vulputat
cididunt ut labore e nulla aliquet enim t e enim nulla.
t dolore magna aliqu ortor at auctor.
a.
In this case, the column spacing is 4 characters wide.
Is anyone aware of a Java library or utility that facilitates this? If not implemented in Java, is there anything that could do this, that could be invoked from Java code?
I have a List<String> emails containing emails, of length n , and another List<String> keywords for containing keywords, of the same length. These lists should meet following condition: For each index i emails.get(i).contains(keywords.get(i))
So, if emails.get(0) == "quick brown fox", then keywords.get(0) == "fox".
if emails.get(5) == "foo bar", then keywords.get(5) == "foo".
How can I check (other than for loop) that each email contains a keyword?
First, it may be needed to check the size of both lists, then to compare corresponding list items, IntStream should be used:
public static boolean allKeywordsFound(List<String> emails, List<String> keywords) {
return emails.size() == keywords.size() &&
IntStream.range(0, emails.size())
.allMatch(i -> emails.get(i).contains(keywords.get(i)));
}
I see that others correctly answered your question but here's my take on the issue.
I presume you want the emails to be checked in order so here's a piece of code that uses Stream API instead of a for loop, I also put together the emails list and the result into a Map since you didn't specify whether you want the resulting boolean value to be for all the emails together or if you want a boolean value for each email containing the same-position keyword:
//mock data initialization
List<String> emails = new ArrayList<>();
List<String> keywords = new ArrayList<>();
//mock data initialization
emails.add("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua");
emails.add("eu lobortis elementum nibh tellus molestie nunc non blandit massa enim nec dui nunc mattis enim ut tellus elementum sagittis");
emails.add("Dignissim suspendisse in est ante in nibh mauris");
//mock data initialization
keywords.add("consectetur");
keywords.add("Foo");
keywords.add("Dignissim");
//initialized a list to contain whether a keyword exists for each email
List<Boolean> exists = new ArrayList<>();
//loaded it with boolean values (the exists List has the same order as the emails list)
emails.forEach(email -> exists.add(email
.contains(keywords
.get(emails
.indexOf(email)))));
//since I don't know what you wanna do with the result, I decided to just put them together in a Map
//with the email string as the key and the existence variable as a value
LinkedHashMap mapOfTruth = new LinkedHashMap();
emails.forEach(email -> mapOfTruth.put(email, exists.get(emails.indexOf(email))));
Output
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua = true
eu lobortis elementum nibh tellus molestie nunc non blandit massa enim nec dui nunc mattis enim ut tellus elementum sagittis = false
Dignissim suspendisse in est ante in nibh mauris = true
This code using Java streams/maps checks if each email contains their respective keyword.
boolean allEmailsContainKeyword(List<String> emails, List<String> keywords) {
return !emails.stream().map(email -> email.contains(keywords.get(emails.indexOf(email)))).collect(Collectors.toList()).contains(false);
}
I would like to have 2 sections on the same page in XWPFDocument. First section should have only 1 column, second section should have 2 columns. Currently, I am using following code:
CTBody body = document.getDocument().getBody();
// 1-column section
section = body.addNewSectPr();
columns = CTColumns.Factory.newInstance();
columns.setNum(new BigInteger("1"));
section.setCols(columns);
paragraph = document.createParagraph();
paragraph.getCTP().addNewPPr().setSectPr(section);
run = paragraph.createRun();
run.setText(firstSectionContent);
//2-column section
section = body.addNewSectPr();
columns = CTColumns.Factory.newInstance();
columns.setNum(new BigInteger("2"));
section.setCols(columns);
paragraph = document.createParagraph();
paragraph.getCTP().addNewPPr().setSectPr(section);
run = paragraph.createRun();
run.setText(secondSectionContent);
This produces 2 sections with correct number of columns, but the sections are not on the same page. How to apply continuous section break instead of next page section break?
The CTSectPr needs to be of CTSectType CONTINUOUS.
Example:
import java.io.File;
import java.io.FileOutputStream;
import java.math.BigInteger;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.apache.poi.xwpf.usermodel.BreakType;
import org.apache.poi.xwpf.usermodel.Borders;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTDocument1;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBody;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSectPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTColumns;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTColumn;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STOnOff;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTDocGrid;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STDocGrid;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STSectionMark;
public class Word2ColumnPage {
public static void main(String[] args) throws Exception {
XWPFDocument document= new XWPFDocument();
XWPFParagraph paragraph = document.createParagraph();
XWPFRun run=paragraph.createRun();
run.setText("One column on top. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.");
paragraph = document.createParagraph();
//paragraph with section setting for one column section above
paragraph = document.createParagraph();
CTSectPr ctSectPr = paragraph.getCTP().addNewPPr().addNewSectPr();
CTColumns ctColumns = ctSectPr.addNewCols();
ctColumns.setNum(BigInteger.valueOf(1));
//left column
paragraph = document.createParagraph();
run=paragraph.createRun();
run.setText("The left side");
paragraph = document.createParagraph();
run=paragraph.createRun();
run.setText("Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.");
paragraph = document.createParagraph();
// right column
//paragraph with column break
paragraph = document.createParagraph();
run=paragraph.createRun();
run.addBreak(BreakType.COLUMN);
run=paragraph.createRun();
run.setText("The right side");
//left border for the paragrapphs on right side
paragraph.setBorderLeft(Borders.THREE_D_EMBOSS);
paragraph.getCTP().getPPr().getPBdr().getLeft().setSz(BigInteger.valueOf(20));
paragraph = document.createParagraph();
run=paragraph.createRun();
run.setText("Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.");
paragraph.setBorderLeft(Borders.THREE_D_EMBOSS);
paragraph.getCTP().getPPr().getPBdr().getLeft().setSz(BigInteger.valueOf(20));
paragraph = document.createParagraph();
paragraph.setBorderLeft(Borders.THREE_D_EMBOSS);
paragraph.getCTP().getPPr().getPBdr().getLeft().setSz(BigInteger.valueOf(20));
//paragraph with section break continuous for two column section above
paragraph = document.createParagraph();
ctSectPr = paragraph.getCTP().addNewPPr().addNewSectPr();
ctSectPr.addNewType().setVal(STSectionMark.CONTINUOUS);
ctColumns = ctSectPr.addNewCols();
ctColumns.setNum(BigInteger.valueOf(2));
ctColumns.setEqualWidth(STOnOff.OFF);
ctColumns.setSep(STOnOff.ON);
CTColumn ctColumn = ctColumns.addNewCol();
ctColumn.setW(BigInteger.valueOf(6000));
ctColumn.setSpace(BigInteger.valueOf(300));
ctColumn = ctColumns.addNewCol();
ctColumn.setW(BigInteger.valueOf(3000));
paragraph.setBorderLeft(Borders.THREE_D_EMBOSS);
paragraph.getCTP().getPPr().getPBdr().getLeft().setSz(BigInteger.valueOf(20));
paragraph = document.createParagraph();
run=paragraph.createRun();
run.setText("One column on bottom");
paragraph = document.createParagraph();
run=paragraph.createRun();
run.setText("Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.");
//section setting continuous for one column section above
CTDocument1 ctDocument = document.getDocument();
CTBody ctBody = ctDocument.getBody();
ctSectPr = ctBody.addNewSectPr();
ctSectPr.addNewType().setVal(STSectionMark.CONTINUOUS);
ctColumns = ctSectPr.addNewCols();
ctColumns.setNum(BigInteger.valueOf(1));
FileOutputStream out = new FileOutputStream("Word2ColumnPage.docx");
document.write(out);
out.close();
document.close();
}
}
Up to apache poi 4.1.2 this code needs the full jar of all of the schemas ooxml-schemas-*.jar as mentioned in FAQ-N10025.
The principle of sections having multiple columns in Word are as follows:
Per default - using no special settings - Word uses a one column section.
If section settings shall change, then a paragraph with section settings for the section above is needed. All body elements above that paragraph use those settings. All body elements after that paragraph are in a new section and use settings of next paragraph having section settings or use sections settings in document body.
At last section settings for last section above needs to be in body settings.
Using apache poi 5.0.0 the org.openxmlformats.schemas.wordprocessingml.x2006.main.STOnOff was removed in poi-ooxml-full-5.0.0.jar. And CTColumns.setEqualWidth and CTColumns.setSep uses java.langObject as attribute type now.
So it would must be now:
//ctColumns.setEqualWidth(STOnOff.OFF);
ctColumns.setEqualWidth("0");
//ctColumns.setSep(STOnOff.ON);
ctColumns.setSep("1");
What I am trying to achieve is to match all words in text, but ignore those words in line (before new line) that start with 4 whitespaces.
Example
Text file to find words:
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
enim ad minim veniam, quis nostrud exercitation ullamco laboris
nisi ut aliquip ex ea commodo consequat.
This must NOT be matched. Because it has 4 whitespaces at the beginning.
Lorem ipsum dolor sit amet. Ut enim ad minim veniam.
So, the words in following line should be NOT considered to match pattern:
This must NOT be matched. Because it has 4 whitespaces at the beginning.
Code
Here is my regex and it can find all words:
\\b[A-Za-z]+\\b
I know that in Java's RegEx syntax there is except which is ^ symbol but I only know how to use it in more simple expressions.
Maybe following snippet could be a basis for what you want to achieve.
String[] lines = {"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do",
"eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut",
"enim ad minim veniam, quis nostrud exercitation ullamco laboris",
"nisi ut aliquip ex ea commodo consequat.",
"",
" This must NOT be matched. Because it has 4 whitespaces at the beginning.",
"",
"Lorem ipsum dolor sit amet. Ut enim ad minim veniam."};
for (String line : lines) {
if (!line.startsWith(" ")) {
String[] words = line.split("[\\p{IsPunctuation}\\p{IsWhite_Space}]+");
System.out.println("words = " + Arrays.toString(words));
}
}
output
words = [Lorem, ipsum, dolor, sit, amet, consectetur, adipiscing, elit, sed, do]
words = [eiusmod, tempor, incididunt, ut, labore, et, dolore, magna, aliqua, Ut]
words = [enim, ad, minim, veniam, quis, nostrud, exercitation, ullamco, laboris]
words = [nisi, ut, aliquip, ex, ea, commodo, consequat]
words = []
words = []
words = [Lorem, ipsum, dolor, sit, amet, Ut, enim, ad, minim, veniam]
PS: the regex has been borrowed from this answer
The following should do that
(?<!\s{4})\\b[A-Za-z]+\\b
It begins with a negative lookbehind so it won't match anything with \s{4} preceding it.
This question already has answers here:
Using == operator in Java to compare wrapper objects
(8 answers)
Closed 7 years ago.
Why the Integer objects do not behave the way String objects behave?
I read that the reason was performance but can not understand how it would perform better?
Look at the code below for example :
public class MyClass{
public static void main(String[] args){
String one = "myString";
String two = "myString";
System.out.println(one == two); // true
String oneLong = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus in leo at massa vehicula rhoncus quis eu mauris. Pellentesque non nulla convallis, tempus augue sed, sollicitudin risus. Aenean posuere nulla ipsum, at faucibus massa dignissim non. Duis felis felis, iaculis eu posuere id, elementum id nulla. Fusce tristique arcu vitae consectetur vehicula. Mauris tincidunt nunc placerat tortor rhoncus, eget venenatis felis dapibus. Sed scelerisque ligula congue ligula elementum hendrerit. Proin et mauris vestibulum, rutrum ante ut, sollicitudin massa. Fusce tempus mattis eleifend. Phasellus ut ante turpis. Suspendisse eu leo nec elit ornare rhoncus sed nec ex. In at tellus mi.";
String twoLong = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus in leo at massa vehicula rhoncus quis eu mauris. Pellentesque non nulla convallis, tempus augue sed, sollicitudin risus. Aenean posuere nulla ipsum, at faucibus massa dignissim non. Duis felis felis, iaculis eu posuere id, elementum id nulla. Fusce tristique arcu vitae consectetur vehicula. Mauris tincidunt nunc placerat tortor rhoncus, eget venenatis felis dapibus. Sed scelerisque ligula congue ligula elementum hendrerit. Proin et mauris vestibulum, rutrum ante ut, sollicitudin massa. Fusce tempus mattis eleifend. Phasellus ut ante turpis. Suspendisse eu leo nec elit ornare rhoncus sed nec ex. In at tellus mi.";
System.out.println(oneLong == twoLong); // true
Integer first = 1;
Integer second = 1;
System.out.println(first == second); // true
Integer third = 500;
Integer fourth = 500;
System.out.println(third == fourth); // false
}
}
Here are the questions I found but no response was given there :
Why Integer In Java is Immutable
Is Integer Immutable?
Generally is a good idea to mantain an object as immutable as possible because an immutable object can be shared without problems in a multithreading enviroment.
Creating n copies of the same Integer is possible, ma that copies are immutable. Note that also for String is possible to create n different copies of the same String. To do that you need to explicitly use the new keyword.
Two objects are the same if compared with the operator == returns true. Two objects have the same content if compared with the method equals returns true.
obj1 == obj2 // if true obj1 and obj2 are the same
obj1.equals(obj2) // if true obj1 and obj2 have the same content
// (can be the same or not)
In your example you have two Integer with the same content (so equals returns true) but different memory locations (so == returns false)