IText - add content to an existing PDF file

I want to do the following with iText:

(1) parse an existing pdf file

(2) add to it some data on an existing separate page of the document (for example, a time stamp)

(3) write down the document

I just can't figure out how to do this with iText. In pseudo code, I would do the following:

Document document = reader.read(input); document.add(new Paragraph("my timestamp")); writer.write(document, output); 

But for some reason, the iText API is so complex that I can't wrap myself around it. PdfReader actually holds a document model or something (instead of spilling out a document), and you need a PdfWriter to read pages from it ... eh?

+43
java pdf itext
Jul 26 '10 at 13:18
source share
4 answers

iText has several ways to do this. The PdfStamper class is one option. But I believe the easiest way is to create a new PDF document and then import individual pages from an existing document into a new PDF.

 // Create output PDF Document document = new Document(PageSize.A4); PdfWriter writer = PdfWriter.getInstance(document, outputStream); document.open(); PdfContentByte cb = writer.getDirectContent(); // Load existing PDF PdfReader reader = new PdfReader(templateInputStream); PdfImportedPage page = writer.getImportedPage(reader, 1); // Copy first page of existing PDF into output PDF document.newPage(); cb.addTemplate(page, 0, 0); // Add your new data / text here // for example... document.add(new Paragraph("my timestamp")); document.close(); 

This will be read in PDF from templateInputStream and written to outputStream . It can be file streams or memory streams or anything that suits your application.

+65
Jul 27 '10 at 13:08
source share

The Gutch code is close, but it will only work if:

  • No annotations (links, fields, etc.), no document structure / tagged content, no bookmarks, script document level, etc. etc. etc.
  • Page size is A.4 (decent odds, but it won’t work on any OL file you came across)
  • You do not mind losing all the original metadata of the document (producer, creation date, possibly author / title / keywords) and, possibly, the document identifier. You cannot copy the creation date and document ID unless you make a pretty deep hacker on iText itself).

The approved method is to do it the other way around. Open an existing document with PdfStamper and use the returned PdfContentByte from getOverContent () to write the text (and everything you may need) directly to the page. No second document required.

And you can use ColumnText to handle layout, etc. for you ... no need to get down and dirty with beginText (), setFontAndSize (), drawText (), drawText () ..., endText ().

+40
Oct. 16 '10 at 17:53
source share

This is the most difficult scenario I can imagine: I have a PDF file created using Ilustrator and modified by Acrobat to have AcroFields (AcroForm), which I am going to fill with data using this Java code, the result of this PDF file is a file with the data in the fields changes with the addition of the document.

In fact, in this case, I dynamically generate a background that is added to the PDF, which is also dynamically generated with a Document with an unknown amount of data or pages.

I use JBoss, and this code is inside a JSP file (should work on any JSP web server).

Note. If you are using IExplorer, you must submit an HTTP form with the POST method to upload the file. If not, you will see the PDF code on the screen. This does not happen in Chrome or Firefox.

 <%@ page import="java.io.*, com.lowagie.text.*, com.lowagie.text.pdf.*" %><% response.setContentType("application/download"); response.setHeader("Content-disposition","attachment;filename=listaPrecios.pdf" ); // -------- FIRST THE PDF WITH THE INFO ---------- String str = ""; // lots of words for(int i = 0; i < 800; i++) str += "Hello" + i + " "; // the document Document doc = new Document( PageSize.A4, 25, 25, 200, 70 ); ByteArrayOutputStream streamDoc = new ByteArrayOutputStream(); PdfWriter.getInstance( doc, streamDoc ); // lets start filling with info doc.open(); doc.add(new Paragraph(str)); doc.close(); // the beauty of this is the PDF will have all the pages it needs PdfReader frente = new PdfReader(streamDoc.toByteArray()); PdfStamper stamperDoc = new PdfStamper( frente, response.getOutputStream()); // -------- THE BACKGROUND PDF FILE ------- // in JBoss the file has to be in webinf/classes to be readed this way PdfReader fondo = new PdfReader("listaPrecios.pdf"); ByteArrayOutputStream streamFondo = new ByteArrayOutputStream(); PdfStamper stamperFondo = new PdfStamper( fondo, streamFondo); // the acroform AcroFields form = stamperFondo.getAcroFields(); // the fields form.setField("nombre","Avicultura"); form.setField("descripcion","Esto describe para que sirve la lista "); stamperFondo.setFormFlattening(true); stamperFondo.close(); // our background is ready PdfReader fondoEstampado = new PdfReader( streamFondo.toByteArray() ); // ---- ADDING THE BACKGROUND TO EACH DATA PAGE --------- PdfImportedPage pagina = stamperDoc.getImportedPage(fondoEstampado,1); int n = frente.getNumberOfPages(); PdfContentByte background; for (int i = 1; i <= n; i++) { background = stamperDoc.getUnderContent(i); background.addTemplate(pagina, 0, 0); } // after this everithing will be written in response.getOutputStream() stamperDoc.close(); %> 

There is another solution that is much simpler and solves your problem. It depends on the amount of text you want to add.

 // read the file PdfReader fondo = new PdfReader("listaPrecios.pdf"); PdfStamper stamper = new PdfStamper( fondo, response.getOutputStream()); PdfContentByte content = stamper.getOverContent(1); // add text ColumnText ct = new ColumnText( content ); // this are the coordinates where you want to add text // if the text does not fit inside it will be cropped ct.setSimpleColumn(50,500,500,50); ct.setText(new Phrase(str, titulo1)); ct.go(); 
