PDFBox does not write the message I want into the page

Viewed 118

I'm looking for at least an hour at my code but I can't find the bug. I'm using PDFBox to create PDF's (PDFBox HelloWorld Example). To learn how PDFBox works I just wanted to create some pages with "hello world" and the page number like "hello world 1", "hello world 2" and so on. As you can see I created a for loop to create six pages.

private void drawPDF(PDDocument doc, File file) throws IOException {
    for (int pageIndex = 0; pageIndex < 6; pageIndex++) {
        PDPage page = new PDPage(PDRectangle.A4);
        doc.addPage(page);
        PDFont font = PDType1Font.HELVETICA_BOLD;
        String message = "hello world " + (pageIndex + 1);
        float stringHeight = font.getFontDescriptor().getFontBoundingBox().getHeight() * FONT_SIZE;
        PDRectangle pageSize = page.getMediaBox();
        try (PDPageContentStream contents = new PDPageContentStream(doc, page)) {
            contents.beginText();
            contents.setFont(font, FONT_SIZE);
            contents.setTextMatrix(Matrix.getTranslateInstance(0, pageSize.getHeight() - stringHeight / 1000f));
            contents.showText(message);
            System.out.println(message + " - " + doc.getNumberOfPages());
            contents.endText();
        }
    }
    doc.save(file);
}

In my console I get the following output (first number is pageIndex, second number is doc.getNumberOfPages()):

hello world 1 - 1
hello world 2 - 2
hello world 3 - 3
hello world 4 - 4
hello world 5 - 5
hello world 6 - 6

This is my load function to view the pdf.

private final ObservableList<Image> pdfFilePages = FXCollections.observableArrayList();


private void loadFile(File file) throws FileNotFoundException, IOException {
    if (file != null) {
        ByteBuffer buffer = null;
        try (RandomAccessFile raf = new RandomAccessFile(file, "r"); FileChannel channel = raf.getChannel()) {
            buffer = ByteBuffer.allocate((int) channel.size());
            channel.read(buffer);
            buffer.flip();

            PDFFile pdfFile = new PDFFile(buffer);
            List<Image> pages = new ArrayList<>();
            for (int i = 0; i < pdfFile.getNumPages(); i++) {
                PDFPage page = pdfFile.getPage(i, true);
                System.out.println("page: " + i + " - " + pdfFile.getNumPages());
                java.awt.geom.Rectangle2D bbox = page.getBBox();
                java.awt.geom.Rectangle2D rect = new Rectangle(0, 0, (int) bbox.getWidth(), (int) bbox.getHeight());
                BufferedImage buffImage = new BufferedImage((int) (bbox.getWidth() * 2d),
                        (int) (bbox.getHeight() * 2d), BufferedImage.TYPE_INT_RGB);
                java.awt.Image awtImage = page.getImage((int) (bbox.getWidth() * 2.0),
                        (int) (bbox.getHeight() * 2.0), rect, null, true, true);
                java.awt.Graphics2D bufImageGraphics = buffImage.createGraphics();
                bufImageGraphics.drawImage(awtImage, 0, 0, null);

                Image image = SwingFXUtils.toFXImage(buffImage, null);
                pages.add(image);
            }
            pdfFilePages.addAll(pages);
        }
    }
}

This is what I get in my console:

page: 0 - 6
page: 1 - 6
page: 2 - 6
page: 3 - 6
page: 4 - 6
page: 5 - 6

When I load the pdf file to display the content in my application i get "hello world 1 - 1" for the first and second page. The following pages have "hello world 2 - 2" to "hello world 5 - 5". I don't understand why I get two pages of "hello world 1 - 1". I hope someone can explain to me where I made a mistake.

1 Answers

With the help of mkl I found the bug in my code. The for loop has to start at 1 and run until the index is equal to pdfFile.getNumPages(). The method getPage() return the first page when the index is 0. Because the index is 1 in the second iteration, the first page will be passed twice. The last page won't be passed since the loop has been finished. This seems to be the right approach.

private void loadFile(File file) throws FileNotFoundException, IOException {
    if (file != null) {
        ByteBuffer buffer = null;
        try (RandomAccessFile raf = new RandomAccessFile(file, "r"); FileChannel channel = raf.getChannel()) {
            buffer = ByteBuffer.allocate((int) channel.size());
            channel.read(buffer);
            buffer.flip();

            PDFFile pdfFile = new PDFFile(buffer);
            List<Image> pages = new ArrayList<>();
            for (int i = 1; i <= pdfFile.getNumPages(); i++) {
                PDFPage page = pdfFile.getPage(i, true);
                System.out.println("page: " + i + " - " + pdfFile.getNumPages());
                java.awt.geom.Rectangle2D bbox = page.getBBox();
                java.awt.geom.Rectangle2D rect = new Rectangle(0, 0, (int) bbox.getWidth(), (int) bbox.getHeight());
                BufferedImage buffImage = new BufferedImage((int) (bbox.getWidth() * 2d),
                        (int) (bbox.getHeight() * 2d), BufferedImage.TYPE_INT_RGB);
                java.awt.Image awtImage = page.getImage((int) (bbox.getWidth() * 2.0),
                        (int) (bbox.getHeight() * 2.0), rect, null, true, true);
                java.awt.Graphics2D bufImageGraphics = buffImage.createGraphics();
                bufImageGraphics.drawImage(awtImage, 0, 0, null);

                Image image = SwingFXUtils.toFXImage(buffImage, null);
                pages.add(image);
            }
            pdfFilePages.addAll(pages);
        }
    }
}
Related