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:
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.
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.
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.
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):
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)
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)
This looks as expected.
Of course there are numerous improvements to make but this should show how to do it.
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:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With