itext-rtf Table within a Cell - java

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));
}

Related

poi ms-word Can you make a table in the table?

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.

How to give separations between the cells of a table in Itext7?

Problem Statement:-
I am using Itext7 in JAVA to create a PDF having a table. I need to give the separations between the cells of the table.
Red and blue arrows in the image are the pin points from where I want to separate them.
Any help regarding the issue is highly appreciated!!
Code:-
package com.example.pdfcreator;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import com.itextpdf.*;
#SpringBootApplication
public class PdfcreatorApplication {
public static final String DEST = "D:\\generate_pdf\\hello.pdf";
public static void main(String args[]) throws IOException, java.io.IOException {
PdfDocument pdf = new PdfDocument(new PdfWriter(DEST));
Document document = new Document(pdf);
var table = new Table(new float[] { 3,3,3,3,3,3,3}).setWidth(UnitValue.createPercentValue(100)).setFixedLayout().setFontSize(8).setMarginTop(4);
Cell cell11 = new Cell(1, 2).setBorder(Border.NO_BORDER).add(new Paragraph("label1 :"));
Cell cell12 = new Cell(1, 5).add(new Paragraph(""));
Cell cell21 = new Cell(1, 2).setBorder(Border.NO_BORDER).add(new Paragraph("label2 :"));
Cell cell22 = new Cell(1, 5).add(new Paragraph(""));
Cell cell31 = new Cell(1, 2).setBorder(Border.NO_BORDER).add(new Paragraph("label3 :"));
Cell cell32 = new Cell(1, 5).add(new Paragraph(""));
Cell cell41 = new Cell(1, 2).setBorder(Border.NO_BORDER).add(new Paragraph("label4 :"));
Cell cell42 = new Cell(1, 5).add(new Paragraph(""));
table.addCell(cell11);
table.addCell(cell12);
table.addCell(cell21);
table.addCell(cell22);
table.addCell(cell31);
table.addCell(cell32);
table.addCell(cell41);
table.addCell(cell42);
document.add(table);
var table99 = new Table(new float[] { 3,3,3,3,3,3,3}).setWidth(UnitValue.createPercentValue(100)).setFixedLayout().setFontSize(8);
Cell cell = new Cell(1,2).setBorder(Border.NO_BORDER).add(new Paragraph("label9 : "));
table99.addCell(cell);
cell = new Cell(1,4).add(new Paragraph(" "));
table99.addCell(cell);
Cell cell23 = new Cell(5, 1).add(new Paragraph("Photo").setMarginLeft(23).setMarginTop(28));
table99.addCell(cell23);
cell = new Cell(1,2).setBorder(Border.NO_BORDER).add(new Paragraph(" label10: "));
table99.addCell(cell);
cell = new Cell(1,4).add(new Paragraph(" "));
table99.addCell(cell);
cell = new Cell(1,2).setBorder(Border.NO_BORDER).add(new Paragraph(" label11: "));
table99.addCell(cell);
cell = new Cell(1,4).add(new Paragraph(" "));
table99.addCell(cell);
cell = new Cell(1,2).setBorder(Border.NO_BORDER).add(new Paragraph(" label12: "));
table99.addCell(cell);
cell = new Cell(1,4).add(new Paragraph(" "));
table99.addCell(cell);
cell = new Cell(1,2).setBorder(Border.NO_BORDER).add(new Paragraph(" label13: "));
table99.addCell(cell);
cell = new Cell(1,4).add(new Paragraph(" "));
table99.addCell(cell);
document.add(table99); }}
I have given the seperations using the empty cells with borders removed and it has worked properly as per my requirement. Demo code line which i have implemented are written as below.
I have created one style in which i have given the minimum height required for my spacing and removed the borders from the cell.
Style spacingCellStyle = new Style().setBorder(Border.NO_BORDER).setHeight(1);
Then, i have simply just added the cell with this style wherever in the table, spacing was required.
Table.addCell(new Cell(1, 6).addStyle(spacingCellStyle));
As per my requirement, this was the only possible way to do so and it executed perfectly.

iText split tables printing multiple times

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);

Redesign output by removing left cell

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);

How to show dynamic List in PDFTable in iText

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

Categories