I have two PDF files A and B, I have a requirement where i need to Merge both these PDF files based on a condition.Like,If i find a string like "attach PDF" in my A, i have to merge the B file into A from that particular page in A. For Example,If i spot the word in Page No 3 in my A file I need to merge the B file from Page No:3. I'm using I-Text 5.5.10. Is it possible to achieve this in I-Text or PDFBox. Here is what i have tried as of now.
public static void mergePdf() throws IOException, DocumentException
{
PdfReader reader1 = new PdfReader("C:\\Users\\user1\\Downloads\\generatedSample.pdf");
PdfReader reader2 = new PdfReader("C:\\Users\\user1\\Desktop\\sample1.pdf");
Document document = new Document();
document.addHeader("Header Text", "");
FileOutputStream fos = new FileOutputStream("C:\\Users\\user1\\Downloads\\MergeFile.pdf");
PdfCopy copy = new PdfCopy(document, fos);
document.open();
PdfImportedPage page;
PdfCopy.PageStamp stamp;
Phrase phrase;
BaseFont bf = BaseFont.createFont();
Font font = new Font(bf, 9);
int n = reader1.getNumberOfPages();
for (int i = 1; i <= reader1.getNumberOfPages(); i++)
{
page = copy.getImportedPage(reader1, i);
stamp = copy.createPageStamp(page);
ColumnText.showTextAligned(stamp.getOverContent(), Element.ALIGN_CENTER, null, 520, 5, 0);
stamp.alterContents();
copy.addPage(page);
}
for (int i = 1; i <= reader2.getNumberOfPages(); i++)
{
page = copy.getImportedPage(reader2, i);
stamp = copy.createPageStamp(page);
ColumnText.showTextAligned(stamp.getOverContent(), Element.ALIGN_CENTER, null, 520, 5, 0);
stamp.alterContents();
copy.addPage(page);
}
document.close();
reader1.close();
reader2.close();
}
Thanks for the solution in advance !!
I am using Itext PDF API to generate a pdf. I am trying to get some text to be aligned to the right-hand side of the pdf. I have tried the manual method of spacing but is not working for some reason (Code shown below). Meanwhile, if there is a way of doing it dynamically that would be great, please!
String dest = "\\location\\";
PdfWriter writer;
writer = new PdfWriter(dest);
// Creating a PdfDcoument
PdfDocument pdf = new PdfDocument(writer);
// Creating a Document
Document document = new Document(pdf);
// Creating a String
String para1 = "TEXT";
//Spacing length
while (para1.length() < 50) {
para1 = " " + para1;
}
//Creating Paragraphs
Paragraph paragraph1 = new Paragraph(para1);
//paragraph1.setAlignment(Element.ALIGN_CENTER);
//Adding Paragraphs to document
document.add(paragraph1);
// Closing the document
document.close();
Thanks in advance!
Class com.itextpdf.layout.element.Paragraph in itext7 has method setTextAlignment. I hope this is what you are looking for:
...
paragraph1.setTextAlignment(TextAlignment.RIGHT);
...
I'm using com.itextpdf:itextpdf:5.5.10 and it looks like the stuff has moved around a bit.
paragraph1.setAlignment(com.itextpdf.text.Element.ALIGN_RIGHT)
I have some code that generates a PDF file programmatically and I need to append to it the existing file (to the end of generated one). Can somebody give an example or link?
Thank you
UPD#1: Actually I am looking for some piece of code of merging existing file and byte's array (of programmatically generated file)
Itext is the good solution.
To append , you need to read the already present data and write it to the next file.
PdfTextExtractor parser =new PdfTextExtractor(new PdfReader("D:/Text.pdf"));
String text1 = parser.getTextFromPage(3);
And before you write your code that generates a PDF file programmatically , you need to add text1.
Thanks for all repliers, I have found the solution:
PdfWriter writer = PdfWriter.getInstance(document, outputStream);
writer.setPageEvent(new FooterGenerator());
document.open();
document.setMargins(MARGIN_LEFT, MARGIN_RIGHT, MARGIN_TOP, MARGIN_BOTTOM);
document.add(generateHeader());
document.add(generateContent());
appendTermsAndConditions(writer, document, context.getRealPath("/files/terms-and-conditions.pdf");
document.close();
protected void appendTermsAndConditions(PdfWriter writer, Document document, String fileName) throws IOException {
File f = new File(fileName);
if (f.exists()) {
PdfReader reader = new PdfReader(fileName);
PdfContentByte cb = writer.getDirectContent();
int pagesCount = reader.getNumberOfPages();
PdfImportedPage page;
for (int i = 0; i < pagesCount; i++) {
document.newPage();
page = writer.getImportedPage(reader, document.getPageNumber() + 1);
cb.addTemplate(page, 0, 0);
}
}
}
I was trying to create pdf using iText in java. And am failed when I tried to set font to paragraph. The exact problem is only the font size is not getting applied. I used the following code.
StringReader strReader = new StringReader(content);
arrList = HTMLWorker.parseToList(strReader, null);
Font font = new Font(BaseFont.createFont("c:\\ARIALUN0.ttf", BaseFont.IDENTITY_H,
BaseFont.EMBEDDED), 6, Font.BOLD, new Color(0, 0, 0));
Paragraph para = new Paragraph();
para.setFont(font);
for (int k = 0; k < arrList.size(); ++k) {
para.add((com.lowagie.text.Element)arrList.get(k));
}
Can anyone help me to find a solution?
//use this code.Sometimes setfont() willnot work with Paragraph
try
{
FileOutputStream out=new FileOutputStream(name);
Document doc=new Document();
PdfWriter.getInstance(doc, out);
doc.open();
Font f=new Font(FontFamily.TIMES_ROMAN,50.0f,Font.UNDERLINE,BaseColor.RED);
Paragraph p=new Paragraph("New PdF",f);
p.setAlignment(Paragraph.ALIGN_CENTER);
doc.add(p);
doc.close();
}
catch(Exception e)
{
System.out.println(e);
}
}
I was pretty confused and almost posted the wrong answer to this.
Your paragraph is having its font set correctly. Just try inserting a String to see.
Your problem lies in your for loop. To the paragraph, you're adding a Element objects. An Element is composed of Chunk objects, which each have their own Font data.
Try setting the Font of the Chunks in your Elements when they are instantiated. That should solve your problem.
Try this ,It will save the style of the text:
Paragraph _p = new Paragraph();
_p.setFont(regular);
ArrayList htmlObjs = (ArrayList) HTMLWorker.parseToList(new StringReader(text_), null);
for (int k = 0; k < htmlObjs.size(); ++k)
{
ArrayList<Chunk> chunk = ((Paragraph) htmlObjs.get(k)).getChunks();
for (int l = 0; l < chunk.size(); l++)
{
Font _original_chunk_font = chunk.get(l).getFont();
Font _newchunk_font = new Font(unicode);
_newchunk_font.setFamily(_original_chunk_font.getFamilyname());
_newchunk_font.setStyle(_original_chunk_font.getStyle());
_newchunk_font.setSize(_original_chunk_font.getSize());
_newchunk_font.setColor(_original_chunk_font.getColor());
chunk.get(l).setFont(_newchunk_font);
}
_p.add((Element)htmlObjs.get(k));
}
I'm new in this.
but i'm showing u a simplest way to set font to
paragraph.
document.open();
document.add(new Paragraph(" Hello World ", FontFactory.getFont(FontFactory.TIMES_ROMAN,18, Font.BOLD, BaseColor.BLACK)));
document.close();
By this way i'm changing the font, font size , color etc.
this worked for me..
Happy coding..
For adding Font to itextpdf Paragraph you can simply use a Chunk then you can set Font to Chunk add that Chunk to Paragraph afterwards.
Example:
Font f3 = new Font(Font.FontFamily.TIMES_ROMAN, 18.0f, Font.BOLD, BaseColor.BLACK);
Chunk c3 = new Chunk("INVOICE", f3);
c3.setBackground(BaseColor.WHITE);
Paragraph p3 = new Paragraph(c3);
p3.setAlignment(Element.ALIGN_CENTER);
I want to do the following with iText:
(1) parse an existing PDF file
(2) add some data to it, on the existing single page of the document (such as a timestamp)
(3) write out the document
I just can't seem to figure out how to do this with iText. In pseudo code I would do this:
Document document = reader.read(input);
document.add(new Paragraph("my timestamp"));
writer.write(document, output);
But for some reason iText's API is so dauntingly complicated that I can't wrap my head around it. The PdfReader actually holds the document model or something (rather than spitting out a document), and you need a PdfWriter to read pages from it... eh?
iText has more than one way of doing this. The PdfStamper class is one option. But I find the easiest method is to create a new PDF document then import individual pages from the existing document into the 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 read in a PDF from templateInputStream and write it out to outputStream. These might be file streams or memory streams or whatever suits your application.
Gutch's code is close, but it'll only work right if:
There are no annotations (links, fields, etc), no Document Structure/Marked Content, no bookmarks, no document-level script, etc, etc, etc...
The page size happens to be A.4 (decent odds, but it won't work on any ol' PDF you happen to come across)
You don't mind losing all the original document metadata (producer, creation date, possibly author/title/keywords), and maybe the document ID. You can't copy the creation date and doc ID unless you do some pretty deep hackery on iText itself).
The Approved Method is to do it the other way around. Open the existing document with a PdfStamper, and use the returned PdfContentByte from getOverContent() to write text (and whatever else you might need) directly to the page. No second document needed.
And you can use a ColumnText to handle layout and such for you... no need to get down and dirty with beginText(),setFontAndSize(),drawText(),drawText()...,endText().
This is the most complicated scenario I can imagine: I have a PDF file created with Ilustrator and modified with Acrobat to have AcroFields (AcroForm) that I'm going to fill with data with this Java code, the result of that PDF file with the data in the fields is modified adding a Document.
Actually in this case I'm dynamically generating a background that is added to a PDF that is also dynamically generated with a Document with an unknown amount of data or pages.
I'm using JBoss and this code is inside a JSP file (should work in any JSP webserver).
Note: if you are using IExplorer you must submit a HTTP form with POST method to be able to download the file. If not you are going to see the PDF code in 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 much simpler, and solves your problem. It depends 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();
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\\'s 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);
}
}
}
how-to-update-a-pdf-without-creating-a-new-pdf
iText 7, please pay attention to version
PdfReader reader = new PdfReader(src);
PdfWriter writer = new PdfWriter(dest);
PdfDocument pdfDoc = new PdfDocument(reader, writer);
//manipulate pdf…
pdfDoc.close();