iText - PDFAppearence issue

后端 未结 1 1197
予麋鹿
予麋鹿 2020-12-22 02:42

We\'re using iText to put a text inside a signature placeholder in a PDF. We use a code snippet similar to this to define the Signature Appearence

PdfStamper         


        
相关标签:
1条回答
  • 2020-12-22 03:09

    As @JJ. already commented,

    TOP_SECTION is connected with acro6layers rendering and the code [determining the datarect in pure DESCRIPTION mode] does not take into account the value of the acro6layer flag.

    Unless one wants to fix this in the iText 5 code itself, the easiest way to make one's description use the whole signature space is to construct the layer 2 appearance oneself.

    To do so one merely has to retrieve a PdfTemplate from PdfSignatureAppearance.getLayer(2) and fill it as desired after one has called PdfSignatureAppearance.setVisibleSignature. The PdfSignatureAppearance remembers that you already have retrieved the layer 2 and doesn't change it anymore.

    For the case at hand we essentially copy the PdfSignatureAppearance.getAppearance code for generating layer 2 in pure DESCRIPTION mode, merely correcting the code determining the datarect:

    PdfSignatureAppearance appearance = ...;
    [...]
    appearance.setVisibleSignature(new Rectangle(36, 748, 144, 780), 1, "sig");
    
    PdfTemplate layer2 = appearance.getLayer(2);
    String text = "We're using iText to put a text inside a signature placeholder in a PDF. "
            + "We use a code snippet similar to this to define the Signature Appearence.\n"
            + "Everything works fine, but the signature text does not fill all the signature "
            + "placeholder area as expected by us, but the area filled seems to have an height "
            + "that is approximately the 70% of the available space.\n"
            + "As a result, sometimes especially if the length of the signature text is quite "
            + "big, the signature text does not fit in the placeholder and the text is striped "
            + "away.";
    Font font = new Font();
    float size = font.getSize();
    final float MARGIN = 2;
    Rectangle dataRect = new Rectangle(
            MARGIN,
            MARGIN,
            appearance.getRect().getWidth() - MARGIN,
            appearance.getRect().getHeight() - MARGIN);
    if (size <= 0) {
        Rectangle sr = new Rectangle(dataRect.getWidth(), dataRect.getHeight());
        size = ColumnText.fitText(font, text, sr, 12, appearance.getRunDirection());
    }
    ColumnText ct = new ColumnText(layer2);
    ct.setRunDirection(appearance.getRunDirection());
    ct.setSimpleColumn(new Phrase(text, font), dataRect.getLeft(), dataRect.getBottom(), dataRect.getRight(), dataRect.getTop(), size, Element.ALIGN_LEFT);
    ct.go();
    

    (CreateSignature.java test signWithCustomLayer2)

    (As description text I used some paragraphs from the question body.)

    The result:

    By adapting the MARGIN value in the code above, one can even use more are. As that can result in the text touching the border, though, that might not be really beautiful.


    As an aside:

    if the length of the signature text is quite big, the signature text does not fit in the placeholder and the text is striped away.

    If you initialize the size variable above with a non-positive value, the code in the if (size <= 0) block will calculate a font size which allows all of the text to fit into the signature rectangle. This does happen in the code above as new Font() returns a font with a size of UNDEFINED which is a constant -1.

    0 讨论(0)
提交回复
热议问题