Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding Header to existing PDF File using PDFBox

Tags:

java

pdf

pdfbox

I am trying to add a Header to an existing PDF file. It works but the table header in the existing PDF are messed up by the change in the font. If I remove setting the font then the header doesn't show up. Here is my code:

    // the document
    PDDocument doc = null;
    try
    {
        doc = PDDocument.load( file );

        List allPages = doc.getDocumentCatalog().getAllPages();
        //PDFont font = PDType1Font.HELVETICA_BOLD;

        for( int i=0; i<allPages.size(); i++ )
        {
            PDPage page = (PDPage)allPages.get( i );
            PDRectangle pageSize = page.findMediaBox();
            PDPageContentStream contentStream = new PDPageContentStream(doc, page, true, true,true);
            PDFont font = PDType1Font.TIMES_ROMAN;
            float fontSize = 15.0f;
            contentStream.beginText();
            // set font and font size
            contentStream.setFont( font, fontSize);
            contentStream.moveTextPositionByAmount(700, 1150);
            contentStream.drawString( message);
            contentStream.endText();

            //contentStream.
            contentStream.close();}

        doc.save( outfile );
    }
    finally
    {
        if( doc != null )
        {
            doc.close();
        }
    }
}`
like image 971
Anita Kulkarni Avatar asked Dec 06 '25 20:12

Anita Kulkarni


1 Answers

Essentially you are running into a PDFBox bug in the current version 1.8.2.

A workaround:

Add a getFonts call of the page resources after creating the new content stream before using a font:

PDPage page = (PDPage)allPages.get( i );
PDRectangle pageSize = page.findMediaBox();
PDPageContentStream contentStream = new PDPageContentStream(doc, page, true, true,true);
page.getResources().getFonts();  // <<<<<<<<
PDFont font = PDType1Font.TIMES_ROMAN;
float fontSize = 15.0f;
contentStream.beginText();

The bug itself:

The bug is in the method PDResources.addFont which is called from PDPageContentStream.setFont:

public String addFont(PDFont font) 
{
    return addFont(font, MapUtil.getNextUniqueKey( fonts, "F" ));
}

It uses the current content of the fonts member variable to determine a unique name for the new font resource on the page at hand. Unfortunately this member variable still can be (and in your case is) uninitialized at this time. This results in the MapUtil.getNextUniqueKey( fonts, "F" ) call to always return F0.

The font variable then is initialized implicitly during the addFont(PDFont, String) call later.

Thus, if unfortunately there already existed a font named F0 on that page, it is replaced by the new font.

Having tested with your PDF this is exactly what happens in your case. As the existing font F0 uses some custom encoding while your replacement font uses a standard one, the text originally written using F0 now looks like gibberish.

The work-around mentioned above implicitly initializes that member variable and, thus, prevents the font replacement.

If you plan to use PDFBox in production for this task, you might want to report the bug.

PS: As mentioned in the comments above there is another bug to observe in context with inherited resources. It should be brought to the PDFBox development's attention, too.

PPS: The issue at hand meanwhile has been fixed in PDFBox for versions 1.8.3 and 2.0.0, cf. PDFBOX-1753.

like image 51
mkl Avatar answered Dec 09 '25 20:12

mkl



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!