1
votes

What I am trying to do here is to create text and place it onto a blank page. That page would then be overlayed onto another document and that would then be saved as one document. In 1.8 I was able to create a blank PDPage in a PDF, write text to it as needed, then overlay that PDF with another and then save or view on screen using the code below -

overlayDoc = new PDDocument();
page = new PDPage();
overlayDoc.addPage(page);
overlayObj = new Overlay();
font = PDType1Font.COURIER_OBLIQUE;
try {
    contentStream = new PDPageContentStream(overlayDoc, page);
    contentStream.setFont(font, 10);
}
catch (Exception e){
    System.out.println("content stream failed");
}

After I created the stream, when I needed to write something to the overlay document's contentStream, I would call this method, give it my x, y coords and tell it what text to write (again, this is in my 1.8 version):

protected void writeString(int x, int y, String text) {
    if (text == null) return;
    try {
        contentStream.moveTo(x, y);
        contentStream.beginText();
        contentStream.drawString(text);  // deprecated. Use showText(String text)
        contentStream.endText();
    }
    catch (Exception e){
        System.out.println(text + " failed. " + e.toString());
    }
}

I would call this method whenever I needed to add text and to wherever I needed to do so. After this, I would close my content stream and then merge the documents together as such:

import org.apache.pdfbox.Overlay;
Overlay overlayObj = new Overlay();

....

PDDocument finalDoc = overlayObj.overlay(overlayDoc, originalDoc);

finalDoc now contains a PDDocument which is my original PDF with text overlayed where needed. I could save it and view it as a BufferedImage on the desktop. The reason I moved to 2.0 was that first off I needed to stay on top of the most recent library and also that I was having issues putting an image onto the page (see here).

The issue I am having in this question is that 2.0 no longer has something similar to the org.apache.pdfbox.Overlay class. To confuse me even more is that there are two Overlay classes in 1.8 (org.apache.pdfbox.Overlay and org.apache.pdfbox.util.Overlay) whereas in 2.0 there is only one. The class I need (org.apache.pdfbox.Overlay), or the methods it offers at least, are not present in 2.0 as far as I can tell. I can only find org.apache.pdfbox.multipdf.Overlay.

1
Your question isn't really clear, i.e. did your code work, are you asking before trying anything? Please look at the source code of OverlayPDF.java for5 an example: svn.apache.org/viewvc/pdfbox/trunk/tools/src/main/java/org/… - Tilman Hausherr
I am sorry... No, the code did not work. I already have the two documents. I think that the way I am using my writeString method should be putting text in the contentStream. I should be able to close that contentStream and then merge the originalDoc and overlayDoc together to get a new PDDocument, but when I try to display this as an image I just get the original document. - Rabbit Guy
@TilmanHausherr When I look at the code supplied it is merging two files together. I have the PDF's loaded already as PDDocuments. I need to overlay one over the other. The overlay(Map<Integer,String> specificPageOverlayFile) is what is getting me bcz it needs a file to overlay? - Rabbit Guy
"the code did not work" is not very specific. The best would be to rework your question, to show a complete minimal code in 1.8, and a complete code in 2.0, and an explanation what happens. With these two pieces of software I could investigate this. - Tilman Hausherr
@TilmanHausherr... Updated. - Rabbit Guy

1 Answers

8
votes

Here's some quick code that works, it adds "deprecated" over a document and saves it elsewhere:

    PDDocument overlayDoc = new PDDocument();
    PDPage page = new PDPage();
    overlayDoc.addPage(page);
    Overlay overlayObj = new Overlay();
    PDFont font = PDType1Font.COURIER_OBLIQUE;

    PDPageContentStream contentStream = new PDPageContentStream(overlayDoc, page);
    contentStream.setFont(font, 50);
    contentStream.setNonStrokingColor(0);
    contentStream.beginText();
    contentStream.moveTextPositionByAmount(200, 200);
    contentStream.drawString("deprecated");  // deprecated. Use showText(String text)
    contentStream.endText();
    contentStream.close();

    PDDocument originalDoc = PDDocument.load(new File("...inputfile.pdf"));
    overlayObj.setOverlayPosition(Overlay.Position.FOREGROUND);
    overlayObj.setInputPDF(originalDoc);
    overlayObj.setAllPagesOverlayPDF(overlayDoc);
    Map<Integer, String> ovmap = new HashMap<Integer, String>(); // empty map is a dummy
    overlayObj.setOutputFile("... result-with-overlay.pdf");
    overlayObj.overlay(ovmap);
    overlayDoc.close();
    originalDoc.close();

What I did additionally to your version:

  • declare variables
  • close the content stream
  • set a color
  • set to foreground
  • set a text position (not a stroke path position)
  • add an empty map

And of course, I read the OverlayPDF source code, it shows more possibilities what you can do with the class.

Bonus content:

Do the same without using the Overlay class, which allows further manipulation of the document before saving it.

    PDFont font = PDType1Font.COURIER_OBLIQUE;
    PDDocument originalDoc = PDDocument.load(new File("...inputfile.pdf"));
    PDPage page1 = originalDoc.getPage(0);
    PDPageContentStream contentStream = new PDPageContentStream(originalDoc, page1, true, true, true);
    contentStream.setFont(font, 50);
    contentStream.setNonStrokingColor(0);
    contentStream.beginText();
    contentStream.moveTextPositionByAmount(200, 200);
    contentStream.drawString("deprecated");  // deprecated. Use showText(String text)
    contentStream.endText();
    contentStream.close();
    originalDoc.save("....result2.pdf");
    originalDoc.close();