Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to generate multiple lines in PDF using Apache pdfbox

I am using Pdfbox to generate PDF files using Java. The problem is that when i add long text contents in the document, it is not displayed properly. Only a part of it is displayed. That too in a single line.

I want text to be in multiple lines.

My code is given below:

PDPageContentStream pdfContent=new PDPageContentStream(pdfDocument, pdfPage, true, true);  pdfContent.beginText(); pdfContent.setFont(pdfFont, 11); pdfContent.moveTextPositionByAmount(30,750);             pdfContent.drawString("I am trying to create a PDF file with a lot of text contents in the document. I am using PDFBox"); pdfContent.endText(); 

My output:

This is my output file

like image 814
Ronald James Avatar asked Oct 28 '13 12:10

Ronald James


People also ask

How do I add a line in a PDFBox?

In order to add multiple lines to a PDF you need to set the leading using the setLeading() method and shift to new line using newline() method after finishing each line.

How do you write paragraphs in PDFBox?

Adding Text to an Existing PDF Document. You can add contents to a document using the PDFBox library, this provides you a class named PDPageContentStream which contains the required methods to insert text, images, and other types of contents in a page of a PDFDocument.

Which is better iText or PDFBox?

One major difference is that PDFBox always processes text glyph by glyph while iText normally processes it chunk (i.e. single string parameter of text drawing operation) by chunk; that reduces the required resources in iText quite a lot.


1 Answers

Adding to the answer of Mark you might want to know where to split your long string. You can use the PDFont method getStringWidth for that.

Putting everything together you get something like this (with minor differences depending on the PDFBox version):

PDFBox 1.8.x

PDDocument doc = null; try {     doc = new PDDocument();     PDPage page = new PDPage();     doc.addPage(page);     PDPageContentStream contentStream = new PDPageContentStream(doc, page);      PDFont pdfFont = PDType1Font.HELVETICA;     float fontSize = 25;     float leading = 1.5f * fontSize;      PDRectangle mediabox = page.findMediaBox();     float margin = 72;     float width = mediabox.getWidth() - 2*margin;     float startX = mediabox.getLowerLeftX() + margin;     float startY = mediabox.getUpperRightY() - margin;      String text = "I am trying to create a PDF file with a lot of text contents in the document. I am using PDFBox";      List<String> lines = new ArrayList<String>();     int lastSpace = -1;     while (text.length() > 0)     {         int spaceIndex = text.indexOf(' ', lastSpace + 1);         if (spaceIndex < 0)             spaceIndex = text.length();         String subString = text.substring(0, spaceIndex);         float size = fontSize * pdfFont.getStringWidth(subString) / 1000;         System.out.printf("'%s' - %f of %f\n", subString, size, width);         if (size > width)         {             if (lastSpace < 0)                 lastSpace = spaceIndex;             subString = text.substring(0, lastSpace);             lines.add(subString);             text = text.substring(lastSpace).trim();             System.out.printf("'%s' is line\n", subString);             lastSpace = -1;         }         else if (spaceIndex == text.length())         {             lines.add(text);             System.out.printf("'%s' is line\n", text);             text = "";         }         else         {             lastSpace = spaceIndex;         }     }              contentStream.beginText();     contentStream.setFont(pdfFont, fontSize);     contentStream.moveTextPositionByAmount(startX, startY);                 for (String line: lines)     {         contentStream.drawString(line);         contentStream.moveTextPositionByAmount(0, -leading);     }     contentStream.endText();      contentStream.close();      doc.save("break-long-string.pdf"); } finally {     if (doc != null)     {         doc.close();     } } 

(BreakLongString.java test testBreakString for PDFBox 1.8.x)

PDFBox 2.0.x

PDDocument doc = null; try {     doc = new PDDocument();     PDPage page = new PDPage();     doc.addPage(page);     PDPageContentStream contentStream = new PDPageContentStream(doc, page);      PDFont pdfFont = PDType1Font.HELVETICA;     float fontSize = 25;     float leading = 1.5f * fontSize;      PDRectangle mediabox = page.getMediaBox();     float margin = 72;     float width = mediabox.getWidth() - 2*margin;     float startX = mediabox.getLowerLeftX() + margin;     float startY = mediabox.getUpperRightY() - margin;      String text = "I am trying to create a PDF file with a lot of text contents in the document. I am using PDFBox";      List<String> lines = new ArrayList<String>();     int lastSpace = -1;     while (text.length() > 0)     {         int spaceIndex = text.indexOf(' ', lastSpace + 1);         if (spaceIndex < 0)             spaceIndex = text.length();         String subString = text.substring(0, spaceIndex);         float size = fontSize * pdfFont.getStringWidth(subString) / 1000;         System.out.printf("'%s' - %f of %f\n", subString, size, width);         if (size > width)         {             if (lastSpace < 0)                 lastSpace = spaceIndex;             subString = text.substring(0, lastSpace);             lines.add(subString);             text = text.substring(lastSpace).trim();             System.out.printf("'%s' is line\n", subString);             lastSpace = -1;         }         else if (spaceIndex == text.length())         {             lines.add(text);             System.out.printf("'%s' is line\n", text);             text = "";         }         else         {             lastSpace = spaceIndex;         }     }      contentStream.beginText();     contentStream.setFont(pdfFont, fontSize);     contentStream.newLineAtOffset(startX, startY);     for (String line: lines)     {         contentStream.showText(line);         contentStream.newLineAtOffset(0, -leading);     }     contentStream.endText();      contentStream.close();      doc.save(new File(RESULT_FOLDER, "break-long-string.pdf")); } finally {     if (doc != null)     {         doc.close();     } } 

(BreakLongString.java test testBreakString for PDFBox 2.0.x)

The result

Screenshot of the result PDF displayed in Acrobat Reader

This looks as expected.

Of course there are numerous improvements to make but this should show how to do it.

Adding unconditional line breaks

In a comment aleskv asked:

could you add line breaks when there are \n in the string?

One can easily extend the solution to unconditionally break at newline characters by first splitting the string at '\n' characters and then iterating over the split result.

E.g. if instead of the long string from above

String text = "I am trying to create a PDF file with a lot of text contents in the document. I am using PDFBox";  

you want to process this even longer string with embedded new line characters

String textNL = "I am trying to create a PDF file with a lot of text contents in the document. I am using PDFBox.\nFurthermore, I have added some newline characters to the string at which lines also shall be broken.\nIt should work alright like this..."; 

you can simply replace

String text = "I am trying to create a PDF file with a lot of text contents in the document. I am using PDFBox";  List<String> lines = new ArrayList<String>(); int lastSpace = -1; while (text.length() > 0) {     [...] } 

in the solutions above by

String textNL = "I am trying to create a PDF file with a lot of text contents in the document. I am using PDFBox.\nFurthermore, I have added some newline characters to the string at which lines also shall be broken.\nIt should work alright like this...";  List<String> lines = new ArrayList<String>(); for (String text : textNL.split("\n")) {     int lastSpace = -1;     while (text.length() > 0)     {         [...]     } } 

(from BreakLongString.java test testBreakStringNL)

The result:

Screenshot

like image 169
mkl Avatar answered Oct 08 '22 21:10

mkl