Creating new PDF with multiple pages using existing PDF as template - java

I've been using PDFBox in an attempt to spit out an auto-generated PDF based off an existing template. The code below fails at finalDoc.save() with an IndexOutOfBoundsException and I'm not sure what I'm doing wrong.
PDDocument finalDoc = new PDDocument();
for (StudentEN student : students) {
PDDocument document = PDDocument.load("template.pdf");
PDPage page = (PDPage) document.getDocumentCatalog().getAllPages().get(0);
PDPageContentStream contentStream = new PDPageContentStream(document, page, true, true);
contentStream.beginText();
// Draw stuff
contentStream.endText();
contentStream.close();
finalDoc.addPage(page);
document.close();
}
finalDoc.save(response.getOutputStream());
finalDoc.close();
Any help is greatly appreciated!

PDFMergerUtility did the job for me:
PDFMergerUtility finalDoc = new PDFMergerUtility();
for (StudentEN student : students) {
PDDocument document = PDDocument.load("template.pdf");
PDPage page = (PDPage) document.getDocumentCatalog().getAllPages().get(0);
PDPageContentStream contentStream = new PDPageContentStream(document, page, true, true);
contentStream.beginText();
// Draw stuff
contentStream.endText();
contentStream.close();
ByteArrayOutputStream out = new ByteArrayOutputStream();
document.save(out);
finalDoc.addSource(new ByteArrayInputStream(out.toByteArray()));
document.close();
}
response.setContentType("application/pdf");
finalDoc.setDestinationStream(response.getOutputStream());
finalDoc.mergeDocuments();

Related

PDF Box - Getting error while adding title

I Tried adding title , but am getting error for pdPageContentStream.drawString();
Error: " drawString(java.lang.String)' is deprecated "
PDDocument document = new PDDocument();
PDPage page = new PDPage(PDRectangle.A4);
// PDRectangle.LETTER and others are also possible
PDRectangle rect = page.getMediaBox();
document.addPage(page);
try {
// Create a Content Stream
PDPageContentStream pdPageContentStream = new PDPageContentStream(document, page);
pdPageContentStream.beginText();
pdPageContentStream.drawString();
pdPageContentStream.endText();
// Creating an PDImageXObject object
PDImageXObject pdImageXObj = PDImageXObject.createFromFile("resources/images/new.png", document);
// Draw that image to the content stream
pdPageContentStream.drawImage(pdImageXObj, 30, 650);
pdPageContentStream.drawString();
// Once all the content is written, close the stream
pdPageContentStream.close();
}
catch (IOException e) {
e.printStackTrace();
}

Unicode Font writing problem with PDFBox2(No glyph for U+0053)

I trying to write some bengali text into a pdf with PDFBox but facing some problem No glyph for U+0053.I have no idea for glyph.
File file = new File("xyz.pdf");
PDDocument document = PDDocument.load(file);
PDPage page = document.getPage(0);
PDPageContentStream contentStream = new PDPageContentStream(document, page);
contentStream.beginText();
PDFont font = PDType0Font.load(document, BengaliPdfGenerationHelloWorld.class.getResourceAsStream("/textloc/Lohit-Bengali.ttf"),true);
contentStream.setFont(font,12);
contentStream.newLineAtOffset();
contentStream.showText(text);
contentStream.endText();
System.out.println("Content added");
contentStream.close();
document.save(new File("new.pdf"));
Exception in thread "main" java.lang.IllegalArgumentException: No glyph for U+0053 (S) in font Lohit-Bengali
at org.apache.pdfbox.pdmodel.font.PDCIDFontType2.encode(PDCIDFontType2.java:366)
at org.apache.pdfbox.pdmodel.font.PDType0Font.encode(PDType0Font.java:415)
at org.apache.pdfbox.pdmodel.font.PDFont.encode(PDFont.java:342)

PDFBox add background when creating document [duplicate]

