I am using iText library to print certain data in table format in a pdf file. I have 11 columns and can have multiple rows. After creating header for titles of each column, how do I create a new row in pdfptable so that I can print the real data on a separate row.
In the constructor of PdfPTable you specify the number of columns in a row.
PdfPTable table = new PdfPTable(4) // 4 Columns
PdfPCell cell;
cell = new PdfPCell( new Phrase("Cell with colspan of 4") ) ;
cell. setColspan(4) ; // an entire row
anotherCell = new PdfPCell( new Phrase("Cell with colspan of 4") );
anotherCell.setColspan(4); // a second row
As you can see, a new row is created when you reach the colspan in the current row.
Related
I made an export pdf system using the java Itext pdf library, but there is a problem when I want to split the data of each page, I want to dynamically divide the data of each page using input, how to do it?like the code below, but the result is not as expected
//looping data row
PdfPTable itemTable = new PdfPTable(headerColumns.length);
itemTable.setWidthPercentage(100);
for(int i = 0;i< data.size();i++){
// header area
PdfPCell area = new PdfPCell(new Phrase(data.get(i).get("area").toString()));
area.setPaddingLeft(4);
area.setVerticalAlignment(Element.ALIGN_MIDDLE);
area.setHorizontalAlignment(Element.ALIGN_CENTER);
itemTable.addCell(area);
// header new_sa
PdfPCell newSa = new PdfPCell(new Phrase(data.get(i).get("new_sa").toString()));
newSa.setPaddingLeft(4);
newSa.setVerticalAlignment(Element.ALIGN_MIDDLE);
newSa.setHorizontalAlignment(Element.ALIGN_CENTER);
itemTable.addCell(newSa);
// header new_sa
PdfPCell saMtd = new PdfPCell(new Phrase(data.get(i).get("sa_mtd").toString()));
saMtd.setPaddingLeft(4);
saMtd.setVerticalAlignment(Element.ALIGN_MIDDLE);
saMtd.setHorizontalAlignment(Element.ALIGN_CENTER);
itemTable.addCell(saMtd);
// header sa_last_month
PdfPCell saLastMonth = new PdfPCell(new Phrase(data.get(i).get("sa_last_month").toString()));
saLastMonth.setPaddingLeft(4);
saLastMonth.setVerticalAlignment(Element.ALIGN_MIDDLE);
saLastMonth.setHorizontalAlignment(Element.ALIGN_CENTER);
itemTable.addCell(saMtd);
//set maxmimum data per page 2
if(itemTable.getRows().size() == 2){
document.newPage();
}
document.add(table);
document.add(itemTable);
}
document.close();
pdf result of the code above
picture page 1
picture page 2
In a comment you clarified
the results that I expect, such as data per page for example 2 , in the results of the image I include it is like a bug where the data on the initial page is 1 but the data is repeated on the 2nd page
If you don't want the data to repeat, then you should not add the same itemTable object again and again but instead create a new one at the start of the loop.
I.e. you should pull the two lines into the loop that currently are before the loop, instead of
PdfPTable itemTable = new PdfPTable(headerColumns.length);
itemTable.setWidthPercentage(100);
for(int i = 0;i< data.size();i++){
...
document.add(itemTable);
}
use
for(int i = 0;i< data.size();i++){
PdfPTable itemTable = new PdfPTable(headerColumns.length);
itemTable.setWidthPercentage(100);
...
document.add(itemTable);
}
I have a list of 100 records and i want to make a table in pdf with 3 columns. My problem is once the pdf file has been made it's 33 rows with 3 columns so it's 99 records not 100. How can i show the other one record in pdf table?
here is my code:
Document document = new Document(PageSize.A4, -60f, -60f, 18f, 5f);
PdfPTable table = new PdfPTable(3);
PdfPCell cell;
if (filterPins.size() > 0) {
for (int i = 0; i < filterPins.size(); i++) {
Bitmap bmp = getRecyclerViewScreenshot(pinList, i);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.JPEG, 100, stream);
Image image = Image.getInstance(stream.toByteArray());
cell = new PdfPCell(image, true);
cell.setPadding(0f);
cell.setBorder(Rectangle.NO_BORDER);
table.addCell(cell);
}
File myDirectory = new File(rootView.getContext().getFilesDir(), String.valueOf(factorNo));
if (!myDirectory.exists()) {
myDirectory.mkdirs();
}
File pdfFile = new File(myDirectory, fileName);
PdfWriter.getInstance(document, new FileOutputStream(pdfFile));
document.open();
document.add(table);
document.close();
}
filterPins is my arrayList containing 100 records.
How can i show the other one record in pdf table?
First of all that also is a question you have to ask yourself. Do you want the 100th entry fill only a single of the three cells of a row? If yes, which one? Or should it span the whole row? Or would you prefer yet another construct?
Let's assume, though, you simply want the 100th entry to be the first cell in the 34th row and you also want the other cells in that row to be empty. In that case there is a PdfPTable utility method that fills the current row with empty cells (copies of the default cell):
table.completeRow();
if(yourlist.size() % 3 == 0){
int totalRows = yourlist.size() / 3;
create your pdf.
for example list.size() = 99 then you create 33 rows each row have 3 column.
}
else
{
int totalRows = yourlist.size() / 3;
for example if yourlist.size() = 100.
then first create 33 row each row have 3 column.
remaining 1 item add in new list after created 33 rows.
remaining 1 or 2 column add in new row.
Note : in any case you have remaining only 1 or 2.
}
The following is the format I want to generate:
From my limited experience of the API I know how to make a list
ListFormat listFormat = builder.getListFormat();
listFormat.setList(document.getLists().add(ListTemplate.NUMBER_DEFAULT));
builder.writeln("Component Specification")
listFormat.setListLevelNumber(1);
builder.writeln("Raw Material Specification")
Now how do I transition from the list to the table below?
writing a new line adds numbers, even in the cells of the table.
If I set the listformat to null then the indentation is lost. I want to maintain the indentation of the list but also add the table below that list value
Anyway to do that?
#Furqan,
You need to set Table LeftIndent property for your requirements. Please check following sample code snippet.
I am Tilal Ahmad, developer evangelist at Aspose.
Document doc= new Document();
DocumentBuilder builder= new DocumentBuilder(doc);
ListFormat listFormat = builder.getListFormat();
listFormat.setList(doc.getLists().add(ListTemplate.NUMBER_DEFAULT));
builder.writeln("Component Specification");
builder.getListFormat().listIndent();
builder.getListFormat().getListLevel().setNumberStyle(NumberStyle.ARABIC);
builder.getListFormat().getListLevel().setNumberFormat("\u0000.\u0001");
builder.writeln("Raw Material Specification");
builder.getListFormat().removeNumbers();
Table table = new Table(doc);
// Add the table to the document.
doc.getFirstSection().getBody().appendChild(table);
Row row1 = new Row(doc);
row1.getRowFormat().setAllowBreakAcrossPages(true);
table.appendChild(row1);
// Create a cell and add it to the row
Cell cell1 = new Cell(doc);
cell1.getCellFormat().getShading()
.setBackgroundPatternColor(Color.LIGHT_GRAY);
cell1.getCellFormat().setWidth(50);
// Add a paragraph to the cell as well as a new run with some text.
cell1.appendChild(new Paragraph(doc));
cell1.getFirstParagraph().appendChild(new Run(doc, "Col1"));
// Add the cell to the row.
row1.appendChild(cell1);
// We would then repeat the process for the other cells and rows in the
// table.
// We can also speed things up by cloning existing cells and rows.
row1.appendChild(cell1.deepClone(false));
row1.getLastCell().appendChild(new Paragraph(doc));
row1.getLastCell().getFirstParagraph()
.appendChild(new Run(doc, "Col2"));
row1.appendChild(cell1.deepClone(false));
row1.getLastCell().appendChild(new Paragraph(doc));
row1.getLastCell().getFirstParagraph()
.appendChild(new Run(doc, "Col3"));
Row row = new Row(doc);
row.getRowFormat().setAllowBreakAcrossPages(true);
table.appendChild(row);
// Create a cell and add it to the row
Cell cell = new Cell(doc);
cell.getCellFormat().setWidth(50);
// Add a paragraph to the cell as well as a new run with some text.
cell.appendChild(new Paragraph(doc));
cell.getFirstParagraph()
.appendChild(new Run(doc, "Row 1, Cell 1 Text"));
// Add the cell to the row.
row.appendChild(cell);
row.appendChild(cell.deepClone(false));
row.getLastCell().appendChild(new Paragraph(doc));
row.getLastCell().getFirstParagraph()
.appendChild(new Run(doc, "Row 1, Cell 2 Text"));
row.appendChild(cell.deepClone(false));
row.getLastCell().appendChild(new Paragraph(doc));
row.getLastCell().getFirstParagraph()
.appendChild(new Run(doc, "Row 1, Cell 3 Text"));
// Add left indent to the table.
table.setLeftIndent(60);
doc.save("E:/Data/Test1.docx");
This question already has answers here:
Right aligning text in PdfPCell
(6 answers)
Closed 7 years ago.
I have a table where in the first row there are only images and in the second row there are only descriptions of the images. I handle this by creating a table with the size (columns) of the amount of images and then filling the cells with tables with size 1 (2 rows = 1st row the image, 2nd row the description). After setting cell alignment of the 1st row to center, the second row will not apply the align and the description stays on the left ... is this a bug?
Integer size = filepathArray.length;
PdfPTable pdfPTable = new PdfPTable(size);
for (int i = 0; i < size; i++) {
PdfPTable inner = new PdfPTable(1);
try {
PdfPCell image = new PdfPCell();
PdfPCell description = new PdfPCell();
PdfPCell cell = new PdfPCell();
image.setImage(Image.getInstance(getImageAsByteArray(filepathArray[i])));
image.setFixedHeight(32);
image.setBorder(Rectangle.NO_BORDER);
image.setHorizontalAlignment(Element.ALIGN_CENTER);
inner.addCell(image);
description.addElement(new Chunk(filepathArray[i], FontFactory.getFont("Arial", 8)));
description.setBorder(Rectangle.NO_BORDER);
description.setHorizontalAlignment(Element.ALIGN_CENTER);
inner.addCell(description);
cell = new PdfPCell();
cell.addElement(inner); // needed to actually remove the border from the cell which contains the inner table because tables have no setter for the border
cell.setBorder(Rectangle.NO_BORDER);
pdfPTable.addCell(cell);
} catch (Exception e) {
}
}
pdfPTable.setHorizontalAlignment(Element.ALIGN_LEFT);
Result: the image is centered, the text is not, no way, I've tried everything! Also addElement() removes all previously set alignments (table and cell elements, is this a bug?) so I have to set the alignment AFTER I added the content to the cell or table.
This is wrong:
PdfPCell description = new PdfPCell();
description.addElement(new Chunk(filepathArray[i], FontFactory.getFont("Arial", 8)));
description.setHorizontalAlignment(Element.ALIGN_CENTER);
It is wrong because you are mixing text mode:
PdfPCell description = new PdfPCell(new Phrase(filepathArray[i], FontFactory.getFont("Arial", 8)));
description.setHorizontalAlignment(Element.ALIGN_CENTER);
With composite mode:
PdfPCell description = new PdfPCell();
Paragraph p = new Paragraph(filepathArray[i], FontFactory.getFont("Arial", 8));
p.setAlignment(Element.ALIGN_CENTER);
description.addElement(p);
Seems like you have tried everything but using the approaches that are explained in the documentation ;-)
I have used one parent table that is table_body. One child table that is sub_table(as i would like to place this sub_table inside a PdfPCell in the parent table. ). I want to draw a line when a row is complete for the parent table as per my requirement. But, the issue is bottomborder for the subtable and for the general pdfPcell 'body_cell_bottomBorder' is not getting aligned in a single straight line.
PdfPTable table_body = new PdfPTable(2); // main table
table_body.getDefaultCell().setBorder(Rectangle.NO_BORDER); // set border to none
table_body.setWidthPercentage(100.0f);
table_body.setWidths(new float[] {3.0f,1.0f,});
table_body.setSpacingBefore(6);
PdfPTable sub_table = new PdfPTable(1); // sub table
sub_table.getDefaultCell().setBorder(Rectangle.NO_BORDER); // set border to none
body_cell_bottomBorder.setPhrase(new Phrase("Example",font_body)); // this cell has the bottom border only
Image image = Image.getInstance(BarCode.createBarcode("example"));
body_cell = new PdfPCell(image, true); // this cell has no border at all
body_cell.setBorder(Rectangle.NO_BORDER);
sub_table.addCell(body_cell); // added one row in the sub table
sub_table.addCell(body_cell_bottomBorder); // added second row in the sub table and also want a bottom border
table_body.addCell(sub_table); // added subtable into the parent table pdfpcell
body_cell_bottomBorder.setPhrase(new Phrase(RPL,font_body)); // now adding second column value in parent table pdfPcell and want a bottom border only
table_body.addCell(body_cell_bottomBorder); // added to the parent table
Problem is these two cells of parent table do not make a complete single straight line which i want.
One way:
In the 'child' PdfPTable as each PdfPCell is added, explicitly set Rectangle.NO_BORDER.
When you're done with the 'child' table, wrap in a PdfPCell and set border(s), then add to 'parent' PdfPTable.
Example in C#, since this question is tagged w/itextsharp:
string text = "0000";
int topBottomBorder = Rectangle.BOTTOM_BORDER | Rectangle.TOP_BORDER;
using (Document document = new Document()) {
PdfWriter writer = PdfWriter.GetInstance(document, STREAM);
document.Open();
PdfPTable parentTable = new PdfPTable(2);
PdfPCell cell = new PdfPCell() {
Phrase = new Phrase(text), Border = topBottomBorder
};
parentTable.AddCell(cell);
// in 'child' PdfPTable *ALL* PdfPCells set *WITH NO* border
PdfPTable childTable = new PdfPTable(1);
childTable.AddCell(new PdfPCell
(
(new BarcodeQRCode(text, 1, 1, null)).GetImage()
)
{ Border = Rectangle.NO_BORDER, PaddingTop = 1 }
);
childTable.AddCell(new PdfPCell() { // row 2
Border = Rectangle.NO_BORDER, Phrase = new Phrase(text)
});
// 1. wrap childTable in PdfPCell and set top & bottom borders
PdfPCell childTableCell = new PdfPCell(childTable) {
Border = topBottomBorder
};
// 2. add to main PdfPTable
parentTable.AddCell(childTableCell);
document.Add(parentTable);
}
Result: