【问题标题】:Calculating the maximum string length that fits in a PDF's form textbox using iText [closed]使用 iText 计算适合 PDF 表单文本框的最大字符串长度 [关闭]
【发布时间】:2014-11-21 19:19:37
【问题描述】:

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

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

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

[更新]

我希望同样的解决方案适用于另一种情况,但似乎我需要在以后包含这个情况,以便将答案引导到正确的方向。

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

【问题讨论】:

    标签: pdf itextsharp itext


    【解决方案1】:

    通过结合 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()

    这三者的结合应该可以解决您的问题。

    【讨论】:

    • 非常感谢您的帖子。这也是查找字段字体的正确方法吗? var ft1 = acroFields.GetFieldItem("FillText1"); var dic = ft1.GetMerged(0); TextField tmp = new TextField(null, null, null); acroFields.DecodeGenericDictionary(dic, tmp); BaseFont font = tmp.Font;
    • 顺便说一句,getWidthPoint 需要fontSize。如何检索字段的字体大小?我已经在互联网上上下搜索过,我只能找到如何设置它。从来没有人谈论得到它!
    • 字体大小通常存储在字段字典的/DA(默认外观)中。
    猜你喜欢
    • 1970-01-01
    • 2018-04-02
    • 1970-01-01
    • 2019-03-13
    • 1970-01-01
    • 2012-04-27
    • 1970-01-01
    • 1970-01-01
    • 2015-09-07
    相关资源
    最近更新 更多