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.
}
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 need some help, I'm working on a project where I need to create a pivot table with report filter. Now I want to set Multiple default value to the report filter. I've gone through this previously posted question Click here!
I couldn't find anything online related this. Thanks in advance.
There has not much changed at creating pivot tables using apache poi since my last answer. So my code in the linked Q/A in your question only can extended a little bit for fulfilling the requirement selecting multiple items as default in page filter. A code which would be general able creating pivot tables from all kind of data, as Excel can do, is further on not possible.
If the need is selecting multiple items, first MultipleItemSelectionAllowed needs to be set in appropriate pivot field.
Then for each item which not shall be selected H(idden) needs set true.
Example:
import org.apache.poi.xssf.usermodel.*;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.*;
import org.apache.poi.ss.SpreadsheetVersion;
import java.util.Random;
import java.io.*;
class PivotTableTest4 {
private static void setCellData(Sheet sheet) {
Row row = sheet.createRow(0);
Cell cell = row.createCell(0);
cell.setCellValue("Name");
cell = row.createCell(1);
cell.setCellValue("Value1");
cell = row.createCell(2);
cell.setCellValue("Value2");
cell = row.createCell(3);
cell.setCellValue("City");
for (int r = 1; r < 15; r++) {
row = sheet.createRow(r);
cell = row.createCell(0);
cell.setCellValue("Name " + ((r-1) % 5 + 1));
cell = row.createCell(1);
cell.setCellValue(r * new java.util.Random().nextDouble());
cell = row.createCell(2);
cell.setCellValue(r * new java.util.Random().nextDouble());
cell = row.createCell(3);
cell.setCellValue("City " + ((r-1) % 4 + 1));
}
}
public static void main(String[] args) {
try {
XSSFWorkbook wb = new XSSFWorkbook();
XSSFSheet sheet = wb.createSheet();
//Create some data to build the pivot table on
setCellData(sheet);
XSSFPivotTable pivotTable = sheet.createPivotTable(
new AreaReference(new CellReference("A1"), new CellReference("D15"), SpreadsheetVersion.EXCEL2007), new CellReference("H5"));
//Configure the pivot table
//Use first column as row label
pivotTable.addRowLabel(0);
//Sum up the second column
pivotTable.addColumnLabel(DataConsolidateFunction.SUM, 1);
//Avarage the third column
pivotTable.addColumnLabel(DataConsolidateFunction.AVERAGE, 2);
//Add fourth column as page filter
pivotTable.addReportFilter(3);
/*
Apache poi adds 15 pivot field items of type "default" (<item t="default"/>) here.
This is because there are 15 rows (A1:D15) and, because they don't have a look at the data,
they are assuming max 15 different values. This is fine because Excel will rebuild its pivot cache while opening.
But if we want preselect items, then this is not fine. Then we must know what items there are that can be preselected.
So we need at least as much items as we want preselecting as numbered items: <item x="0"/><item x="1"/><item x="2"/>...
And we must build a cache definition which has shared elements for those items.
*/
for (int i = 0; i < 4; i++) {
//take the first 4 items as numbered items: <item x="0"/><item x="1"/><item x="2"/><item x="3"/>
pivotTable.getCTPivotTableDefinition().getPivotFields().getPivotFieldArray(3).getItems().getItemArray(i).unsetT();
pivotTable.getCTPivotTableDefinition().getPivotFields().getPivotFieldArray(3).getItems().getItemArray(i).setX((long)i);
//build a cache definition which has shared elements for those items
//<sharedItems><s v="City 1"/><s v="City 2"/><s v="City 3"/><s v="City 4"/></sharedItems>
pivotTable.getPivotCacheDefinition().getCTPivotCacheDefinition().getCacheFields().getCacheFieldArray(3).getSharedItems().addNewS().setV("City " + (i+1));
}
//Now we can predefinite a page filter. Second item, which is "City 2", in this case.
//pivotTable.getCTPivotTableDefinition().getPageFields().getPageFieldArray(0).setItem(1);
//If the need is selecting multiple items, first MultipleItemSelectionAllowed needs to be set.
pivotTable.getCTPivotTableDefinition().getPivotFields().getPivotFieldArray(3).setMultipleItemSelectionAllowed(true);
//Then set H(idden) true for all items which not shall be selected. First ("City 1") and fourth ("City 4") in this case.
pivotTable.getCTPivotTableDefinition().getPivotFields().getPivotFieldArray(3).getItems().getItemArray(0).setH(true);
pivotTable.getCTPivotTableDefinition().getPivotFields().getPivotFieldArray(3).getItems().getItemArray(3).setH(true);
FileOutputStream fileOut = new FileOutputStream("PivotTableTest4.xlsx");
wb.write(fileOut);
fileOut.close();
wb.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
This needs the full jar of all of the schemas, ooxml-schemas-1.3.jar, as mentioned in the FAQ.
I am working on itext 5 using java. I have pages with mutiple tables with dynamic rows. In some instances, the table last row is splitted into next page with the folowing header. I am using setHeaderRows() and setSkipFirstHeader() to manage continuation of next page. The last row has enough space to fit on earlier page. I would like to fit that last row in same page instead of next page.
For example, on page 1, the last row is splitted into first row of next page. Instead I would like to fit that row in page 1 so save one extra page with all blanks.
I tried using setExtendLastRow(), but its not working. Does anyone know how to fix this problem. I am attaching a working sample code.
public class ProposalItextSplitLastRow {
public static void main(String[] args) {
try {
Document document = new Document();
document.setPageSize(PageSize.LETTER);
document.setMargins(16, 14, 14, 14);
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("C:/SplitLastRow.pdf"));
document.open();
document.setPageSize(PageSize.LETTER);
document.setMargins(16, 14, 42, 38);
for (int m = 1; m < 20; m++) {
int row = 0;
PdfPTable table = new PdfPTable(1);
table.setSpacingAfter(0);
table.setSpacingBefore(0);
table.setWidthPercentage(100);
table.setHeaderRows(1);
table.setSkipFirstHeader(true);
add(table, "Header Row continued " + m, BaseColor.LIGHT_GRAY, row++);
add(table, "Header Row normal " + m, BaseColor.LIGHT_GRAY, row++);
add(table, "Text Row 1 ", BaseColor.WHITE, row++);
add(table, "Text Row 2 ", BaseColor.WHITE, row++);
add(table, "Text Row 3 ", BaseColor.WHITE, row++);
addPadding(table);
document.add(table);
}
document.close();
} catch (Exception de) {
de.printStackTrace();
}
}
private static void add(PdfPTable table, String text, BaseColor color, int row) {
PdfPCell pdfCellHeader = new PdfPCell();
pdfCellHeader.setBackgroundColor(color);
pdfCellHeader.addElement(new Paragraph(new Phrase(text)));
table.addCell(pdfCellHeader);
}
private static void addPadding(PdfPTable table) {
PdfPCell cell = new PdfPCell();
cell.setFixedHeight(2f);
cell.setBorder(Rectangle.NO_BORDER);
cell.setColspan(table.getNumberOfColumns());
table.addCell(cell);
}
}
you can table.setKeepRowsTogather(true);
table.setHeaderRows(1) as well alongwith it
setKeepRowsTogather() checks if it can keep all the rows in page but splits the rows in case the table spans multiple pages. In that case setHeaderRows(1) will put the header rows again in the next page.
I had to execute the example to understand your question. You confused me by talking about a header that isn't a header (the rows with "Header Row normal" aren't header rows!) and your reference to setExtendLastRow() didn't help either (mentioning that method doesn't make sense to me; it's very confusing).
This being said, the solution to your problem is a no-brainer. I've rewritten the main class:
public static void main(String[] args) {
try {
Document document = new Document();
document.setPageSize(PageSize.LETTER);
document.setMargins(16, 14, 14, 14);
PdfWriter writer = PdfWriter.getInstance(document,
new FileOutputStream("SplitLastRow.pdf"));
document.open();
document.setPageSize(PageSize.LETTER);
document.setMargins(16, 14, 42, 38);
for (int m = 1; m < 20; m++) {
int row = 0;
PdfPTable table = new PdfPTable(1);
table.setSpacingAfter(0);
table.setSpacingBefore(0);
table.setTotalWidth(document.right() - document.left());
table.setLockedWidth(true);
table.setHeaderRows(1);
table.setSkipFirstHeader(true);
add(table, "Header Row continued " + m, BaseColor.LIGHT_GRAY, row++);
add(table, "Header Row normal " + m, BaseColor.LIGHT_GRAY, row++);
add(table, "Text Row 1 ", BaseColor.WHITE, row++);
add(table, "Text Row 2 ", BaseColor.WHITE, row++);
add(table, "Text Row 3 ", BaseColor.WHITE, row++);
addPadding(table);
if (writer.getVerticalPosition(true) - table.getRowHeight(0) - table.getRowHeight(1) < document.bottom()) {
document.newPage();
}
document.add(table);
}
document.close();
} catch (Exception de) {
de.printStackTrace();
}
}
Make sure you define a total width instead of a width percentage, and lock the width. As documented (and as common sense tells you), a PdfPTable object doesn't know its actual width if you define a width percentage. It goes without saying that you can't calculate the height of a table that doesn't know it's actual width.
Then use getVerticalPosition() method to get the current position of the cursor, and check if the first two rows fit on the page. If they don't go to a new page before adding the table. If you want to check if the complete table fits, use the getTotalHeight() method instead of the getRowHeight() method.
You can do
table.setSplitRows(false);
But I believe that when there is a row that wont fit it just wont be shown. It's worth a shot though
I attempted to find a solution already, but nothing has come up that matches my problem. I'm using JXL to read an excel spreadsheet and convert each row into a specified object. Each cell within a row corresponds to a property of the object I'm creating. My spreadsheet has 41 columns and after reading 375 rows, the number of cells per row changes from 41 to 32. I can't figure out why.
Here's the code where I'm looping through rows and retrieving the cells:
w = Workbook.getWorkbook(inputWorkbook);
// Get the first sheet
Sheet sheet = w.getSheet(0);
// Loop over first 10 column and lines
for (int row=1; row < sheet.getRows();row++)
{
EventData event = new EventData();
// we skip first row bc that should be header info
//now iterate through columns in row
try
{
Cell[] cell = sheet.getRow(row);
event.Name = cell[0].getContents();
event.Location = cell[1].getContents();
The rest of the code continues to grab the contents of each cell and assign them accordingly. But when attempting to access cell[32] on row 376, I get an out of bounds exception.
Could it not just be that everything after cell[32] on that row is empty and thus cell[32] (and up) in the array are not created at all?
Am now just starting with jxl and I think that's what I'm seeing
Instead of accessing the cell data as:
Cell[] cell = sheet.getRow(row);
event.Name = cell[0].getContents();
event.Location = cell[1].getContents();
Try to access the data as:
sheet.getCell(column, row);
Complete code would be:
w = Workbook.getWorkbook(inputWorkbook);
// Get the first sheet
Sheet sheet = w.getSheet(0);
// Loop over first 10 column and lines
for (int row=1; row < sheet.getRows();row++)
{
EventData event = new EventData();
// we skip first row bc that should be header info
//now iterate through columns in row
try
{
event.Name = sheet.getCell(0, row).getContents();
event.Location = sheet.getCell(1, row).getContents();
}
}
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.