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'm using itextpdf to create my pdf with tables. While creating table i need to align some column to right, but its now working properly , can you guys help me.
I tried googling too, but didt work out for me. im using itextpdf 5.4 version.
public void generateMonthlySubReport(String[][] StrArray,String dueMonth,int Amt){
try {
Document document = new Document();
PdfWriter.getInstance(document, new FileOutputStream(MON_SUB_FILE));
PdfPTable pt = new PdfPTable(StrArray[0].length);
pt.setTotalWidth(new float[]{ 55,120,360,140});
pt.setLockedWidth(true);
PdfPCell pcell = new PdfPCell();
document.open();
addKvLogo(document);
Chunk glue = new Chunk(new VerticalPositionMark());
Paragraph p1 = new Paragraph("Monthly Subscription Report",catFont);
p1.setAlignment(Element.ALIGN_CENTER);
addEmptyLine(p1,2);
document.add(p1);
Paragraph p2 = new Paragraph("Month : "+dueMonth);
p2.add(new Chunk(glue));
p2.add("Per Member : Rs."+Amt);
addEmptyLine(p2,2);
document.add(p2);
for(int i=0;i<StrArray.length;i++){
for(int j=0;j<StrArray[i].length;j++){
pcell = new PdfPCell();
if(i==0){
pcell.setBackgroundColor(BaseColor.LIGHT_GRAY);
}else{
pcell.setBackgroundColor(BaseColor.WHITE);
}
pcell.setUseAscender(true);
pcell.setMinimumHeight(22);
pcell.setPaddingLeft(10);
pcell.setHorizontalAlignment(Element.ALIGN_RIGHT);
pcell.setVerticalAlignment(Element.ALIGN_MIDDLE);
pcell.addElement(new Phrase(StrArray[i][j]));
pt.addCell(pcell);
}
}
pt.setTotalWidth(PageSize.A4.getWidth()-(document.leftMargin()*2));
pt.setLockedWidth(true);
document.add(pt);
document.close();
} catch (Exception e) {
e.printStackTrace();
}
} `
You are mixing text mode with composite mode.
This is text mode:
pcell = new PdfPCell(new Phrase(StrArray[i][j]));
pcell.setHorizontalAlignment(Element.ALIGN_RIGHT);
In this case, the alignment of the cell will be used for the alignment of the text.
This is composite mode:
pcell = new PdfPCell();
Paragraph p = new Parapgraph(StrArray[i][j])
p.setAlignment(Element.ALIGN_RIGHT);
pcell.addElement(p);
In this case, the alignment of the cell is ignored, in favor of the alignment of the element.
How to know the difference between text mode and composite mode?
iText automatically switches from text mode to composite mode in a PdfPCell the moment you use the addElement() method. As soon as you do this, some properties defined at the cell level are ignored. This explains why the content you are adding isn't right-aligned.
I need to add some text to pdf. I am doing this by creating a Phrase and passing it to ColumnText.showTextAligned method and there is just one specific pdf which gives an error when the pdf is viewed:-
"An error exists on this page. Acrobat may not display the page correctly. Please contact the person...
"
Below is the code snipped that is being used to add text:-
PdfReader reader = new PdfReader(pdfBytes);
PdfStamper stamper = new PdfStamper(reader, pdfOutputByteArray);
PdfContentByte page;
FontSelector selector = new FontSelector();
int start = 0;
int n = reader.getNumberOfPages();
BaseFont bf = BaseFont.createFont("GARABD.TTF", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
Font font1 = new Font(bf, 12, Font.NORMAL);
selector.addFont(font1);
for (int i = start; i < n + start; i++) {
page = stamper.getOverContent(i - start + 1);
Rectangle rect = reader.getPageSizeWithRotation(i - start + 1);
page.beginText();
page.setFontAndSize(bf, 12);
page.setColorFill(BaseColor.BLACK);
Phrase ph = selector.process(staticText);
ColumnText.showTextAligned(page, Element.ALIGN_RIGHT, ph, rect.getRight(350), rect.getTop(60), 0);
page.endText();
}
When I try to add the same text by the below method no error comes up, below is the code:-
PdfReader reader = new PdfReader(pdfBytes);
PdfStamper stamper = new PdfStamper(reader, pdfOutputByteArray);
PdfContentByte page;
FontSelector selector = new FontSelector();
int start = 0;
int n = reader.getNumberOfPages();
BaseFont bf = BaseFont.createFont("GARABD.TTF", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
Font font1 = new Font(bf, 12, Font.NORMAL);
selector.addFont(font1);
for (int i = start; i < n + start; i++) {
page = stamper.getOverContent(i - start + 1);
Rectangle rect = reader.getPageSizeWithRotation(i - start + 1);
page.beginText();
page.setFontAndSize(bf, 12);
page.setColorFill(BaseColor.BLACK);
page.setTextMatrix(rect.getRight(455), rect.getTop(60));
page.showText(staticText);
page.endText();
I would like to mention that this is happening for just one particular pdf of one page. Below is the pdf link:-
Download Link: https://www.send18.com/?uid=a89d-403ee175
Password: 9mbBvqwY
The code can't be changed because it has been written at many places, moreover changing the code for just one pdf doesn't make sense.
Please advise what can be the issue.
You are mixing two different things.
You can either have this:
page.beginText();
page.setFontAndSize(bf, 12);
page.setColorFill(BaseColor.BLACK);
page.showTextAligned(Element.ALIGN_RIGHT, "some text", x, y, 0);
page.endText();
Or you can have this:
Phrase ph = new Phrase("some text");
ColumnText.showTextAligned(page, Element.ALIGN_RIGHT, ph, x, y, 0);
The latter is shorthand for the former.
ColumnText.showTextAligned() creates a beginText() and endText() internally, so you have something like:
page.beginText();
page.setFontAndSize(bf, 12);
page.setColorFill(BaseColor.BLACK);
page.beginText();
page.setFontAndSize(bf, 12);
page.showTextAligned(Element.ALIGN_RIGHT, "some text", x, y, 0);
page.endText();
page.endText();
It's illegal in PDF to nest text objects and that is what's causing the error.
I advise that you remove the following lines form your code:
page.beginText();
page.setFontAndSize(bf, 12);
page.setColorFill(BaseColor.BLACK);
page.endText();
This should solve the problem.
You say that you can't change the code, but you should. Right now all the PDFs you are creating are wrong. The error is ignored in most cases, but there's no guarantee that the error will be ignored by (all versions of) all PDF viewers.
I need to know if someone can help me about this cool free PDF generator: iText using JAVA.
My request is this: I've a string with html tags such as:
<bold>Hi everyone</bolddd>, my name is <italic>Maurice</italic>.
Is possible to "parse" my string and make the PDF with the correct output about the font (bold, italic, etc etc etc)??
Thanks in advance.
Try the below code...
String htmlString="<bold>Hi everyone</bolddd>, my name is <italic>Maurice</italic>";
ArrayList p=new ArrayList();
StringReader strReader = new StringReader(htmlString);
Document document = new Document(PageSize.A4, 20, 20, 20, 50);
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("filename.pdf"));
document.open();
-------
-------
p = HTMLWorker.parseToList(strReader, null);
Paragraph paragraph=new paragraph();
for (int k = 0; k < p.size(); ++k){
paragraph.add((com.lowagie.text.Element)p.get(k));
}
document.add(paragraph);
-------
-------
document.close();
Hope this helps...
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();