+5
Dec 07 2018-11-11T00:
source share
 Document document = new Document(); PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("E:/TextFieldForm.pdf")); document.open(); PdfPTable table = new PdfPTable(2); table.getDefaultCell().setPadding(5f); // Code 1 table.setHorizontalAlignment(Element.ALIGN_LEFT); PdfPCell cell; // Code 2, add name TextField table.addCell("Name"); TextField nameField = new TextField(writer, new Rectangle(0,0,200,10), "nameField"); nameField.setBackgroundColor(Color.WHITE); nameField.setBorderColor(Color.BLACK); nameField.setBorderWidth(1); nameField.setBorderStyle(PdfBorderDictionary.STYLE_SOLID); nameField.setText(""); nameField.setAlignment(Element.ALIGN_LEFT); nameField.setOptions(TextField.REQUIRED); cell = new PdfPCell(); cell.setMinimumHeight(10); cell.setCellEvent(new FieldCell(nameField.getTextField(), 200, writer)); table.addCell(cell); // force upper case javascript writer.addJavaScript( "var nameField = this.getField('nameField');" + "nameField.setAction('Keystroke'," + "'forceUpperCase()');" + "" + "function forceUpperCase(){" + "if(!event.willCommit)event.change = " + "event.change.toUpperCase();" + "}"); // Code 3, add empty row table.addCell(""); table.addCell(""); // Code 4, add age TextField table.addCell("Age"); TextField ageComb = new TextField(writer, new Rectangle(0, 0, 30, 10), "ageField"); ageComb.setBorderColor(Color.BLACK); ageComb.setBorderWidth(1); ageComb.setBorderStyle(PdfBorderDictionary.STYLE_SOLID); ageComb.setText("12"); ageComb.setAlignment(Element.ALIGN_RIGHT); ageComb.setMaxCharacterLength(2); ageComb.setOptions(TextField.COMB | TextField.DO_NOT_SCROLL); cell = new PdfPCell(); cell.setMinimumHeight(10); cell.setCellEvent(new FieldCell(ageComb.getTextField(), 30, writer)); table.addCell(cell); // validate age javascript writer.addJavaScript( "var ageField = this.getField('ageField');" + "ageField.setAction('Validate','checkAge()');" + "function checkAge(){" + "if(event.value < 12){" + "app.alert('Warning! Applicant\\ age can not" + " be younger than 12.');" + "event.value = 12;" + "}}"); // add empty row table.addCell(""); table.addCell(""); // Code 5, add age TextField table.addCell("Comment"); TextField comment = new TextField(writer, new Rectangle(0, 0,200, 100), "commentField"); comment.setBorderColor(Color.BLACK); comment.setBorderWidth(1); comment.setBorderStyle(PdfBorderDictionary.STYLE_SOLID); comment.setText(""); comment.setOptions(TextField.MULTILINE | TextField.DO_NOT_SCROLL); cell = new PdfPCell(); cell.setMinimumHeight(100); cell.setCellEvent(new FieldCell(comment.getTextField(), 200, writer)); table.addCell(cell); // check comment characters length javascript writer.addJavaScript( "var commentField = " + "this.getField('commentField');" + "commentField" + ".setAction('Keystroke','checkLength()');" + "function checkLength(){" + "if(!event.willCommit && " + "event.value.length > 100){" + "app.alert('Warning! Comment can not " + "be more than 100 characters.');" + "event.change = '';" + "}}"); // add empty row table.addCell(""); table.addCell(""); // Code 6, add submit button PushbuttonField submitBtn = new PushbuttonField(writer, new Rectangle(0, 0, 35, 15),"submitPOST"); submitBtn.setBackgroundColor(Color.GRAY); submitBtn. setBorderStyle(PdfBorderDictionary.STYLE_BEVELED); submitBtn.setText("POST"); submitBtn.setOptions(PushbuttonField. VISIBLE_BUT_DOES_NOT_PRINT); PdfFormField submitField = submitBtn.getField(); submitField.setAction(PdfAction .createSubmitForm("",null, PdfAction.SUBMIT_HTML_FORMAT)); cell = new PdfPCell(); cell.setMinimumHeight(15); cell.setCellEvent(new FieldCell(submitField, 35, writer)); table.addCell(cell); // Code 7, add reset button PushbuttonField resetBtn = new PushbuttonField(writer, new Rectangle(0, 0, 35, 15), "reset"); resetBtn.setBackgroundColor(Color.GRAY); resetBtn.setBorderStyle( PdfBorderDictionary.STYLE_BEVELED); resetBtn.setText("RESET"); resetBtn .setOptions( PushbuttonField.VISIBLE_BUT_DOES_NOT_PRINT); PdfFormField resetField = resetBtn.getField(); resetField.setAction(PdfAction.createResetForm(null, 0)); cell = new PdfPCell(); cell.setMinimumHeight(15); cell.setCellEvent(new FieldCell(resetField, 35, writer)); table.addCell(cell); document.add(table); document.close(); } class FieldCell implements PdfPCellEvent{ PdfFormField formField; PdfWriter writer; int width; public FieldCell(PdfFormField formField, int width, PdfWriter writer){ this.formField = formField; this.width = width; this.writer = writer; } public void cellLayout(PdfPCell cell, Rectangle rect, PdfContentByte[] canvas){ try{ // delete cell border PdfContentByte cb = canvas[PdfPTable .LINECANVAS]; cb.reset(); formField.setWidget( new Rectangle(rect.left(), rect.bottom(), rect.left()+width, rect.top()), PdfAnnotation .HIGHLIGHT_NONE); writer.addAnnotation(formField); }catch(Exception e){ System.out.println(e); } } } 
+3
Jun 09 '13 at 9:38 on
source share



All Articles