iText - PDFAppearence问题 [英] iText - PDFAppearence issue

查看:199
本文介绍了iText - PDFAppearence问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们正在使用iText将文本放入PDF中的签名占位符中。我们使用类似于此的代码片段来定义签名外观

  PdfStamper stp = PdfStamper.createSignature(inputReader,os,'\\ \\ 0',tempFile2,true); 
sap = stp.getSignatureAppearance();
sap.setVisibleSignature(占位符);
sap.setRenderingMode(PdfSignatureAppearance.RenderingMode.DESCRIPTION);
sap.setCertificationLevel(PdfSignatureAppearance.NOT_CERTIFIED);

日历cal = Calendar.getInstance();
sap.setSignDate(cal);
sap.setLayer2Text(text +\ n+ cal.getTime()。toString());
sap.setReason(text +\ n+ cal.getTime()。toString()); `

一切正常,但签名文本没有按照我们的预期填充所有签名占位符区域,但填充区域的高度似乎大约是可用空间的70%。



因此,有时特别是如果签名文本的长度是相当大,签名文本不适合占位符,文本被条纹化。



填充签名示例:





我查看了PdfSignatureAppearence类,我在getApperance()方法中找到了这段代码片段负责此行为,并在

  sap.setRenderingMode(PdfSignatureAppearance.RenderingMode.DESCRIPTION)时调用; 

正在调用

  else {
dataRect = new Rectangle(
MARGIN,
MARGIN,
rect.getWidth() - MARGIN,
rect.getHeight() *(1 - TOP_SECTION) - MARGIN);
}

我没理由这个,因为我希望文本可以使用所有可用的占位符高度,具有适当的边距。



有没有办法绕过这种行为?



我们正在使用iText 5.4.2,但也更新版本包含相同的代码片段,所以我希望行为是相同的。

解决方案

作为@JJ。已经评论过,


TOP_SECTION与 acro6layers 连接和代码[确定纯$ DESCRIPTION 模式中的 datarect 未考虑 acro6layer的值 flag。


除非有人想在iText 5代码中解决这个问题,否则最简单的方法是制作一个描述使用整个签名空间就是自己构造第2层外观。



要做到这一点,只需要检索 PdfTemplate PdfSignatureAppearance.getLayer(2)并在调用 PdfSignatureAppearance.setVisibleSignature 之后根据需要填写。 PdfSignatureAppearance 会记住您已经检索到第2层并且不再更改它。



对于此案例我们基本上复制 PdfSignatureAppearance.getAppearance 代码,用于在纯描述模式下生成第2层,只是更正确定 datarect的代码

  PdfSignatureAppearance appearance = ...; 
[...]
appearance.setVisibleSignature(new Rectangle(36,748,144,780),1,sig);

PdfTemplate layer2 = appearance.getLayer(2);
String text =我们使用iText将文本放入PDF中的签名占位符。
+我们使用类似于此的代码片段来定义签名外观。\\ n
+一切正常,但签名文本没有填写我们预期的所有签名
+占位符区域,但填充的区域似乎有一个高度
+这大约是可用空间的70%。\ n
+因此,有时特别是如果签名文本的长度非常
+大,则签名文本不会适合占位符,文本条纹为
+。;
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();



通过调整上面代码中的 MARGIN 值,甚至可以使用更多的值。因为这可能导致文本触摸边框,但可能不是很漂亮。






暂且不说:


如果签名文本的长度很大,签名文本不适合占位符,文本会被条带化。 / p>

如果使用非正值初始化上面的 size 变量, 中的代码if(size< = 0)块将计算允许所有文本适合签名矩形的字体大小。这确实发生在上面的代码中,因为 new Font()返回一个大小为 UNDEFINED 的字体,这是一个常量 -1


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 stp = PdfStamper.createSignature(inputReader, os, '\0', tempFile2, true);
sap = stp.getSignatureAppearance();
sap.setVisibleSignature(placeholder);           
sap.setRenderingMode(PdfSignatureAppearance.RenderingMode.DESCRIPTION);
sap.setCertificationLevel(PdfSignatureAppearance.NOT_CERTIFIED);

Calendar cal = Calendar.getInstance();
sap.setSignDate(cal);
sap.setLayer2Text(text+"\n"+cal.getTime().toString());
sap.setReason(text+"\n"+cal.getTime().toString());      `

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.

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.

Example of filled Signature:

I looked into the PdfSignatureAppearence class and I found this code snippet in the getApperance() method that is responsible of this behaviour and is invoked when

sap.setRenderingMode(PdfSignatureAppearance.RenderingMode.DESCRIPTION);

is being called

      else {
            dataRect = new Rectangle(
                    MARGIN,
                    MARGIN,
                    rect.getWidth() - MARGIN,
                    rect.getHeight() * (1 - TOP_SECTION) - MARGIN);
      }

I don't get the reason for that, because I expect that the text could use all the available placeholder height, with the proper margin.

Is there any way to bypass this behaviour?

We are using iText 5.4.2, but also newer version contains same code snippet so I expect that the behaviour will be same.

解决方案

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.

这篇关于iText - PDFAppearence问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