This question already has answers here:
Watermarking with PDFBox
(7 answers)
Closed 3 years ago.
So I want to not only add text to a pdf when I create it but as well add a background image at the same time. I was wondering if this is possible since I haven't been able to find any example and the only question similar to this (This one) has not given any feedback from the person that made the question and it wasn't marked as solved.
I'm using this very simple example at the moment:
PDDocument doc = null;
PDPage page = null;
try{
doc = new PDDocument();
page = new PDPage();
doc.addPage(page);
PDFont font = PDType1Font.HELVETICA_BOLD;
PDPageContentStream content = new PDPageContentStream(doc, page);
content.beginText();
content.setFont( font, 12 );
content.moveTextPositionByAmount( 100, 700 );
content.drawString("Hello World");
content.endText();
content.close();
doc.save("printme.pdf");
doc.close();
} catch (Exception e){
System.out.println(e);
}
Thanks for your time.
try {
PDDocument document = new PDDocument();
PDPage page = new PDPage(PDPage.PAGE_SIZE_A4);
document.addPage(page);
PDFont font = PDType1Font.HELVETICA_BOLD;
PDPageContentStream contentStream = new PDPageContentStream(document, page, true, true);
addImageToPage(document, 0, 0, 4f, "D:/test.jpg", contentStream);
contentStream.beginText();
contentStream.setFont(font, 12);
contentStream.moveTextPositionByAmount(100, 700);
contentStream.drawString("Hello World");
contentStream.endText();
contentStream.close();
document.save("D:/mydoc.pdf");
} catch (Exception e) {
System.out.println(e);
}
method to add image :
public static void addImageToPage(PDDocument document, int x, int y, float scale, String imageFilePath, PDPageContentStream contentStream)
throws IOException {
BufferedImage tmp_image = ImageIO.read(new File(imageFilePath));
BufferedImage image = new BufferedImage(tmp_image.getWidth(), tmp_image.getHeight(),
BufferedImage.TYPE_4BYTE_ABGR);
image.createGraphics().drawRenderedImage(tmp_image, null);
PDXObjectImage ximage = new PDPixelMap(document, image);
contentStream.drawXObject(ximage, x, y, ximage.getWidth() * scale, ximage.getHeight() * scale);
}

Unable to add Pages to PDF using PDFBox using separate method from main()

