iTextPdf - Writing on same page's copy multiple times and merging them - java

I have a pdf template on which I have to write, say the number of person visited a place along with other information. The pdf template has 25 rows.
So, if the count of people visiting the place is more than 25, I need to append a copy of the same pdf template as page 2 which will contain the entry for person 26 till 50. My current set up is :
reader = new PdfReader(PATH_TO_PDF_TEMPLATE);
stamper = new PdfStamper(reader, WRITTEN_FILE_PATH);
I want to use the same PDF Template again and append to the written 1st page in case the number of people is more than 25.

Here is a simple example of table which has 21 rows per page. You can set cell.setFixedHeight(33.68f) (bigger than 33.68) cell height to get 25 rows per page.
public class SimpleTable {
public static final String DEST = "C:\\Users\\krezus\\Desktop\\simple_table.pdf";
public static void main(String[] args) throws IOException,
DocumentException {
File file = new File(DEST);
file.getParentFile().mkdirs();
new SimpleTable5().createPdf(DEST);
}
public void createPdf(String dest) throws IOException, DocumentException {
Document document = new Document(PageSize.A4);
PdfWriter.getInstance(document, new FileOutputStream(dest));
document.open();
PdfPTable table = new PdfPTable(5);
table.setWidthPercentage(100);
table.setSkipFirstHeader(true);
System.out.println(PageSize.A4.getHeight()/25);
table.setSkipLastFooter(true);
for (int i = 0; i < 350; i++) {
PdfPCell celltable = new PdfPCell(new Phrase(Integer.toString(i)));
celltable.setFixedHeight(33.68f);
table.addCell(celltable);
}
document.add(table);
document.close();
}
}

I have used PdfPageEvent.onStartPage() and onEndPage().
writer = PdfWriter.getInstance(document, exportOutputStream);
writer.setPageEvent(pageEventHandler);

Related

itext - setSimpleColumn unable to understand llx,lly,urx,ury

I am developing a simple invoice generation software for my store.
I am trying to print the final things in a PDF using iText but I am not able to work properly with the method setSimpleColumn that I am using with ColumnText.
I am not able to understand the concept of llx,lly,urx,ury but I am trying through hit n try method but not able to get any result
This is my code
public class CreateInvoicePdf {
public static final String DEST="C:\\Users\\sanju\\Desktop\\resul.pdf";
public static void main(String args[]) throws FileNotFoundException, DocumentException
{
File file = new File (DEST);
file.getParentFile().mkdirs();
new CreateInvoicePdf().createPdf(DEST);
}
public void createPdf(String dest) throws FileNotFoundException, DocumentException
{
Document d = new Document(PageSize.A4);
PdfWriter writer = PdfWriter.getInstance(d, new FileOutputStream(dest));
d.open();
PdfContentByte can = writer.getDirectContent();
Paragraph companyDetails = new Paragraph("CLIMAX EXCLUSIVE\nShop No. G1 G2 Mohan Bazar\nCentral Market Ashok Vihar\nNew Delhi-110052");
Paragraph invoiceDetails = new Paragraph("Invoice No : 1234\nDate : 10/05/2018\nPay : CASH");
PdfPTable itemTable = new PdfPTable(9);
itemTable.addCell("1");
itemTable.addCell("Shirt");
itemTable.addCell("1999");
itemTable.addCell("1");
itemTable.addCell("1999");
itemTable.addCell("12");
itemTable.addCell("1500");
itemTable.addCell("250");
itemTable.addCell("250");
ColumnText ct = new ColumnText(can);
ct.setSimpleColumn(100,200,300,400);
ct.addElement(companyDetails);
ct.go();
ct.setSimpleColumn(400,200,600,700);
ct.addElement(invoiceDetails);
ct.go();
ct.setSimpleColumn(100, 700, 500, 500);
ct.addElement(itemTable);
ct.go();
d.close();
writer.close();
}}
and the output I am getting is weird.
I want the company details and address to be on the upper left corner
The invoice number date and details at upper right corner
The invoice items table below these

