当前位置: 首页 > 知识库问答 >
问题:

Apache PDFBox表单填充TrueType文本行间距问题

微生毅
2023-03-14

我在用ApachePDFBox填写PDF表格。我使用的是TrueType字体(不是默认字体),叫做“Impact”,非常标准。在模板中,我有一个名为“Title”的字段,指定了影响字体。我使用下面的代码获取该模板,并用一个包含多个单词的值填充该字段。

问题是,当你查看创建的PDF时,单词之间有很大的空格。如果在Acrobat中打开PDF并单击该字段,文本将发生变化,大间距将消失。以任何方式编辑该字段都将永久性地更正该问题,但我生成的表单不会在事后更改。

我用默认字体做了同样的实验(本例中是Helvetica),但上述问题并不存在。我可以创建一个空白表单,添加一个字段,设置自定义字体并复制问题。

我读到过类似的问题在2.0.0 PDFBOX-2062中得到了解决,但这是为了改变字体大小,而不是定制字体。

我使用的是PDFBox版本2.0.1。

public static void main(String[] args) throws IOException {

    String formTemplate = "/BLANK.pdf";
    String outputPDF = "/FillFormField.pdf";

    // load the documents
    PDDocument pdfDocument = PDDocument.load(new File(formTemplate));

    // get the document catalog
    PDAcroForm acroForm = pdfDocument.getDocumentCatalog().getAcroForm();

    // as there might not be an AcroForm entry a null check is necessary
    if (acroForm != null)
    {
        PDTextField field = (PDTextField) acroForm.getField( "Title" );
        field.setValue("Low Mileage Beauty");
    }

    // Save and close the filled out form.
    pdfDocument.save(outputPDF);
    pdfDocument.close();

}

共有1个答案

孟选
2023-03-14

这个问题是由两个因素造成的:

  • PDFBox在编写文本和
  • 时的一个怪癖
  • 源PDF中的不一致字体对象。

将文本写入内容流时,PDFBox会将每个Unicode代码点转换为名称,并在从倒排字体编码生成的映射中查找该名称。

手头案例中的字体编码是MacRomanEncode。在该编码中(同样在WinAnsiEncode中)有两个到名称空间的映射,参见PDF规范ISO 32000-1的附件D2,表中给出了一个:

          CHAR CODE (OCTAL)
CHAR NAME  STD MAC WIN PDF
...
     space 040 040 040 040
...

脚注6中有一条:

反转字体编码只能有一个名称空间值,碰巧是八进制312(=十进制202)。

由于这两个空间图示符预计在排版上是相同的,这种怪癖应该是无害的。但是:

PDF中的字体影响定义为正常空格图示符的宽度为176,非中断空格图示符的宽度为750。因此,它们在版式上存在巨大差异。

但是,由于PDF中的影响被定义为具有MacRomanEncode(此处没有兴趣的微小变化),因此这两个字形需要(“应”表示要求)在排版上相同,参见脚注。上面引用。

第一个快速选项是@Tilman已经在评论中建议,

设置acroForm。SetNeedAppearancess(true)

这将设置一个标志,指示PDF查看器重新创建外观内容流。不过,这可能不适用于某些预览器。

下一个选项是修复包含不一致字体定义的源PDF。

最终PDFBox可能想要摆脱这种怪癖。虽然在排版上应该不会对绘制的空间变体产生影响,但选择非破坏性变体是一种诱人的命运。

 类似资料:
  • 问题内容: 有什么办法可以通过简单的CSS设置文本格式?我有一个包含不同产品及其药物和剂量的数据库,希望统一显示它们,但没有等宽字体。 问题答案: 这是一款优雅且不失礼貌的产品,但有一些限制(请参阅下文)。 CSS: HTML: 局限性: 在IE <8中不起作用 在属性中仅接受文字字符,不接受HTML实体,因此不接受。(@Radek指出,这没有问题,因为UTF-8字符几乎可以满足这里的所有需求)。

  • 我目前正在使用FPDI在静态pdf文档上打印数字。当我尝试对带有可填充表单的pdf执行相同操作时,FPDI会抛出一个错误: “此文档([pdf path])可能使用了FPDI附带的免费解析器不支持的压缩技术。” 阅读文档FPDI显然无法做到这一点。搜索替代项并没有让我走那么远(我通常会找到预先填充表单字段的方法……但我需要在表单区域之外打印一个数字) 是否有人知道这方面的解决方案(例如替代LIB)

  • 以下文件是我试图向nodejs(Express)服务器提交POST请求的过程。req.body不会从我的表单中填充任何类型的数据。我已经做了很多搜索,发现许多解决这个特殊问题的方法包括在我的路线之前移动身体解析器,并确保在表单字段中包含名称。 应用程序。js 指数玉 指数js(从app.post('/signup',…)调用) 安慰日志

  • 我使用的是带有AppCompatEditText的TextInputLayout,它为AppCompatEditText提供了一个基于xml形状的自定义背景。每当我设置一些错误,错误线从布局的开始。有没有办法给那个错误行做填充。

  • 但还是不行,知道吗?

  • 当我使用这个长字段名时,我没有得到任何错误,但是得到的PDF不包含我放在字段中的值。我想可能字段名有问题,所以我使用了Pdftk工具,它只给出了作为字段名。但是当我仅仅使用它时,我会得到error。救命?