I am trying to dynamically add PDF pages depending upon content size.
for that I did not want to clutter the main method, instead I created a separate method to write the PDF and call the method from main() like below:
//PDF Log Method
PDlog("Create First Page", "b");
PDlog("add more page", "b");
PDlog("close pdf", "b");
I have added system.out.println at the end of each if condition, and all three are getting printed on IDE screen. but an Empty PDF is being generated after 3 method calls end. When I had only one if condition and called the PDlog method only once, the PDF is being saved and closed properly.
How can I call this method multiple times from main and keep on adding page and content multiple times?
Below is the method code:
public static void PDlog(String action, String msg) throws IOException, ClassNotFoundException, SQLException, InterruptedException, COSVisitorException {
//Master PDF Log File --------------------------------------------------------------------
String masterPDLog = "X:\\eHub\\QA\\eHub_Automation_Log.pdf";
// Create a document and add a page to it
PDDocument document = new PDDocument();
PDPage page = new PDPage(PDPage.PAGE_SIZE_A4);
if (action.equals("Create First Page")) {
document.addPage(page);
// Create a new font object selecting one of the PDF base fonts
PDFont font = PDType1Font.TIMES_ROMAN;
PDFont boldFont = PDType1Font.TIMES_BOLD;
//File for CTS Logo --------------------
InputStream in = new FileInputStream(new File("X:\\eHub\\QA\\img\\cts.jpg"));
PDJpeg img = new PDJpeg(document, in);
// Start a new content stream which will "hold" the to be created content
PDPageContentStream contentStream = new PDPageContentStream(document, page);
//Place CTS Logo
//contentStream.drawImage(img, 500, 750);
contentStream.drawXObject( img, 450, 700, 50, 50 );
// Define a text content stream using the selected font, moving the cursor and drawing the text "Hello World"
contentStream.beginText();
contentStream.setFont( boldFont, 20 );
contentStream.setNonStrokingColor(Color.BLUE);
contentStream.moveTextPositionByAmount( 120, 650 );
contentStream.drawString("eHub Automated Data Quality Report");
contentStream.endText();
contentStream.beginText();
contentStream.setFont( boldFont, 20 );
contentStream.setNonStrokingColor(Color.BLUE);
contentStream.moveTextPositionByAmount( 140, 600 );
contentStream.drawString("Data Profiling/Quality/Analysis");
contentStream.endText();
// Make sure that the content stream is closed:
contentStream.close();
//document.save(masterPDLog);
System.out.println("1ST PAGE ADDED");
}
else if (action.equals("add more page")) {
PDFont font = PDType1Font.TIMES_ROMAN;
document.addPage(page);
PDPageContentStream contentStream = new PDPageContentStream(document, page);
contentStream.beginText();
contentStream.setFont( font, 20 );
contentStream.setNonStrokingColor(Color.BLACK);
contentStream.moveTextPositionByAmount( 100, 800 );
contentStream.drawString("eHub Automated Data Quality Report");
contentStream.endText();
contentStream.close();
//document.save(masterPDLog);
System.out.println("2ND PAGE ADDED");
}
else if (action.equals("close pdf")) {
PDFont font = PDType1Font.TIMES_ROMAN;
PDPageContentStream contentStream = new PDPageContentStream(document, page);
contentStream.beginText();
contentStream.setFont( font, 20 );
contentStream.setNonStrokingColor(Color.BLACK);
contentStream.moveTextPositionByAmount( 100, 800 );
contentStream.drawString("eHub Automated Data Quality Report");
contentStream.endText();
contentStream.close();
document.save(masterPDLog);
document.close();
System.out.println("PDF CLOSED");
}
You create the document each time, that is why.
Just pass the document object to your method, and create the document first - here's your code, corrected:
public static void main(String[] args) throws IOException, COSVisitorException
{
PDDocument document = new PDDocument();
pdlog("Create First Page", "b", document);
pdlog("add more page", "b", document);
pdlog("close pdf", "b", document);
}
public static void pdlog(String action, String msg, PDDocument document) throws IOException, COSVisitorException
{
//Master PDF Log File --------------------------------------------------------------------
String masterPDLog = "X:\\eHub\\QA\\eHub_Automation_Log.pdf";
// Create a document and add a page to it
PDPage page = new PDPage(PDPage.PAGE_SIZE_A4);
if (action.equals("Create First Page"))
{
document.addPage(page);
// Create a new font object selecting one of the PDF base fonts
PDFont font = PDType1Font.TIMES_ROMAN;
PDFont boldFont = PDType1Font.TIMES_BOLD;
//File for CTS Logo --------------------
InputStream in = new FileInputStream(new File("X:\\eHub\\QA\\img\\cts.jpg"));
PDJpeg img = new PDJpeg(document, in);
// Start a new content stream which will "hold" the to be created content
PDPageContentStream contentStream = new PDPageContentStream(document, page);
//Place CTS Logo
//contentStream.drawImage(img, 500, 750);
contentStream.drawXObject(img, 450, 700, 50, 50);
// Define a text content stream using the selected font, moving the cursor and drawing the text "Hello World"
contentStream.beginText();
contentStream.setFont(boldFont, 20);
contentStream.setNonStrokingColor(Color.BLUE);
contentStream.moveTextPositionByAmount(120, 650);
contentStream.drawString("eHub Automated Data Quality Report");
contentStream.endText();
contentStream.beginText();
contentStream.setFont(boldFont, 20);
contentStream.setNonStrokingColor(Color.BLUE);
contentStream.moveTextPositionByAmount(140, 600);
contentStream.drawString("Data Profiling/Quality/Analysis");
contentStream.endText();
// Make sure that the content stream is closed:
contentStream.close();
//document.save(masterPDLog);
System.out.println("1ST PAGE ADDED");
}
else if (action.equals("add more page"))
{
PDFont font = PDType1Font.TIMES_ROMAN;
document.addPage(page);
PDPageContentStream contentStream = new PDPageContentStream(document, page);
contentStream.beginText();
contentStream.setFont(font, 20);
contentStream.setNonStrokingColor(Color.BLACK);
contentStream.moveTextPositionByAmount(100, 800);
contentStream.drawString("eHub Automated Data Quality Report");
contentStream.endText();
contentStream.close();
//document.save(masterPDLog);
System.out.println("2ND PAGE ADDED");
}
else if (action.equals("close pdf"))
{
PDFont font = PDType1Font.TIMES_ROMAN;
PDPageContentStream contentStream = new PDPageContentStream(document, page);
contentStream.beginText();
contentStream.setFont(font, 20);
contentStream.setNonStrokingColor(Color.BLACK);
contentStream.moveTextPositionByAmount(100, 800);
contentStream.drawString("eHub Automated Data Quality Report");
contentStream.endText();
contentStream.close();
document.save(masterPDLog);
document.close();
System.out.println("PDF CLOSED");
}
}
Your "close pdf" action does not make much sense, you are writing to a PDPage that is never appended.
1st of all, thanks Tilman for answering my actual question.
In the meantime, for practical purposes, I have changed my approach to writing dynamically to a PDF, as the code flows through If Else and Loops.... instead I have chosen to simply keep on Logging to simple text file using PrintWriter.
At the final end of the code, I am calling a method to Read each line of the Text Log file and place in a PDF document. To Summarize: One time Text to PDF conversion.
I explored iText and chose it over Apache PDFBox, it is perhaps 2-3 times faster than PDFBox and adding page is implicit and automatic.

PDFBox setting A5 page size

Started playing with PDFBox
PDDocument document = new PDDocument();
PDPage page = new PDPage();
document.addPage( page );
PDFont font = PDType1Font.HELVETICA_BOLD;
PDPageContentStream contentStream = new PDPageContentStream(document, page);
contentStream.beginText();
contentStream.setFont( font, 12 );
contentStream.moveTextPositionByAmount( 100, 700 );
contentStream.drawString( "Hello World" );
contentStream.endText();
contentStream.close();
document.save("Page.pdf");
document.close();
but I want to set the file size to be PDPage.PAGE_SIZE_A5. I've tried setting all the
setXXXBox(PDRectangle mediaBox) method signatures but I can't get the expected output.
page.setArtBox(PDPage.PAGE_SIZE_A5); // ??
page.setMediaBox(PDPage.PAGE_SIZE_A5); // ??
Any ideas?
Quick note: in PDFBox 2 replace PDPage.PAGE_SIZE_A5 with PDRectangle.A5, i.e.
PDPage page = new PDPage(PDRectangle.A5);
Use PDPage.PAGE_SIZE_A5 to change size to A5
PDPage page = new PDPage(PDPage.PAGE_SIZE_A5);

Categories

Resources