Apache PdfBox - MultiLine Content being overwritten while writing into pdf

39 Views Asked by At

I need to create a pdf that contains multi-line content. I am able to create the pdf successfully. However there are some portion that are being overwritten. I have tried using contentStream.newLine() but it does not work. I am not sure what am i missing. Could you please let me know how to rectify this.

Below is the generated pdf: Generated PDF Screenshot

Below is the code :

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.font.PDType1Font;


public class PDFGen {

    public static void main(String[] args) {
        try {
            PDDocument document = new PDDocument();
            PDPage page = new PDPage(org.apache.pdfbox.pdmodel.common.PDRectangle.A4);
            document.addPage(page);

            generateContent(document);

            document.save("output.pdf");
            document.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static void generateContent(PDDocument document) throws IOException {
        PDPage page = document.getPage(0);


        PDPageContentStream contentStream = new PDPageContentStream(document, page, PDPageContentStream.AppendMode.APPEND, true);
        contentStream.setFont(org.apache.pdfbox.pdmodel.font.PDType1Font.HELVETICA_BOLD, 12);
        float margin = 50;
        float yStart = page.getMediaBox().getHeight() - margin;
        float yPosition = yStart;
        float bottomMargin = 70;
        float width = page.getMediaBox().getWidth() - 2 * margin;
        List<String> lines = getSampleText(); // Your content goes here

        for (String line : lines) {
            if (yPosition - bottomMargin < 0) {
                contentStream.close();
                page = new PDPage(org.apache.pdfbox.pdmodel.common.PDRectangle.A4);
                document.addPage(page);
                contentStream = new PDPageContentStream(document, page, PDPageContentStream.AppendMode.APPEND, true);
                yStart = page.getMediaBox().getHeight() - margin;
                yPosition = yStart;
            }

            drawText(contentStream, line, margin, yPosition, width);
            yPosition -= 25; // Adjust line height
        } 

        contentStream.close();
    }

    private static void drawText(PDPageContentStream contentStream, String text, float x, float y, float width) throws IOException {
        List<String> lines = new ArrayList<>();
        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 = PDType1Font.HELVETICA_BOLD.getStringWidth(subString) / 1000 * 12;
            if (size > width) {
                if (lastSpace < 0)
                    lastSpace = spaceIndex;
                subString = text.substring(0, lastSpace);
                lines.add(subString);
                text = text.substring(lastSpace).trim();
                lastSpace = -1;
            } else if (spaceIndex == text.length()) {
                lines.add(text);
                text = "";
            } else {
                lastSpace = spaceIndex;
            }
        }
        
        contentStream.setFont(PDType1Font.HELVETICA_BOLD, 12);

        contentStream.beginText();
        contentStream.newLineAtOffset(x, y);
        for (String line : lines) {
            contentStream.showText(line);
            contentStream.newLine();
            contentStream.newLineAtOffset(0, -12); // Adjust line height
        }
        contentStream.endText();
    }

    private static List<String> getSampleText() {
        List<String> lines = new ArrayList<>();
         lines.add("1.1.");
         lines.add("Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.ffffffff");
         lines.add("Lorem ipsum dolor sit amet, consectetur adipiscing elit.");
         lines.add("qwertyu");
         lines.add("1.2.");
         lines.add("Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.Ut enim ad minim veniam, quis nostrud exercit");
         lines.add("Lorem ipsum dolor sit amet, consectetur adipiscing elit.");
         lines.add("qwertyu");
         lines.add("1.3.");
         lines.add("Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.Ut enim ad minim veniam, quis nostrud exercit");
         lines.add("Lorem ipsum dolor sit amet, consectetur adipiscing elit.");
         lines.add("qwertyu");
         
        return lines;
    }
}
1

There are 1 best solutions below

2
Techies On

Change code to:

contentStream.setFont(PDType1Font.HELVETICA_BOLD, 12);

        contentStream.beginText();
        
        for (String line : lines) {
            contentStream.newLineAtOffset(x, y);
            contentStream.showText(line);
        }
        contentStream.endText();