I am trying to split a table after x rows so I do not have an orphaned signature block on a page (i.e., there is always at least one row of the table before the signature block on the page). In my test I have six rows to be printed in the table. The first set of two is being printed once the second set is printed as two identical tables with three blank rows between them the third set is printed as three identical tables with three blank rows between them.
How do I remove the duplicate tables please? The code is:
Paragraph preface = new Paragraph();
PdfPTable table = new PdfPTable(3);
table.setWidths(new int[]{1, 3, 1});
table.setHeaderRows(1);
PdfPCell c1 = new PdfPCell(new Phrase("Section"));
c1.setHorizontalAlignment(Element.ALIGN_CENTER);
table.addCell(c1);
c1 = new PdfPCell(new Phrase("Award"));
c1.setHorizontalAlignment(Element.ALIGN_CENTER);
table.addCell(c1);
c1 = new PdfPCell(new Phrase("Date"));
c1.setHorizontalAlignment(Element.ALIGN_CENTER);
table.addCell(c1);
table.setHeaderRows(1);
String storedName = null;
int noRows = 0;
DateFormat df1 = new SimpleDateFormat("yyyy-MM-dd");
DateFormat df2 = new SimpleDateFormat("dd-MM-yyyy");
for (final Transcript scoutNamesDescription : listymAwards) {
if (noRows > 1){ // Change this to number of rows required
noRows = 0;
preface.add(table);
document.add(preface);
document.newPage();
// We add three empty lines
addEmptyLine(preface, 1);
addEmptyLine(preface, 1);
addEmptyLine(preface, 1);
table.flushContent();
}
noRows++;
if (scoutNamesDescription.getSection().equals(storedName)){
table.addCell(" ");
}else{
storedName = scoutNamesDescription.getSection();
table.addCell(scoutNamesDescription.getSection());
}
table.addCell(scoutNamesDescription.getAwardName());
Date awardedDate = df1.parse(scoutNamesDescription.getAwardedDate());
String awardedString = df2.format(awardedDate);
table.addCell(awardedString);
}
preface.add(table);
document.add(preface);
Related
Can you make a table in the compartment inside the table like case 2?
Can you make a table in the compartment inside the table like case 2?
enter image description here
public class PoiTest3 {
public static void main(String[] args) throws Exception {
try (XWPFDocument doc = new XWPFDocument()) {
XWPFTable table = doc.createTable();
//Creating first Row
XWPFTableRow row1 = table.getRow(0);
row1.getCell(0).setText("First Row, First Column");
row1.addNewTableCell().setText("First Row, Second Column");
row1.addNewTableCell().setText("First Row, Third Column");
//Creating second Row
XWPFTableRow row2 = table.createRow();
row2.getCell(0).setText("Second Row, First Column");
row2.getCell(1).setText("Second Row, Second Column");
row2.getCell(2).setText("Second Row, Third Column");
//create third row
XWPFTableRow row3 = table.createRow();
row3.getCell(0).setText("Third Row, First Column");
row3.getCell(1).setText("Third Row, Second Column");
row3.getCell(2).setText("Third Row, Third Column");
// save to .docx file
try (FileOutputStream out = new FileOutputStream("c:\\excel\\table.docx")) {
doc.write(out);
}
}
}
}
XWPFTableCell is a IBody. So it provides XWPFTable insertNewTbl(org.apache.xmlbeans.XmlCursor cursor). So yes, it is possible to add a table into a table cell.
But the usage of that org.apache.xmlbeans.XmlCursor is not well documented.
To create that cursor we need the table cell, the cursor shall be in, and an new empty paragrsph in that cell. The empty paragrsph is needed because all content we insert using that cursor will be before the element the cursor points to. So that element should be an empty paragraph to avoid inserting content into existing elements like paragraphs with content or other content containing elements.
The following shows the simplest possible complete example.
import java.io.FileOutputStream;
import org.apache.poi.xwpf.usermodel.*;
public class CreateWordTableInTable {
public static void main(String[] args) throws Exception {
try (XWPFDocument doc = new XWPFDocument()) {
//create main table
XWPFTable table = doc.createTable();
//create rows and cells
XWPFTableRow row = table.getRow(0);
row.getCell(0).setText("Main table A1");
row.addNewTableCell().setText("Main table B1");
row.addNewTableCell().setText("Main table C1");
row = table.createRow();
row.getCell(0).setText("Main table A2");
row.getCell(1).setText("Main table B2");
row.getCell(2).setText("Main table C2");
//create inner table
//we need the first table cell and an new empty paragrsph in that first cell
row = table.getRow(0);
XWPFTableCell cell = row.getTableCells().get(0);
XWPFParagraph paragraph = cell.addParagraph();
//now we can insert a table there
org.apache.xmlbeans.XmlCursor cursor = paragraph.getCTP().newCursor();
XWPFTable innerTable = cell.insertNewTbl(cursor);
//set table borders
innerTable.setTopBorder(XWPFTable.XWPFBorderType.SINGLE, 4, 0, "000000");
innerTable.setRightBorder(XWPFTable.XWPFBorderType.SINGLE, 4, 0, "000000");
innerTable.setBottomBorder(XWPFTable.XWPFBorderType.SINGLE, 4, 0, "000000");
innerTable.setLeftBorder(XWPFTable.XWPFBorderType.SINGLE, 4, 0, "000000");
innerTable.setInsideHBorder(XWPFTable.XWPFBorderType.SINGLE, 4, 0, "000000");
innerTable.setInsideVBorder(XWPFTable.XWPFBorderType.SINGLE, 4, 0, "000000");
//create rows and cells
XWPFTableRow rowInInnerTable = innerTable.createRow();
XWPFTableCell cellInInnerTable = rowInInnerTable.createCell();
cellInInnerTable.setText("Inner table A1");
cellInInnerTable = rowInInnerTable.createCell();
cellInInnerTable.setText("Inner table B1");
cellInInnerTable = rowInInnerTable.createCell();
cellInInnerTable.setText("Inner table C1");
rowInInnerTable = innerTable.createRow();
cellInInnerTable = rowInInnerTable.getCell(0);
cellInInnerTable.setText("Inner table A2");
cellInInnerTable = rowInInnerTable.getCell(1);
cellInInnerTable.setText("Inner table B2");
cellInInnerTable = rowInInnerTable.getCell(2);
cellInInnerTable.setText("Inner table C2");
//save to .docx file
try (FileOutputStream out = new FileOutputStream("./CreateWordTableInTable.docx")) {
doc.write(out);
}
}
}
}
It produces:
This code is tested an works using the current Apache POI version 5.2.3. Download: https://poi.apache.org/download.html#POI-5.2.3. Needed components see https://poi.apache.org/components/index.html#components.
If you see the below table I have separated two cells one cell is added as a left cell(Name) and one more cell added as a table.
I have tried below code :
I am using the package as import com.lowagie.text.pdf.*;
PdfWriter.getInstance(document,
new FileOutputStream("C:/Temp/TableWidthAlignment.pdf"));
document.open();
//Main table
PdfPTable mainTable = new PdfPTable(2);
mainTable.setWidths(new int[] { 10,90 });
//cell one is Name cell
PdfPCell innerCellKeyName = new PdfPCell(new Phrase("Name", boldFont));
//innerCellKeyName.setBorder(Rectangle.NO_BORDER);
mainTable.addCell(innerCellKeyName);
PdfPTable table = new PdfPTable(3);
PdfPCell cell = new PdfPCell(new Paragraph("header with colspan 3"));
cell.setColspan(3);
table.addCell(cell);
table.addCell("1.1");
table.addCell("2.1");
table.addCell("3.1");
table.addCell("1.2");
table.addCell("2.2");
table.addCell("3.2");
table.addCell("4.1");
table.addCell("4.2");
table.addCell("4.3");
//cell two is as table
PdfPCell cell2 = new PdfPCell(table);
mainTable.addCell(cell2);
document.add(mainTable);
Output is:
Expected output is : Cross box need to be removed form box in the left cell.
I have tried some thing to make work out of expected result
Solution:
I have copy pasted the same above table and made the left cell as no boarder.
document.open();
PdfPTable mainTable = new PdfPTable(2);
mainTable.setWidths(new int[] { 10,90 });
PdfPCell innerCellKeyName = new PdfPCell(new Phrase("Name", boldFont));
//innerCellKeyName.setBorder(Rectangle.NO_BORDER);
mainTable.addCell(innerCellKeyName);
// step4
PdfPTable table = new PdfPTable(3);
PdfPCell cell = new PdfPCell(new Paragraph("header with colspan 3"));
cell.setColspan(3);
table.addCell(cell);
table.addCell("1.1");
table.addCell("2.1");
table.addCell("3.1");
table.addCell("1.2");
table.addCell("2.2");
table.addCell("3.2");
table.addCell("4.1");
table.addCell("4.2");
table.addCell("4.3");
PdfPCell cell2 = new PdfPCell(table);
mainTable.addCell(cell2);
document.add(mainTable);
PdfPTable mainTable2 = new PdfPTable(2);
mainTable2.setWidths(new int[] { 10,90 });
PdfPCell innerCellKeyName2 = new PdfPCell(new Phrase("", boldFont));
innerCellKeyName2.setBorder(Rectangle.NO_BORDER);
mainTable2.addCell(innerCellKeyName2);
// step4
PdfPTable table2 = new PdfPTable(3);
PdfPCell cell3 = new PdfPCell(new Paragraph("header with colspan 3"));
cell3.setColspan(3);
table2.addCell(cell3);
table2.addCell("1.1");
table2.addCell("2.1");
table2.addCell("3.1");
table2.addCell("1.2");
table2.addCell("2.2");
table2.addCell("3.2");
table2.addCell("4.1");
table2.addCell("4.2");
table2.addCell("4.3");
PdfPCell cell4 = new PdfPCell(table2);
mainTable2.addCell(cell4);
document.add(mainTable2);
I need your help in displaying the list of earnings which is retrieved from a database in a PDFTable in iText. The earnings will be having two columns which are: earnings_description and earnings_amount which are defined in a separate class called Earnings. The java code for retrieving them is:
List<Earnings> listEarnings = new ArrayList<Earnings>();
try{
Connection con = Database.getConnection();
PreparedStatement ps = con.prepareStatement("select * from Earnings");
List<Earnings> listEarnings = new ArrayList<Earnings>();
ResultSet rs = ps.executeQuery();
while (rs.next()) {
Earnings e = new Earnings();
e.setEarningsDescription(rs.getString("Earning_description"));
e.setEarningsAmount(rs.getString("Earning_amount"));
listEarnings.add(e);
}
catch(Exception e)){
System.out.println("Error");
}
However I tried to create a table to place the values under the headers, but I need some help. Below is the code:
PdfPTable table = new PdfPTable(2);
Font font = new Font(FontFamily.HELVETICA, 14, Font.BOLD, BaseColor.WHITE);
PdfPCell c1 = new PdfPCell(new Phrase("Earning Description"),font);
c1.setHorizontalAlignment(Element.ALIGN_CENTER);
table.addCell(c1);
c1 = new PdfPCell(new Phrase("Earning Amount"),font);
c1.setHorizontalAlignment(Element.ALIGN_CENTER);
table.addCell(c1);
Now I need your assistant in adding the values under each header.
First , you didn't post your get methods for earnings_description & earnings_amount,
So assuming they are getEarningsDescription() & getEarningsAmount(), but adapt them according to your Earnings class :
PdfPTable table = new PdfPTable(2);
Font font = new Font(FontFamily.HELVETICA, 14, Font.BOLD, BaseColor.WHITE);
PdfPCell c1 = new PdfPCell(new Phrase("Earning Description"),font);
c1.setHorizontalAlignment(Element.ALIGN_CENTER);
table.addCell(c1);
c1 = new PdfPCell(new Phrase("Earning Amount"),font);
c1.setHorizontalAlignment(Element.ALIGN_CENTER);
table.addCell(c1);
// Here's how you adding the values
for(int i=0;i<listEarnings.size();i++){
String temp1 = listEarnings.get(i).getEarningsDescription();
String temp2 =listEarnings.get(i).getEarningsAmount();
if(temp.equalsIgnoreCase("")){
temp="*"; // this fills the cell with * if the String is empty otherwise cell won't be created
}
if(temp2.equalsIgnoreCase("")){
temp2="*"; // this fills the cell with * if the String is empty otherwise cell won't be created
}
table.addCell( temp1 ); // rows for first column
table.addCell(temp2); // rows for seconds column
}
Note : don't forget to adapt those getEarningsDescription() & getEarningsAmount() accordingly
I'm using itext-rtf 2.1.7 to generate an RTF document.
The parameter table below for the method writeSectionHeaderTableInACell() will have two columns.
For each column, I need to insert a new inner Table, with two columns as well. This inner table will have the first column as left-aligned, and the second as right-aligned.
However, the code below causes a corrupted Table in the generated RTF document. The two inner Tables which supposed to be both on a single row, they appear as one row for each inner Table.
Anyone, has any idea why it seems we cannot add an inner Table within a Cell for RTF document? Thanks.
private static void writeSectionHeaderTableInACell(PdfPTable table) {
PdfPTable sectionTable1 = new PdfPTable(2);
Phrase phrase1 = new Phrase("? 1 ?", FontFactory.getFont("MS Mincho", 10, Font.NORMAL));
Paragraph p1 = new Paragraph(phrase1);
p1.setAlignment(Element.ALIGN_LEFT);
PdfPCell cell1 = new PdfPCell(p1);
sectionTable1.addCell(cell1);
Phrase phrase2 = new Phrase("2 Chi", FontFactory.getFont("MS Mincho", 10, Font.NORMAL));
Paragraph p2 = new Paragraph(phrase2);
p2.setAlignment(Element.ALIGN_RIGHT);
PdfPCell cell2 = new PdfPCell(p2);
sectionTable1.addCell(cell2);
table.addCell(new PdfPCell(sectionTable1));
PdfPTable sectionTable2 = new PdfPTable(2);
Phrase phrase3 = new Phrase("Section 1", FontFactory.getFont("Times New Roman", 10, Font.NORMAL));
Paragraph p3 = new Paragraph(phrase3);
p3.setAlignment(Element.ALIGN_LEFT);
PdfPCell cell3 = new PdfPCell(p3);
sectionTable2.addCell(cell3);
Phrase phrase4 = new Phrase("2 Eng", FontFactory.getFont("Times New Roman", 10, Font.NORMAL));
Paragraph p4 = new Paragraph(phrase4);
p4.setAlignment(Element.ALIGN_RIGHT);
PdfPCell cell4 = new PdfPCell(p4);
sectionTable2.addCell(cell4);
table.addCell(new PdfPCell(sectionTable2));
}
I have a lot of small tables, which i encapsulate in a sorrounding 1x1 table, and set the SplitRows attribute to false on the sorrounding table. This way, i can avoid my table getting split when it reaches the bottom of a page. When i get to the end of a page, and there is a little space for text, but not enough for the next table, iText doesn't add the table at all, but continues to add the next table in the list.
If there is not enough space for the table on the current page, id like to send it to the next. What can i do?
http://compgroups.net/comp.text.pdf/Avoid-page-breaks-in-PdfPTable-using-iText-1.2
This is my code:
public static void CreateMatrixProcentQuestionTable(ShowQuestionViewModel model, Document doc)
{
ShowMatrixQuestionViewModel sm = (ShowMatrixQuestionViewModel)model;
Font fontsize = new Font(Font.FontFamily.HELVETICA, 9f);
Font QuestionFont = new Font(Font.FontFamily.HELVETICA, 12f);
PdfPTable table = new PdfPTable(sm.columns.Count + 2);
// Tilføj spørgsmålet i en række for sig selv, ellers er der chance for at
// svarmulighederne ikke kommer med ved page breaks
PdfPCell question = new PdfPCell(new Phrase(sm.Question_Wording + Environment.NewLine, QuestionFont));
question.Border = Rectangle.NO_BORDER;
question.Colspan = table.NumberOfColumns;
table.AddCell(question);
// Tilføj et mellemrum mellem spørgsmålet og svarmulighederne
PdfPCell mellemrum = new PdfPCell(new Phrase(Environment.NewLine));
mellemrum.Border = Rectangle.NO_BORDER;
mellemrum.Colspan = table.NumberOfColumns;
table.AddCell(mellemrum);
// Tilføj rækker og kolonner
// Dette er den første tomme celle
table.AddCell(new PdfPCell(new Phrase("", fontsize)));
foreach (MatrixColumns column in sm.columns)
{
PdfPCell cell = new PdfPCell(new Phrase(column.Column_Description, fontsize));
cell.HorizontalAlignment = 1;
table.AddCell(cell);
}
PdfPCell ialt = new PdfPCell(new Phrase("I alt", fontsize));
ialt.HorizontalAlignment = 1;
table.AddCell(ialt);
foreach (var pair in sm.columnrow)
{
MatrixRows row = pair.Key;
PdfPCell rowcell = new PdfPCell(new Phrase(row.Row_Description == null ? "*" : row.Row_Description, fontsize));
rowcell.HorizontalAlignment = 1;
table.AddCell(rowcell);
foreach (MatrixColumns column in pair.Value)
{
PdfPCell cell = new PdfPCell(new Phrase("%", fontsize));
cell.HorizontalAlignment = Element.ALIGN_RIGHT;
table.AddCell(cell);
}
PdfPCell sumcell = new PdfPCell(new Phrase("100%", fontsize));
sumcell.HorizontalAlignment = Element.ALIGN_RIGHT;
table.AddCell(sumcell);
}
// Man laver en 1x1 table uden om den rigtige table, og sætter
// SplitRows = False. Dette gør at tabellen ikke bliver knækket over
// ved page breaks
PdfPTable sorroundingTable = new PdfPTable(1);
PdfPCell innerTable = new PdfPCell(table);
innerTable.Border = Rectangle.NO_BORDER;
sorroundingTable.AddCell(innerTable);
sorroundingTable.SplitRows = false;
doc.Add(sorroundingTable);
doc.Add(new Phrase(Environment.NewLine));
}
This solves the problem:
table.setKeepTogether(true)
document.add(table)