The drawing of the table is done correctly but it gets wrong as the data is repeated.
the barcode has to be like this to avoid errors from employees checking wrong codes.
The ideal would be A picture speaks a thousand words.
My function:
Document documentoPDF = new Document();
try {
PdfWriter writer = PdfWriter.getInstance(documentoPDF, new FileOutputStream("c:\\exporta_Celso\\contagem_" + jComboBox1.getSelectedItem().toString() + ".pdf"));
documentoPDF.open();
documentoPDF.setPageSize(PageSize.A4);
PdfPTable table = new PdfPTable(3);
table.setWidthPercentage(100);
table.setTotalWidth(documentoPDF.getPageSize().getWidth());
for (int i = 0; i < itens.size(); i++) {
System.out.println(((List) itens.get(i)).get(0).toString());
System.out.println(((List) itens.get(i)).get(1).toString());
String item = ((List) itens.get(i)).get(1).toString();
BarcodeEAN codeEAN = new BarcodeEAN();
codeEAN.setCodeType(codeEAN.EAN13);
String barCodeBruto = ((List) itens.get(i)).get(0).toString();
String barCode = null;
if (barCodeBruto.length() != 13) {
barCode = ("0000000000000" + barCodeBruto).substring(barCodeBruto.length());
} else {
barCode = barCodeBruto;
}
codeEAN.setCode(barCode);
PdfContentByte cb = writer.getDirectContent();
Image imageEAN = codeEAN.createImageWithBarcode(cb, null, null);
PdfPCell cellBar = new PdfPCell(imageEAN);
PdfPCell cellDesc = new PdfPCell(new Paragraph(item));
PdfPCell cellQtd = new PdfPCell(new Paragraph("QTD."));
cellBar.setPadding(3);
cellBar.setUseDescender(true);
cellBar.setUseAscender(true);
cellDesc.setPadding(3);
cellDesc.setUseDescender(true);
cellDesc.setUseAscender(true);
cellQtd.setPadding(3);
cellQtd.setUseDescender(true);
cellQtd.setUseAscender(true);
float height = table.calculateHeights();
float width = documentoPDF.getPageSize().getWidth();
if (i % 2 == 0) {
float[] widths = new float[]{145f, width - 36 - 10f, 80f};
table.setWidths(widths);
table.addCell(cellBar);
table.addCell(cellDesc);
table.addCell(cellQtd);
}else{
float[] widths = new float[]{80f, width - 36 - 10f, 145f};
table.setWidths(widths);
table.addCell(cellQtd);
table.addCell(cellDesc);
table.addCell(cellBar);
}
PdfContentByte canvas = writer.getDirectContent();
ColumnText columnText = new ColumnText(canvas);
columnText.setSimpleColumn(36, 756 - height, width - 36, 36);
columnText.addElement(table);
columnText.go();
}
} catch (DocumentException de) {
de.printStackTrace();
} catch (IOException ioe) {
ioe.printStackTrace();
} finally {
documentoPDF.close();
}
I solved it by creating a parent table outside the looping.
PdfPTable tableFinal = new PdfPTable(1);
tableFinal.setWidthPercentage(100);
tableFinal.setTotalWidth(documentoPDF.getPageSize().getWidth());
tableFinal.addCell(table);
PdfContentByte canvas = writer.getDirectContent();
ColumnText columnText = new ColumnText(canvas);
columnText.setSimpleColumn(36, 756 - height, width - 36, 36);
columnText.addElement(tableFinal);
columnText.go();
Related
I need to add an itext watermark to my pdf android java pdf file
my sample current code for creating the pdf file:
File docsFolder = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_DOWNLOADS), "osary/estmara");
String currentDate = new SimpleDateFormat("dd-MM-yyyy_hh_mm_aaa", Locale.getDefault()).format(new Date());
String pdfname = myEstmaraa.getTalabId() + "_" + currentDate + ".pdf";
pdfFile = new File(docsFolder, pdfname);
OutputStream output = new FileOutputStream(pdfFile);
Document document = new Document(PageSize.A4);
document.setMargins(5, 5, 5, 5);
PdfWriter PdfWriters = PdfWriter.getInstance(document, output);
PdfWriters.createXmpMetadata();
PdfWriters.setTagged();
document.open();
//todo 2 preparing Header and directions and margin row 0
PdfPTable tableForRowZero = new PdfPTable(new float[]{1});
tableForRowZero.setSpacingBefore(5);
tableForRowZero.setRunDirection(PdfWriter.RUN_DIRECTION_RTL);
tableForRowZero.getDefaultCell().setFixedHeight(34);
tableForRowZero.setTotalWidth(PageSize.A4.getWidth());
tableForRowZero.setWidthPercentage(100);
tableForRowZero.setHeaderRows(0);
tableForRowZero.getDefaultCell().setVerticalAlignment(Element.ALIGN_MIDDLE);
cellss = new PdfPCell(new Phrase("رقم الاستمارة", FONT2));
cellss.setHorizontalAlignment(Element.ALIGN_CENTER);
cellss.setVerticalAlignment(Element.ALIGN_CENTER);
cellss.setBackgroundColor(BaseColor.GRAY);
tableForRowZero.addCell(cellss);
tableForRowZero.setHeaderRows(0);
cellss = new PdfPCell(new Phrase(String.valueOf(myEstmaraa.getTalabId()), FONT2));
cellss.setHorizontalAlignment(Element.ALIGN_CENTER);
cellss.setVerticalAlignment(Element.ALIGN_CENTER);
tableForRowZero.addCell(cellss);
document.add(tableForRowZero);
document.close();
i have tried this code but it for desktop java:
enter link description here
and the problem that i faced is this line:
PdfDocument pdfDoc = new PdfDocument(new PdfReader(SRC), new PdfWriter(dest));
when i change it to android i face a problem, i tried it like:
com.itextpdf.kernel.pdf.PdfDocument pdfDoc = new com.itextpdf.kernel.pdf.PdfDocument(new PdfReader(pdfFile.getPath()),new PdfWriter(pdfFile.getPath()));
it gives me this hint:
Cannot resolve constructor 'PdfWriter(java.lang.String)'
the code i tried to make watermark:
com.itextpdf.kernel.pdf.PdfDocument pdfDoc = new com.itextpdf.kernel.pdf.PdfDocument(new PdfReader(pdfFile.getPath()),new PdfWriter(pdfFile.getPath()));
PdfCanvas under = new PdfCanvas(pdfDoc.getFirstPage().newContentStreamBefore(), new PdfResources(), pdfDoc);
PdfFont font = PdfFontFactory.createFont(FontProgramFactory.createFont(StandardFonts.HELVETICA));
com.itextpdf.layout.element.Paragraph paragraph2 = new com.itextpdf.layout.element.Paragraph("This watermark is added UNDER the existing content")
.setFont(font)
.setFontSize(15);
Canvas canvasWatermark1 = new Canvas(under, pdfDoc.getDefaultPageSize())
.showTextAligned(paragraph2, 297, 550, 1, TextAlignment.CENTER, VerticalAlignment.TOP, 0);
canvasWatermark1.close();
PdfCanvas over = new PdfCanvas(pdfDoc.getFirstPage());
over.setFillColor(ColorConstants.BLACK);
paragraph2 = new com.itextpdf.layout.element.Paragraph("This watermark is added ON TOP OF the existing content")
.setFont(font)
.setFontSize(15);
Canvas canvasWatermark2 = new Canvas(over, pdfDoc.getDefaultPageSize())
.showTextAligned(paragraph2, 297, 500, 1, TextAlignment.CENTER, VerticalAlignment.TOP, 0);
canvasWatermark2.close();
paragraph2 = new com.itextpdf.layout.element.Paragraph("This TRANSPARENT watermark is added ON TOP OF the existing content")
.setFont(font)
.setFontSize(15);
over.saveState();
// Creating a dictionary that maps resource names to graphics state parameter dictionaries
PdfExtGState gs1 = new PdfExtGState();
gs1.setFillOpacity(0.5f);
over.setExtGState(gs1);
Canvas canvasWatermark3 = new Canvas(over, pdfDoc.getDefaultPageSize())
.showTextAligned(paragraph2, 297, 450, 1, TextAlignment.CENTER, VerticalAlignment.TOP, 0);
canvasWatermark3.close();
over.restoreState();
i tried also to add png image and set its opacity but it cover the content
try {
com.itextpdf.text.Image image1_emp_osary = null;
Drawable d_emp_osary = getResources().getDrawable(R.drawable.ketm_estmara);
BitmapDrawable bitDw_emp_osary = ((BitmapDrawable) d_emp_osary);
Bitmap bmp_emp_osary = bitDw_emp_osary.getBitmap();
ByteArrayOutputStream stream_emp_osary = new ByteArrayOutputStream();
bmp_emp_osary.compress(Bitmap.CompressFormat.PNG, 100, stream_emp_osary);
image1_emp_osary = com.itextpdf.text.Image.getInstance(stream_emp_osary.toByteArray());
image1_emp_osary.scaleToFit(200, 200);
image1_emp_osary.setAlignment(Element.ALIGN_BOTTOM);
image1_emp_osary.setSpacingBefore(200);
image1_emp_osary.setTransparency(new int[]{5, 5});
document.add(new Chunk(image1_emp_osary, 0, 200));
PdfContentByte canvas = PdfWriters.getDirectContentUnder();
PdfGState state = new PdfGState();
state.setFillOpacity(0.6f);
canvas.setGState(state);
canvas.addImage(image1_emp_osary);
canvas.restoreState();
} catch (Exception e) {
e.printStackTrace();
}
i have solved it,
the idea is:
1.we need to save the file with out water mark ,and that was easy:
File docsFolder = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_DOWNLOADS), "osary/estmara");
String currentDate = new SimpleDateFormat("dd-MM-yyyy_hh_mm_aaa", Locale.getDefault()).format(new Date());
String pdfname = myEstmaraa.getTalabId() + "_" + currentDate + ".pdf";
pdfFile = new File(docsFolder, pdfname);
OutputStream output = new FileOutputStream(pdfFile);
Document document = new Document(PageSize.A4);
document.setMargins(5, 5, 5, 5);
PdfWriter PdfWriters = PdfWriter.getInstance(document, output);
PdfWriters.createXmpMetadata();
PdfWriters.setTagged();
document.open();
//todo 2 preparing Header and directions and margin row 0
PdfPTable tableForRowZero = new PdfPTable(new float[]{1});
tableForRowZero.setSpacingBefore(5);
tableForRowZero.setRunDirection(PdfWriter.RUN_DIRECTION_RTL);
tableForRowZero.getDefaultCell().setFixedHeight(34);
tableForRowZero.setTotalWidth(PageSize.A4.getWidth());
tableForRowZero.setWidthPercentage(100);
tableForRowZero.setHeaderRows(0);
tableForRowZero.getDefaultCell().setVerticalAlignment(Element.ALIGN_MIDDLE);
cellss = new PdfPCell(new Phrase("رقم الاستمارة", FONT2));
cellss.setHorizontalAlignment(Element.ALIGN_CENTER);
cellss.setVerticalAlignment(Element.ALIGN_CENTER);
cellss.setBackgroundColor(BaseColor.GRAY);
tableForRowZero.addCell(cellss);
tableForRowZero.setHeaderRows(0);
cellss = new PdfPCell(new Phrase(String.valueOf(myEstmaraa.getTalabId()), FONT2));
cellss.setHorizontalAlignment(Element.ALIGN_CENTER);
cellss.setVerticalAlignment(Element.ALIGN_CENTER);
tableForRowZero.addCell(cellss);
document.add(tableForRowZero);
document.close();
2.we will open the file but we can not override it directly,
so:
a. we will save it in a temp file with the watermark and close it:
File tempFile = new File(docsFolder.getPath(), "temp.pdf");
com.itextpdf.kernel.pdf.PdfWriter TempWriter = new com.itextpdf.kernel.pdf.PdfWriter(tempFile);
String font = "/res/font/arialbd.ttf";
PdfFontFactory.register(font);
FontProgram fontProgram = FontProgramFactory.createFont(font, true);
PdfFont f = PdfFontFactory.createFont(fontProgram, PdfEncodings.IDENTITY_H);
LanguageProcessor languageProcessor = new ArabicLigaturizer();
com.itextpdf.kernel.pdf.PdfDocument tempPdfDoc = new com.itextpdf.kernel.pdf.PdfDocument(new PdfReader(pdfFile.getPath()), TempWriter);
com.itextpdf.layout.Document TempDoc = new com.itextpdf.layout.Document(tempPdfDoc);
com.itextpdf.layout.element.Paragraph paragraph0 = new com.itextpdf.layout.element.Paragraph(languageProcessor.process("الاستماره الالكترونية--الاستماره الالكترونية--الاستماره الالكترونية--الاستماره الالكترونية"))
.setFont(f).setBaseDirection(BaseDirection.RIGHT_TO_LEFT)
.setFontSize(15);
Drawable d_ketm_estmara = getResources().getDrawable(R.drawable.ketm_estmara);
Bitmap bitDw_estmara = ((BitmapDrawable) d_ketm_estmara).getBitmap();
ByteArrayOutputStream stream_estmara = new ByteArrayOutputStream();
bitDw_estmara.compress(Bitmap.CompressFormat.PNG, 100, stream_estmara);
byte[] data = stream_estmara.toByteArray();
ImageData img = ImageDataFactory.create(data);
PdfExtGState gs1 = new PdfExtGState().setFillOpacity(0.2f);
for (int i = 1; i <= tempPdfDoc.getNumberOfPages(); i++) {
PdfPage pdfPage = tempPdfDoc.getPage(i);
com.itextpdf.kernel.geom.Rectangle pageSize = pdfPage.getPageSize();
float x = (pageSize.getLeft() + pageSize.getRight()) / 2;
float y = (pageSize.getTop() + pageSize.getBottom()) / 3;
PdfCanvas over = new PdfCanvas(pdfPage);
over.saveState();
over.setExtGState(gs1);
TempDoc.showTextAligned(paragraph0, 300, 760, i, TextAlignment.CENTER, VerticalAlignment.TOP, 0);
float leftImage = 20;
float bottomImage = 120;
float rightImage = 550;
float topImage = 720;
over.addImageWithTransformationMatrix(img, rightImage, 0, 0, topImage, leftImage, bottomImage, true);
over.restoreState();
}
TempDoc.close();
tempPdfDoc.close();
b. we will open the temp file and save it with the old name:
com.itextpdf.kernel.pdf.PdfDocument pdfDoc = new com.itextpdf.kernel.pdf.PdfDocument(new PdfReader(tempFile.getPath()), new com.itextpdf.kernel.pdf.PdfWriter(new File(docsFolder.getPath(), pdfname)));
com.itextpdf.layout.Document doc = new com.itextpdf.layout.Document(pdfDoc);
doc.close();
pdfDoc.close();
I am using itext 5 legacy for the first time and I am new to app development.
I am generating a table that keeps splitting the columns into new rows on a new page and it would repeat the data.
The first Table:
The second table with split columns and repeating data:
Third table:
The fourth table:
The fifth Table:
The table is required to be one long row.
Please help me rectify this,
Here is the code:
private void createPdf() throws FileNotFoundException, DocumentException,IOException {
// getIntent().setType("application/pdf");
Toast.makeText(this,"GENERATING PDF ..."+ directory_path,Toast.LENGTH_LONG).show();
File file = new File(directory_path+filename);
if (!file.exists())
{
file.mkdirs();
}
ProductCondition prodCond = new ProductCondition(true,"GREEN","BFobrourinbiurfufbjfnbbu");
ProductOperations prodOper = new ProductOperations(true,true,true,1000,986,500,"OBNobdfiuvdob");
Product product = new Product("bkbukb","sfdvsf","sdfsdfs","1sfdssV45",prodCond,prodOper);
technicians.addProduct(product);
Document document = new Document(PageSize.A1.rotate());
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(directory_path+filename));
document.open();
PdfPTable table = new PdfPTable(15);
table.setTotalWidth(5000);
table.setWidthPercentage(100);
List<String> listData =new ArrayList<>() ;
listData = GetTechnicianData(technicians);
Image image1 = GetImage();
Image image2 = GetImage();
table.addCell("Bloop");
table.addCell("han Solo");
table.addCell("Hamburger");
table.addCell("NUmber time");
table.addCell("boogaloo");
table.addCell("Boo thang");
table.addCell("Spanish");
table.addCell("Inquisition");
table.addCell("Never ");
table.addCell("Death");
table.addCell("Test ");
// table.addCell("Button");
table.addCell("Lights");
table.addCell("Sunshine");
table.addCell("Comment");
table.addCell("Images");
table.setHeaderRows(3);
table.setFooterRows(1);
table.getDefaultCell().setBackgroundColor(GrayColor.GRAYWHITE);
PdfPCell cell;
Toast.makeText(this,"ADDING PRELIMINARY DATA",Toast.LENGTH_LONG).show();
for (int c = 0; c < 14; c++) {
cell = new PdfPCell();
cell.setFixedHeight(50);
cell.addElement(new Paragraph(listData.get(c)));
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
//cell.setBorder(PdfPCell.NO_BORDER);
table.addCell(cell);
table.setKeepTogether(true);
}
Paragraph p = new Paragraph();
p.add(new Chunk(image1,0,0,true));
p.add(new Chunk(image2,0,0,true));
cell = new PdfPCell();
cell.addElement(p);
//cell.setBorder(PdfPCell.NO_BORDER);
table.addCell(cell);
//document.add(table);
Toast.makeText(this,"ADDING IMAGES...",Toast.LENGTH_LONG).show();
/* cell = new PdfPCell();
Paragraph p = new Paragraph();
p.add(new Chunk(image1,0,0,true));
p.add(new Chunk(image1,0,0,true));
cell.addElement(p);
table.addCell(cell);*/
// document.add(table);
PdfContentByte canvas = writer.getDirectContent();
PdfTemplate tableTemplate = canvas.createTemplate(5000, 2600);
table.writeSelectedRows(0, -1, 0, 800, tableTemplate);
PdfTemplate clip;
for (int j = 0; j <5000; j += 1000) {
table.setKeepTogether(true);
document.newPage();
for (int i = 2600; i > 0; i -= 1300) {
clip = canvas.createTemplate(2000, 1300);
clip.addTemplate(tableTemplate, -j, 1750 - i);
canvas.addTemplate(clip, 50, 312);
table.setKeepTogether(true);
//canvas.addImage(image1);
}
}
// byte [] pdf = Files.readAllBytes(file.toPath());
Uri filepdf = Uri.fromFile(new File(directory_path+filename));
UploadTask uploadTask = storageReference.child(technicians.getEmailAddress()).child("PDFUpdate").putFile(filepdf);
Toast.makeText(this,"PDF Generated Successfully",Toast.LENGTH_LONG).show();
document.close();
/* PackageManager packageManager = context.getPackageManager();
Intent testIntent = new Intent(Intent.ACTION_VIEW);
testIntent.setType("application/pdf");
List list = packageManager.queryIntentActivities(testIntent, PackageManager.MATCH_DEFAULT_ONLY);
if (list.size() > 0) {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
Uri uri = Uri.fromFile(file);
intent.setDataAndType(uri, "application/pdf");
context.startActivity(intent);
} else {
Toast.makeText(context, "Download a PDF Viewer to see the generated PDF", Toast.LENGTH_SHORT).show();
}
*/
}
private void createPdfWrapper() throws FileNotFoundException, DocumentException ,IOException{
int hasWriteStoragePermission = ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (hasWriteStoragePermission != PackageManager.PERMISSION_GRANTED) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (!ActivityCompat.shouldShowRequestPermissionRationale(this,Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
showMessageOKCancel("You need to allow access to Storage",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
ActivityCompat.requestPermissions(CentralHome.this, new String[]{ Manifest.permission.WRITE_EXTERNAL_STORAGE},
REQUEST_CODE_ASK_PERMISSIONS);
}
}
});
return;
}
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
REQUEST_CODE_ASK_PERMISSIONS);
return;
}
} else {
createPdf();
}
}
private Image GetImage() throws BadElementException,IOException{
Drawable d = getResources().getDrawable(R.drawable.logo);
BitmapDrawable bitDw = ((BitmapDrawable) d);
Bitmap bmp = bitDw.getBitmap();
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.PNG, 100, stream);
Image image = Image.getInstance(stream.toByteArray());
image.scalePercent(10);
return image;
// document.add(image);
}
}
In createPdf you have a loop that adds sections of the template with the whole table to separate pages:
for (int j = 0; j <5000; j += 1000) {
table.setKeepTogether(true);
document.newPage();
for (int i = 2600; i > 0; i -= 1300) {
clip = canvas.createTemplate(2000, 1300);
clip.addTemplate(tableTemplate, -j, 1750 - i);
canvas.addTemplate(clip, 50, 312);
table.setKeepTogether(true);
//canvas.addImage(image1);
}
}
Each section is 2000 units wide (canvas.createTemplate(2000, 1300)) but when advancing to the next section you only go right by 1000 units (j += 1000). Thus, each new section (except the first one) repeats the last three columns (the second half) of the previous section.
You can prevent these repetitions by going right by 2000 units after each section, i.e. by replacing
for (int j = 0; j <5000; j += 1000)
by
for (int j = 0; j <5000; j += 2000)
As an aside, there are numerous other weirdnesses in your code, e.g.
table.setHeaderRows(3);
table.setFooterRows(1);
(here you declare that you have three header rows and one footer row to repeat automatically if the table is added to the Document directly and split over multiple pages; as you don't add the table to the Document but manually to a template, that functionality is not used which is fortunate as you only create enough cells to fill two rows, not even enough for the declared header rows)
and multiple calls of
table.setKeepTogether(true)
after already having rendered the table in
table.writeSelectedRows(0, -1, 0, 800, tableTemplate)
After rendering the table it is too late to set properties controlling the rendering process...
In a comment you said that you only wanted to have a normal 15 column table, not one whose columns are spread across multiple pages. In that case why don't you simply do
Document document = new Document(PageSize.A1.rotate());
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(directory_path+filename));
document.open();
PdfPTable table = new PdfPTable(15);
table.setWidthPercentage(100);
... create cells and add them to the table ...
document.add(table);
document.close();
All the usage of PdfContentByte, PdfTemplate, and writeSelectedRows is completely unnecessary for your use case.
For particular table layout with particular cell having larger data then it is not getting properly exported to PDF, the data in that particular cell getting cropped.
private static void tableLayout1() {
Document doc = new Document();
try {
PdfWriter.getInstance(doc, new FileOutputStream(
".\\TableLayout_1.pdf"));
doc.open();
// Table
PdfPTable table = new PdfPTable(3);
table.setWidthPercentage(100f);
table.setSplitLate(false);
//row 1
PdfPCell cell00 = new PdfPCell(new Paragraph("Cell00"));
cell00.setBackgroundColor(new Color(200, 0, 0));
cell00.setRowspan(3);
PdfPCell cell01 = new PdfPCell(new Paragraph("Cell01"));
cell01.setBackgroundColor(new Color(0, 200, 0));
cell01.setColspan(2);
//row 2
PdfPCell cell11 = new PdfPCell(new Paragraph("Cell11"));
cell11.setBackgroundColor(new Color(100, 100, 0));
PdfPCell cell12 = new PdfPCell( getLongCellData() );
cell12.setBackgroundColor(new Color(0, 200, 200));
cell12.setRowspan(2);
//row 3
PdfPCell cell21 = new PdfPCell(new Paragraph("Cell21"));
cell21.setBackgroundColor(new Color(200, 0, 200));
table.addCell(cell00);
table.addCell(cell01);
table.addCell(cell11);
table.addCell(cell12);
table.addCell(cell21);
doc.add(table);
} catch (FileNotFoundException | DocumentException e) {
e.printStackTrace();
}
doc.close();
}
private static Paragraph getLongCellData() {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 100; i++) {
sb.append("Cell12_" + i);
sb.append("\n");
}
return new Paragraph(sb.toString());
}
Here the data from cell12 (which has row span of 2 and has larger data) is getting cropped at the page end and it is not being continued on next page.
Tried dividing this table into two different tables as below, but still the issue is there.
private static void tableLayout2() {
Document doc = new Document();
try {
PdfWriter.getInstance(doc, new FileOutputStream(
".\\TableLayout_2.pdf"));
doc.open();
// Table
PdfPTable table = new PdfPTable(2);
table.setWidthPercentage(100f);
table.setSplitLate(false);
table.setWidths(new int[]{1, 2});
//Inner table for column 1
PdfPTable column1Table = new PdfPTable(1);
PdfPCell cell00 = new PdfPCell(new Paragraph("Cell00"));
cell00.setBackgroundColor(new Color(200, 0, 0));
//cell00.setRowspan(3);
column1Table.addCell(cell00);
//Inner table for column 2
PdfPTable column2Table = new PdfPTable(2);
PdfPCell cell01 = new PdfPCell(new Paragraph("Cell01"));
cell01.setBackgroundColor(new Color(0, 200, 0));
cell01.setColspan(2);
PdfPCell cell11 = new PdfPCell(new Paragraph("Cell11"));
cell11.setBackgroundColor(new Color(100, 100, 0));
PdfPCell cell12 = new PdfPCell( getLongCellData() );
cell12.setBackgroundColor(new Color(0, 200, 200));
cell12.setRowspan(2);
PdfPCell cell21 = new PdfPCell(new Paragraph("Cell21"));
cell21.setBackgroundColor(new Color(200, 0, 200));
column2Table.addCell(cell01);
column2Table.addCell(cell11);
column2Table.addCell(cell12);
column2Table.addCell(cell21);
table.addCell(column1Table);
table.addCell(column2Table);
doc.add(table);
} catch (FileNotFoundException | DocumentException e) {
e.printStackTrace();
}
doc.close();
}
This issue is partially resolved on iText5, but, due to some issues upgrading library is not quite possible for us, so is there any solution for this ?
With iText5 the data is not getting cropped but cells' heights are not so appropriate. For TableLayout_2_withIText5.pdf cell21 should have rendered on page3 instead of page4. For TableLayout_1_withIText5.pdf cell21 is getting extended in the margin area of Page1.
I am developing an application to generate barcode. I need a number of bar codes to be generated at a time and add to a document of A4 size, using iText Table structure. Also all the barcodes to be positioned in a 13 X 5 matrix style, that fits A4 sheet, and to be printed. But for me, the bar codes are not properly aligned and positioned. Kindly help me.
This is the code:
int barwidthleft=(int) 14.112;
int barwidthtop=(int) 53.28;
int barwidthright=(int) 16.56;
int barwidthbottom=(int) 53.28;
float borderwidth=(float) 0.5;
int vgap=0;
int columns=0;
int i=0,j=0;
Rectangle pageSize = new Rectangle(new Rectangle(PageSize.A4));
Document document = new Document(pageSize);
document.setMargins(barwidthleft, barwidthright, barwidthtop, barwidthbottom);
try
{
PdfWriter writer =PdfWriter.getInstance(document,new FileOutputStream(new File("./barcode.pdf")));
document.open();
int count1=0,count2=0,count3=0,count4=0;
int maxcount=qty;
int itemcount=0,barcount=0;
columns=9;
Barcode128 code128 = new Barcode128();
code128.setGenerateChecksum(true);
String code="";
while(count2<maxcount)
{
PdfPTable table = new PdfPTable(columns); // 1 columns.
table.setWidthPercentage(100);
table.setHorizontalAlignment(PdfPTable.ALIGN_CENTER);
table.setTotalWidth(new float[]{ (float)107.28, (float)5.61,(float)107.28, (float)5.61,(float)107.28, (float)5.61,(float)107.28, (float)5.61, (float)107.28});
table.setLockedWidth(true);
for(i=0;i<columns &&count2<maxcount;i=i+2)
{
code=Integer.toString(nextcode);
code128.setCode(code);
code128.setBarHeight(30);
code128.setX(1f);
Image img=code128.createImageWithBarcode(writer.getDirectContent(), null, null);
PdfPCell cell2 = new PdfPCell();
cell2.setFixedHeight((float) 59.04);
cell2.addElement(new Paragraph("Choice ",new Font(Font.FontFamily.COURIER, 6)));
cell2.addElement(new Paragraph("Rs. "+itemlist[itemcount][4]+"/-",new Font(Font.FontFamily.COURIER, 6)));
cell2.addElement(new Paragraph(" ",new Font(Font.FontFamily.COURIER, 2)));
cell2.addElement(img);
cell2.setBorder(PdfPCell.NO_BORDER);
cell2.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
table.addCell(cell2);
if(i!=8)
{
PdfPCell cellblank1 = new PdfPCell();
cellblank1.setBorder(PdfPCell.NO_BORDER);
cellblank1.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
table.addCell(cellblank1);
}
count2++;
itemcount++;
System.out.println("Two:"+count2);
nextcode++;
}
if(count2>=maxcount)
{
while(i<columns)
{
PdfPCell finalblank1 = new PdfPCell();
finalblank1.setBorder(PdfPCell.NO_BORDER);
finalblank1.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
table.addCell(finalblank1);
PdfPCell finalblank2 = new PdfPCell();
finalblank2.setBorder(PdfPCell.NO_BORDER);
finalblank2.setHorizontalAlignment(PdfPCell.ALIGN_CENTER);
table.addCell(finalblank1);
i=i+2;
}
}
document.add(table);
}
document.close();
//print
String[]args={};
PrintPdf.main(args);
}
catch(Exception e)
{
System.out.println(e);
}
Following is a demo code to generate a PDF doc from a HTML source:
public class SimpleAdhocReport
{
public SimpleAdhocReport()
{
build();
}
private void build()
{
AdhocConfiguration configuration = new AdhocConfiguration();
AdhocReport report = new AdhocReport();
configuration.setReport(report);
AdhocColumn column = new AdhocColumn();
column.setName("item");
report.addColumn(column);
column = new AdhocColumn();
column.setName("orderdate");
report.addColumn(column);
column = new AdhocColumn();
column.setName("quantity");
report.addColumn(column);
column = new AdhocColumn();
column.setName("unitprice");
report.addColumn(column);
try
{
AdhocManager.saveConfiguration(configuration, new FileOutputStream("d:/configuration.xml"));
#SuppressWarnings("unused")
AdhocConfiguration loadedConfiguration = AdhocManager.loadConfiguration(new FileInputStream("d:/configuration.xml"));
JasperReportBuilder reportBuilder = AdhocManager.createReport(configuration.getReport());
reportBuilder.setDataSource(createDataSource());
ByteArrayOutputStream baos = new ByteArrayOutputStream();
reportBuilder.toHtml(baos);
String html = new String(baos.toByteArray(), "UTF-8");
baos.close();
Whitelist wl = Whitelist.simpleText();
wl.addTags("table", "tr", "td");
String clean = Jsoup.clean(html, wl);
clean = clean.replace("<td></td>", "");
clean = clean.replace("<td> </td>", "");
clean = clean.replace("<td> ", "<td>");
Document doc = Jsoup.parse(clean);
for (Element element : doc.select("*"))
{
if (!element.hasText() && element.isBlock())
{
element.remove();
}
}
clean = doc.body().html();
int startIndex = clean.indexOf("<table>", 6);
int endIndex = clean.indexOf("</table>");
clean = clean.substring(startIndex, endIndex + 8);
BufferedWriter writer = new BufferedWriter(new FileWriter(("d:/test.html")));
writer.write(clean);
writer.close();
try
{
createPdf(clean);
}
catch (DocumentException e)
{
e.printStackTrace();
}
}
catch (DRException e)
{
e.printStackTrace();
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private JRDataSource createDataSource()
{
DRDataSource dataSource = new DRDataSource("item", "orderdate", "quantity", "unitprice");
for (int i = 0; i < 20; i++)
{
dataSource.add("Book", new Date(), (int) (Math.random() * 10) + 1,
new BigDecimal(Math.random() * 100 + 1).setScale(4, BigDecimal.ROUND_HALF_UP));
}
return dataSource;
}
public static void main(String[] args)
{
new SimpleAdhocReport();
}
public void createPdf(String html) throws IOException, DocumentException
{
com.itextpdf.text.Document document = new com.itextpdf.text.Document(PageSize.LETTER);
document.setMargins(30, 30, 80, 30);
PdfWriter.getInstance(document, new FileOutputStream("D:\\HTMLtoPDF.pdf"));
document.open();
PdfPTable table = null;
ElementList list = com.itextpdf.tool.xml.XMLWorkerHelper.parseToElementList(html, null);
for (com.itextpdf.text.Element element : list)
{
table = new PdfPTable((PdfPTable) element);
}
table.setWidthPercentage(100);
ArrayList<PdfPRow> rows = table.getRows();
for (PdfPRow rw : rows)
{
PdfPCell[] cells = rw.getCells();
for (PdfPCell cl : cells)
{
cl.setVerticalAlignment(com.itextpdf.text.Element.ALIGN_MIDDLE);
cl.setBorder(PdfPCell.NO_BORDER);
cl.setNoWrap(true);
cl.setPadding(10f);
cl.setCellEvent(new MyCell());
}
}
document.add(table);
document.close();
}
}
class MyCell implements PdfPCellEvent
{
public void cellLayout(PdfPCell cell, Rectangle position, PdfContentByte[] canvases)
{
float x1 = position.getLeft() - 2;
float x2 = position.getRight() + 2;
float y1 = position.getTop() + 2;
float y2 = position.getBottom() - 2;
PdfContentByte canvas = canvases[PdfPTable.LINECANVAS];
canvas.rectangle(x1, y1, x2 - x1, y2 - y1);
canvas.stroke();
}
}
I am working with jasper reports to create a adhoc report and generate the HTML from there. I have to generate a PDF from this HTML.
Couple of issue I am facing, any help is appreciated:
I am setting the
table.setWidthPercentage(100);
for a page with table its not working.
I have to increase spacing between columns. Tried what Bruno suggested here. Its not working. I have also tried using a solution from here with no luck. Ref. image below.
Also if i cell event to default is not working.
e.g.
table.getDefaultCell().setCellEvent()
Any suggestions ?
Update:
My Output
I was able to get the padding as i want by parsing the HTML following way:
public PdfPTable getTable(String cleanHTML) throws IOException
{
String CSS = "tr { text-align: center; } td { padding: 5px; }";
CSSResolver cssResolver = new StyleAttrCSSResolver();
CssFile cssFile = XMLWorkerHelper.getCSS(new ByteArrayInputStream(CSS.getBytes()));
cssResolver.addCss(cssFile);
// HTML
HtmlPipelineContext htmlContext = new HtmlPipelineContext(null);
htmlContext.setTagFactory(Tags.getHtmlTagProcessorFactory());
// Pipelines
ElementList elements = new ElementList();
ElementHandlerPipeline pdf = new ElementHandlerPipeline(elements, null);
HtmlPipeline html = new HtmlPipeline(htmlContext, pdf);
CssResolverPipeline css = new CssResolverPipeline(cssResolver, html);
// XML Worker
XMLWorker worker = new XMLWorker(css, true);
XMLParser p = new XMLParser(worker);
p.parse(new ByteArrayInputStream(cleanHTML.getBytes()));
return (PdfPTable) elements.get(0);
}
That fixes the issue mentioned in question 2. Q3 is not longer required.