使用iText计算适合PDF格式文本框的最大字符串长度

时间:2014-11-21 19:19:37

标签: pdf itextsharp itext

我使用 iTextSharp 填充包含表单的 PDF 。这些表单由文本框(以及其他字段类型)组成,如果我在PDF阅读器中打开它,我可以输入任意数量的字符,没有任何限制。但是如果我在字段中输入太多字符时打印这样的PDF表单,则根本不会打印溢出。

现在,我正在寻找一种方法来测量适合某些特定文本框的字符串的最大长度,而不会丢失任何打印数据。我知道理论上需要做什么,我需要考虑文本框的字体属性来测量字符串的宽度(以像素/点为单位),然后将其与文本框的宽度进行比较(减去它可能具有的任何填充) 。但我对PDF概念都不熟悉,我也不知道从哪里开始。有人可以指导我走向正确的方向吗?

还有一件事,我无法控制模板PDF,我无法以任何方式改变它们。我所能做的就是在用户要求提供拼合的PDF文件时,提示用户输入的文字不适合该字段!

[UPDATE]

还有另一个场景,我希望同样的解决方案适用于此,但似乎我需要将此后一个包括在内,以指导正确方向的答案。

我的PDF表单文件中有三个文本框,当我手动填写它们(使用PDF阅读器)时,我有责任将输入分成三个。一个例子是三行地址字段。如果我正在设计表单,我会使用多行文本字段,因此地址自动换行,但不幸的是我只是递给表单,因为它们受密码保护,我所能做的就是找到适当的点拆分输入字符串以在三个字段中输入它们。

1 个答案:

答案 0 :(得分:4)

通过将已经在StackOverflow上回答的不同问题的答案组合在一起,您应该能够解决问题。

第一步:您需要知道定义字段的矩形的大小。我在回答问题Add image to iText dynamically on PDF file

时解释了这一点

在这个答案中,我这样做:

AcroFields form = stamper.getAcroFields();
AcroFields.FieldPosition fieldPosition = form.getFieldPositions(field).get(0);
Rectangle rect = fieldPosition.position;

其中field包含字段的名称,rect描述了一个矩形,您可以从中获取宽度和高度。

第二步:您需要为该字段定义的字体BaseFont实例。 Chris Haas回答了这个问题:iTextSharp Re-use Font Embedded In Acrofield

我已将他的答案移植到Java:ReuseFont

public BaseFont findFontInForm(PdfReader reader, PdfName fontname) {
    PdfDictionary root = reader.getCatalog();
    PdfDictionary acroform = root.getAsDict(PdfName.ACROFORM);
    if (acroform == null) return null;
    PdfDictionary dr = acroform.getAsDict(PdfName.DR);
    if (dr == null) return null;
    PdfDictionary font = dr.getAsDict(PdfName.FONT);
    if (font == null) return null;
    for (PdfName key : font.getKeys()) {
        if (key.equals(fontname)) {
            return BaseFont.createFont((PRIndirectReference)font.getAsIndirectObject(key));
        }
    }
    return null;
}

您必须调整此示例,因为它假设您已经知道字体的名称。在/DR字典中找到该名称应该相当容易。

警告:此字体可能不包含您需要的足够信息。这是最微妙的一步。如果您只是使用Helvetica或更改字体可能会更好。请注意,原始文档是否加密并不重要:如果您可以阅读它,您可以更改您正在填写的文档中的字体(您不需要更改原始模板中的字体;它只会是在结果文件中改变了。)

第三步:现在您已拥有字体和可用宽度,您可以使用此问题的答案来计算绘制特定字符串所需的大小:How to calculate the string width in iText?

  

您可以使用BaseFont.getWidthPoint(String text, float fontSize)来获取pt中字符串的宽度。或者将字符串放入Chunk并执行chunk.getWidthPoint()

三者的结合可以解决你的问题。