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

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)

Related

Create PDF file with embedded SVG in Java

I have an SVG file and I need to create a PDF that has the SVG embedded. I tried with Apache PDFBox (see below) but I get an error saying that "SVG files are not supported". Any ideas how to create a PDF with an embedded SVG? It doesn't have to be with PDFBox, and I prefer not to convert the SVG to an image file.
PDDocument doc = new PDDocument();
PDPage page = new PDPage();
doc.addPage(page);
PDImageXObject pdImage = PDImageXObject.createFromFile("C:/chart.svg", doc);
PDPageContentStream contentStream = new PDPageContentStream(doc, page);
contentStream.drawImage(pdImage, 70, 250);
contentStream.close();
doc.save("C:/chart.pdf");
doc.close();
Exception in thread "main" java.lang.IllegalArgumentException: Image
type not supported: chart.svg at
org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject.createFromFileByExtension(PDImageXObject.java:257)
at
org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject.createFromFile(PDImageXObject.java:202)
at testjava.TestPdfBox.main(TestPdfBox.java:18)

Not able to add extra content to an existing PDF using PDFBox

I am using PdfBox to generate pdf with an existing Pdf containing the template which has to be used for every Pdf that i want to generate.
But When i try to load the template pdf and wants to write something in it, all previous contains were removed.
So i want both the content should be shown.
Please suggest any solution for it.
Here is the code i am trying to do :
//Loading an existing document
File file = new File("/home/spaneos/ScoringReports-TM-110617.pdf");
PDDocument document = PDDocument.load(file);
//Retrieving the pages of the document
PDPage page = document.getPage(0);
PDPageContentStream contentStream = new PDPageContentStream(document, page);
//Begin the Content stream
contentStream.beginText();
//Setting the font to the Content stream
contentStream.setFont( PDType1Font.TIMES_ROMAN, 16 );
//Setting the leading
contentStream.setLeading(14.5f);
//Setting the position for the line
contentStream.newLineAtOffset(25, 725);
String text1 = "This is an example of adding text to a page in the pdf document.we can add as many lines";
String text2 = "as we want like this using the ShowText() method of the ContentStream class";
//Adding text in the form of string
contentStream.showText(text1);
contentStream.newLine();
contentStream.showText(text2);
//Creating PDImageXObject object
PDImageXObject pdImage = PDImageXObject.createFromFile("/home/spaneos/Downloads/man-161282_960_720.png",document);
//creating the PDPageContentStream object
PDPageContentStream contents = new PDPageContentStream(document, page);
contentStream.endText();
System.out.println("Content added");
//Closing the PDPageContentStream object
contents.close();
//Closing the content stream
contentStream.close();
//Saving the document
document.save(System.getProperty("user.dir").concat("/PdfBox_Examples/sample.pdf"));
//Closing the document
document.close();
You create the PDPageContentStream instances like this
PDPageContentStream contentStream = new PDPageContentStream(document, page);
[...]
PDPageContentStream contents = new PDPageContentStream(document, page);
Creating it using this constructor replaces any existing content streams with the new one. Instead use this one:
PDPageContentStream contents = new PDPageContentStream(document, page, AppendMode.APPEND, true, true);
AppendMode.APPEND here tells PDFBox to append the new stream, the first true tells it to compress the stream, and the second true tells it to reset the graphics state at the start of your added stream.
Furthermore, you don't really use the second content stream...

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.

Creating new PDF with multiple pages using existing PDF as template

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();

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