itext 5.5 Portrait orientation not working from new page

I run the following code for an HTML file with Tables.
I am able to convert HTML to PDF for first page with margins all sides.
But as I do document.newPage(); and apply document.setPageSize(); its not working. Margins are not present.
PDF is borderless, without any margins.
Pls guide.
Code:
public class Potrait_ParseHtmlObjects {
public static final String HTML = "C:/h.html";
public static final String DEST = "C:/test33.pdf";
public void createPdf(String file) {
// Parse HTML into Element list
try{
XMLWorkerHelper helper = XMLWorkerHelper.getInstance();
// CSS
CSSResolver cssResolver = helper.getDefaultCssResolver(true);
CssFile cssFile = helper.getCSS(new FileInputStream("D:\\Itext_Test\\Test\\src\\test.css"));
cssResolver.addCss(cssFile);
// HTML
HtmlPipelineContext htmlContext = new HtmlPipelineContext(null);
htmlContext.setTagFactory(Tags.getHtmlTagProcessorFactory());
htmlContext.autoBookmark(false);
//mycode starts
FontFactory.registerDirectories();
//mycode ends
// Pipelines
ElementList elements = new ElementList();
ElementHandlerPipeline end = new ElementHandlerPipeline(elements, null);
HtmlPipeline html = new HtmlPipeline(htmlContext, end);
CssResolverPipeline css = new CssResolverPipeline(cssResolver, html);
// XML Worker
XMLWorker worker = new XMLWorker(css, true);
XMLParser p = new XMLParser(worker);
//mycode starts
p.parse(new FileInputStream(HTML),Charset.forName("UTF-8"));//changed for Charset Encoding
// step 1
Document document = new Document();
// step 2
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(file));
writer.setInitialLeading(12.5f);
// step 3
document.open();
// step 4
Rectangle left = new Rectangle(33,33,550,770);
document.setPageSize(left);
System.out.println("1"+document.getPageSize());
ColumnText column = new ColumnText(writer.getDirectContent());
column.setSimpleColumn(left);
int runDirection = PdfWriter.RUN_DIRECTION_LTR;
column.setRunDirection(runDirection);
int status = ColumnText.START_COLUMN;
for (Element e : elements) {
if (e instanceof PdfPTable) {
PdfPTable table = (PdfPTable) e;
for (PdfPRow row : table.getRows()) {
for (PdfPCell cell : row.getCells()) {
if(cell!=null)
cell.setRunDirection(runDirection);
}
}
}
if (ColumnText.isAllowedElement(e)) {
column.addElement(e);
status = column.go();
while (ColumnText.hasMoreText(status)) {
Rectangle left1 = new Rectangle(50,50,500,700);
document.newPage();
document.setPageSize(left1);
column.setSimpleColumn(left1);
status = column.go();
}
}
}
// step 5
document.close();
}catch(Exception ex)
{ex.printStackTrace();}
}
/**
* Main method
*/
public static void main(String[] args) throws IOException, DocumentException {
File file = new File(DEST);
file.getParentFile().mkdirs();
new Potrait_ParseHtmlObjects().createPdf(DEST);
}
}
You initialize all page parameters when you do document.newPage(), hence changing the page size or margins doesn't make sense after triggering document.newPage(). If you want a different page size (or orientation, or margins), you need to set the values for the page size, orientation and margins before invoking document.newPage() (and before document.open() if you want to change the first page).
For instance: in your case, you should create your document like this:
Document document = new Document(new Rectangle(33,33,550,770));
And you should change the page size like this:
document.setPageSize(left1);
document.newPage();
column.setSimpleColumn(left1);
You don't have any margins because you use the same Rectangle for the page size as for the column. You are creating a PDF of which the coordinate of the lower-left corner is not equal to (0, 0). This isn't illegale, but it's unusual. My guess is that you want to do something like this:
document.setPageSize(new Rectangle(0, 0, 550, 750););
document.newPage();
column.setSimpleColumn(new Rectangle(50,50,500,700));
This will result in a page size of 7.64 by 10.42 inch (550 by 750 pt) and you'll have a margin of 0
69 inches on every side (50 pt).

