Search code examples
itextitextpdf

How to edit PdfTemplate width (in Java)


Is it possible to edit width of PdfTemplate object before close of document ? In my pdf process I create a document, and set a template for write total page number. I set width but it doesnot works :

// onOpenDocument
PdfTemplate pageNumTemplate = writer.getDirectContent().createTemplate(10, 20);
globalDataMap.put("myTemplate", pageNumTemplate)

// onCloseDocument
Font font = (Font) globalDataMap.get("myFont");
String pagenum = String.valueOf(writer.getPageNumber());

float widthPoint = font.getBaseFont().getWidthPoint(pagenum, font.getSize());
PdfTemplate pdfTemplate = (PdfTemplate) globalDataMap.get("myTemplate");
pdfTemplate.setWidth(widthPoint);
ColumnText.showTextAligned(pdfTemplate, Element.ALIGN_LEFT, new Phrase(pagenum), 0, 1, 0);

Solution

  • An error in the OP's initial code

    You call ColumnText.showTextAligned with a String as third parameter:

    String pagenum = String.valueOf(writer.getPageNumber());
    [...]
    ColumnText.showTextAligned(pdfTemplate, Element.ALIGN_LEFT, pagenum, 0, 1, 0);
    

    But all ColumnText.showTextAligned overloads expect a Phrase there:

    public static void showTextAligned(final PdfContentByte canvas, final int alignment, final Phrase phrase, final float x, final float y, final float rotation)
    
    public static void showTextAligned(final PdfContentByte canvas, int alignment, final Phrase phrase, final float x, final float y, final float rotation, final int runDirection, final int arabicOptions)
    

    (at least up to the current 5.5.9-SNAPSHOT development version).

    Thus, you might want to use

    ColumnText.showTextAligned(pdfTemplate, Element.ALIGN_LEFT, new Phrase(pagenum), 0, 1, 0);
    

    instead.

    But now it works

    Based on the OP's code I built this proof-of-concept:

    try (   FileOutputStream stream = new FileOutputStream(new File(RESULT_FOLDER, "dynamicTemplateWidths.pdf"))    )
    {
        Document document = new Document(PageSize.A6);
        PdfWriter writer = PdfWriter.getInstance(document, stream);
        writer.setPageEvent(new PdfPageEventHelper()
        {
            PdfTemplate dynamicTemplate = null;
            Font font = new Font(BaseFont.createFont(), 12);
            String postfix = "0123456789";
    
            @Override
            public void onOpenDocument(PdfWriter writer, Document document)
            {
                super.onOpenDocument(writer, document);
                dynamicTemplate = writer.getDirectContent().createTemplate(10, 20);
            }
    
            @Override
            public void onEndPage(PdfWriter writer, Document document)
            {
                writer.getDirectContent().addTemplate(dynamicTemplate, 100, 300);
            }
    
            @Override
            public void onCloseDocument(PdfWriter writer, Document document)
            {
                float widthPoint = font.getBaseFont().getWidthPoint(postfix, font.getSize());
                dynamicTemplate.setWidth(widthPoint / 2.0f);
                ColumnText.showTextAligned(dynamicTemplate, Element.ALIGN_LEFT, new Phrase(String.valueOf(writer.getPageNumber()) + "-" + postfix), 0, 1, 0);
            }
    
        });
        document.open();
    
        document.add(new Paragraph("PAGE 1"));
        document.newPage();
        document.add(new Paragraph("PAGE 2"));
    
        document.close();
    }
    

    The output:

    dynamicTemplateWidths.pdf

    Considering I set the template width to half the width of the postfix 0123456789 in onCloseDocument, this is exactly as expected.