When you large content to be displayed in the PDF using the pdPageContentStream.showText(str) the content can sometimes go out of the PDF and get cut. See below example :
1 2 3 4 5 6 7 |
String content = "Anyone, anywhere can open a PDF file. " + "All you need is the free Adobe Acrobat Reader. " + "Recipients of other file formats sometimes can't open files " + "because they don't have the applications " + "used to create the documents."; pdPageContentStream.showText(content); |
To avoid this we need some processing to be done of the content, so that it is converted into an array that can be printed without cutting any data.
Steps to Add multiple lines in PDF using Apache PDFBox
1) Define all the constants like X, Y coordinates, font, font size and the pdf margin
1 2 3 4 5 |
int cursorX = 25; int cursorY = 700; PDFont pdFont = PDType1Font.HELVETICA; int fontSize = 12; int margin = 50; |
2) Using the PDRectangle class get the allowed printable width inside the pdf
1 2 |
PDRectangle mediabox = pdPage.getMediaBox(); float printableWidth = mediabox.getWidth() - (2 * margin) - cursorX; |
3) Inside a While loop, check the length of the content Vs the printable width. If content length is greater, then cut the length into the printable width allowed. Add that to the array. Process the remaining content again in loop.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
boolean convertContent = true; while (convertContent) { int contentSize = (int) (fontSize * pdFont.getStringWidth(content) / 1000); if (contentSize > printableWidth) { int contentLength = content.length(); float rem = contentSize / printableWidth; float lenForSubString = contentLength / rem; int lenForSubStringInt = (int) Math.floor(lenForSubString); finalLines.add(content.substring(0, lenForSubStringInt)); content = content.substring(lenForSubStringInt); } else { finalLines.add(content); convertContent = false; } } |
4) IMPORTANT : Setting a leading to avoid the overlapping of text
1 |
pdPageContentStream.setLeading(15f); |
5) Loop the array and print the lines one by one. Use pdPageContentStream.newLine() after each line.
1 2 3 4 |
for (String str : finalLines) { pdPageContentStream.showText(str); pdPageContentStream.newLine(); } |
Example
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 |
package com.kscodes.examples.pdfbox; import java.io.IOException; import java.util.ArrayList; import java.util.List; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.PDPageContentStream; import org.apache.pdfbox.pdmodel.common.PDRectangle; import org.apache.pdfbox.pdmodel.font.PDFont; import org.apache.pdfbox.pdmodel.font.PDType1Font; public class PdfMultipleLinesExample { public static void main(String args[]) { PDDocument pdDocument = new PDDocument(); PDPage pdPage = new PDPage(); pdDocument.addPage(pdPage); String content = "Anyone, anywhere can open a PDF file. " + "All you need is the free Adobe Acrobat Reader. " + "Recipients of other file formats sometimes can't open files " + "because they don't have the applications " + "used to create the documents."; // Define all the constants like X, Y coordinates, font, font size and // the pdf margin int cursorX = 25; int cursorY = 700; PDFont pdFont = PDType1Font.HELVETICA; int fontSize = 12; int margin = 50; // Using the PDRectangle class get the printableWidth PDRectangle mediabox = pdPage.getMediaBox(); float printableWidth = mediabox.getWidth() - (2 * margin) - cursorX; // We will convert the String content into a array of strings/lines List<String> finalLines = new ArrayList<>(); try { // Inside a While loop, check the length of the content Vs the // Printable width. If content length is greater, then cut the // length into the printable width allowed. Add that to the array. // Process the remaining content again in loop. boolean convertContent = true; while (convertContent) { int contentSize = (int) (fontSize * pdFont.getStringWidth(content) / 1000); if (contentSize > printableWidth) { int contentLength = content.length(); float rem = contentSize / printableWidth; float lenForSubString = contentLength / rem; int lenForSubStringInt = (int) Math.floor(lenForSubString); finalLines.add(content.substring(0, lenForSubStringInt)); content = content.substring(lenForSubStringInt); } else { finalLines.add(content); convertContent = false; } } PDPageContentStream pdPageContentStream = new PDPageContentStream(pdDocument, pdPage); pdPageContentStream.beginText(); pdPageContentStream.newLineAtOffset(cursorX, cursorY); pdPageContentStream.setFont(pdFont, fontSize); // Setting a leading while avoid the overlapping of text. pdPageContentStream.setLeading(15f); // Loop the array and print the lines one by one for (String str : finalLines) { pdPageContentStream.showText(str); pdPageContentStream.newLine(); } pdPageContentStream.endText(); pdPageContentStream.close(); pdDocument.save("K:\\Kscodes\\pdf\\multiplelines-sample.pdf"); pdDocument.close(); System.out.println("PDF saved to the location !!!"); } catch (IOException ioe) { System.out.println("Error while saving pdf" + ioe.getMessage()); } } } |
Output
Reference
1)Apache PDFBox