function that can use iText to concatenate / merge pdfs together - causing some issues

I'm using the following code to merge PDFs together using iText:
public static void concatenatePdfs(List<File> listOfPdfFiles, File outputFile) throws DocumentException, IOException {
Document document = new Document();
FileOutputStream outputStream = new FileOutputStream(outputFile);
PdfWriter writer = PdfWriter.getInstance(document, outputStream);
document.open();
PdfContentByte cb = writer.getDirectContent();
for (File inFile : listOfPdfFiles) {
PdfReader reader = new PdfReader(inFile.getAbsolutePath());
for (int i = 1; i <= reader.getNumberOfPages(); i++) {
document.newPage();
PdfImportedPage page = writer.getImportedPage(reader, i);
cb.addTemplate(page, 0, 0);
}
}
outputStream.flush();
document.close();
outputStream.close();
}
This usually works great! But once and a while, it's rotating some of the pages by 90 degrees? Anyone ever have this happen?
I am looking into the PDFs themselves to see what is special about the ones that are being flipped.
There are errors once in a while because you are using the wrong method to concatenate documents. Please read chapter 6 of my book and you'll notice that using PdfWriter to concatenate (or merge) PDF documents is wrong:
You completely ignore the page size of the pages in the original document (you assume they are all of size A4),
You ignore page boundaries such as the crop box (if present),
You ignore the rotation value stored in the page dictionary,
You throw away all interactivity that is present in the original document, and so on.
Concatenating PDFs is done using PdfCopy, see for instance the FillFlattenMerge2 example:
Document document = new Document();
PdfCopy copy = new PdfSmartCopy(document, new FileOutputStream(dest));
document.open();
PdfReader reader;
String line = br.readLine();
// loop over readers
// add the PDF to PdfCopy
reader = new PdfReader(baos.toByteArray());
copy.addDocument(reader);
reader.close();
// end loop
document.close();
There are other examples in the book.
In case anyone is looking for it, using Bruno Lowagie's correct answer above, here is the version of the function that does not seem to have the page flipping issue i described above:
public static void concatenatePdfs(List<File> listOfPdfFiles, File outputFile) throws DocumentException, IOException {
Document document = new Document();
FileOutputStream outputStream = new FileOutputStream(outputFile);
PdfCopy copy = new PdfSmartCopy(document, outputStream);
document.open();
for (File inFile : listOfPdfFiles) {
PdfReader reader = new PdfReader(inFile.getAbsolutePath());
copy.addDocument(reader);
reader.close();
}
document.close();
}

how to add the checkbox into the Itext pdf table

am generating check-box inside Itext PDF Table but inside table check box is not generating its generating outside table.could please help me how to append that check box into PDF table.could you please help me out.
Below is my code:
Class A{
public void createFourColumnBody() throws DocumentException, FileNotFoundException {
com.itextpdf.text.Document document = new com.itextpdf.text.Document(PageSize.A4);
com.itextpdf.text.pdf.PdfWriter writer1 = PdfWriter.getInstance(document, new FileOutputStream("D:\\PDF_Java.pdf", false));
document.open();
float[] widths = new float[]{30f, 30f};
com.itextpdf.text.pdf.PdfPTable table = new com.itextpdf.text.pdf.PdfPTable(widths);
table.setWidthPercentage(100);
table.setHorizontalAlignment(Element.ALIGN_LEFT);
PdfFormField checkboxGroupField = PdfFormField.createCheckBox(writer1);
PdfPCell cell = table.getDefaultCell();
PdfPCell cell12;
cell = new PdfPCell(new Paragraph("checkbox3"));
table.addCell(cell);
cell12 = new PdfPCell(table.getDefaultCell());
cell12.setCellEvent(new CellField(writer1, checkboxGroupField, true));
table.addCell(cell12);
writer1.addAnnotation(checkboxGroupField);
document.add(table);
document.close();
}
public static void main(String[] args) throws DocumentException, FileNotFoundException {
A a1 = new A();
a1.createFourColumnBody();
}
}
This is explained in the CheckboxCell example. That example was written in answer to Resizing a form field in iTextSharp, but it also answers your question.
Note that your question remained unanswered for so long because you used the [itextpdf] tag instead of [itext] or [itextsharp]. I only found this question by coincidence.

Editing PDF text using Java

Is there a way I can edit a PDF from Java?
I have a PDF document which contains placeholders for text that I need to be replaced using Java, but all the libraries that I saw created PDF from scratch and small editing functionality.
Is there anyway I can edit a PDF or is this impossible?
You can do it with iText. I tested it with following code. It adds a chunk of text and a red circle over each page of an existing PDF.
/* requires itextpdf-5.1.2.jar or similar */
import java.io.*;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.*;
public class AddContentToPDF {
public static void main(String[] args) throws IOException, DocumentException {
/* example inspired from "iText in action" (2006), chapter 2 */
PdfReader reader = new PdfReader("C:/temp/Bubi.pdf"); // input PDF
PdfStamper stamper = new PdfStamper(reader,
new FileOutputStream("C:/temp/Bubi_modified.pdf")); // output PDF
BaseFont bf = BaseFont.createFont(
BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED); // set font
//loop on pages (1-based)
for (int i=1; i<=reader.getNumberOfPages(); i++){
// get object for writing over the existing content;
// you can also use getUnderContent for writing in the bottom layer
PdfContentByte over = stamper.getOverContent(i);
// write text
over.beginText();
over.setFontAndSize(bf, 10); // set font and size
over.setTextMatrix(107, 740); // set x,y position (0,0 is at the bottom left)
over.showText("I can write at page " + i); // set text
over.endText();
// draw a red circle
over.setRGBColorStroke(0xFF, 0x00, 0x00);
over.setLineWidth(5f);
over.ellipse(250, 450, 350, 550);
over.stroke();
}
stamper.close();
}
}
I modified the code found a bit and it was working as follows
public class Principal {
public static final String SRC = "C:/tmp/244558.pdf";
public static final String DEST = "C:/tmp/244558-2.pdf";
public static void main(String[] args) throws IOException, DocumentException {
File file = new File(DEST);
file.getParentFile().mkdirs();
new Principal().manipulatePdf(SRC, DEST);
}
public void manipulatePdf(String src, String dest) throws IOException, DocumentException {
PdfReader reader = new PdfReader(src);
PdfDictionary dict = reader.getPageN(1);
PdfObject object = dict.getDirectObject(PdfName.CONTENTS);
PdfArray refs = null;
if (dict.get(PdfName.CONTENTS).isArray()) {
refs = dict.getAsArray(PdfName.CONTENTS);
} else if (dict.get(PdfName.CONTENTS).isIndirect()) {
refs = new PdfArray(dict.get(PdfName.CONTENTS));
}
for (int i = 0; i < refs.getArrayList().size(); i++) {
PRStream stream = (PRStream) refs.getDirectObject(i);
byte[] data = PdfReader.getStreamBytes(stream);
stream.setData(new String(data).replace("NULA", "Nulo").getBytes());
}
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
stamper.close();
reader.close();
}
}
Take a look at iText and this sample code
Take a look at aspose and this sample code
I've done this using LibreOffice Draw.
You start by manually opening a pdf in Draw, checking that it renders OK, and saving it as a Draw .odg file.
That's a zipped xml file, so you can modify it in code to find and replace the placeholders.
Next (from code) you use a command line call to Draw to generate the pdf.
Success!
The main issue is that Draw doesn't handle fonts embedded in a pdf. If the font isn't also installed on your system - then it will render oddly, as Draw will replace it with a standard one that inevitably has different sizing.
If this approach is of interest, I'll put together some shareable code.

Categories

Resources