保存的文本字段值在使用 PDFBOX 生成的 PDF 中无法正确显示

2023-12-14

import java.io.IOException;

import javax.swing.text.BadLocationException;

import org.apache.pdfbox.cos.COSArray;
import org.apache.pdfbox.cos.COSDictionary;
import org.apache.pdfbox.cos.COSFloat;
import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.cos.COSString;
import org.apache.pdfbox.exceptions.COSVisitorException;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.interactive.action.PDAnnotationAdditionalActions;
import org.apache.pdfbox.pdmodel.interactive.action.type.PDActionJavaScript;
import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
import org.apache.pdfbox.pdmodel.interactive.form.PDTextbox;
import org.junit.Test;

public class TestPDTextbox {
    @Test
    public void Sample1 () throws IOException, COSVisitorException, BadLocationException {


        PDDocument doc = new PDDocument();
        PDPage page = new PDPage();
        doc.addPage(page);   

        COSDictionary acroFormDict = new COSDictionary(); 
//        acroFormDict.setBoolean(COSName.getPDFName("NeedAppearances"), true);
        acroFormDict.setItem(COSName.getPDFName("Fields"), new COSArray());

        PDAcroForm acroForm = new PDAcroForm(doc, acroFormDict);
        doc.getDocumentCatalog().setAcroForm(acroForm);

        COSDictionary cosDict1 = new COSDictionary();
        COSArray rect1 = new COSArray();
        rect1.add(new COSFloat(100));
        rect1.add(new COSFloat(700));
        rect1.add(new COSFloat(200));
        rect1.add(new COSFloat(750));

        cosDict1.setItem(COSName.RECT, rect1);
        cosDict1.setItem(COSName.FT, COSName.getPDFName("Tx")); // Field Type
        cosDict1.setItem(COSName.TYPE, COSName.ANNOT);
        cosDict1.setItem(COSName.SUBTYPE, COSName.getPDFName("Widget"));
        cosDict1.setItem(COSName.T, new COSString("tx1"));
        cosDict1.setItem(COSName.DA, new COSString("/Helv 7 Tf 0 g"));
        cosDict1.setItem(COSName.V, new COSString("Test Value1"));

        PDTextbox textbox = new PDTextbox(doc.getDocumentCatalog().getAcroForm(), cosDict1);

//      textbox.setValue("Test Value");

        page.getAnnotations().add(textbox.getWidget());
        acroForm.getFields().add(textbox);

         doc.save("C:\\PDF\\SampleTextbox.pdf");
         doc.close();
    }
}

Issue#1我创建了一个文本字段,如上面的代码所示,并尝试使用 textbox.setValue("Test Value"); 设置值。方法,但它给出错误,如下所示:

java.io.IOException: Error: Don't know how to calculate the position for non-simple fonts
    at org.apache.pdfbox.pdmodel.interactive.form.PDAppearance.getTextPosition(PDAppearance.java:1037)
    at org.apache.pdfbox.pdmodel.interactive.form.PDAppearance.insertGeneratedAppearance(PDAppearance.java:558)
    at org.apache.pdfbox.pdmodel.interactive.form.PDAppearance.setAppearanceValue(PDAppearance.java:338)
    at org.apache.pdfbox.pdmodel.interactive.form.PDVariableText.setValue(PDVariableText.java:131)
    at sample.pdfbox.example.TestPDTextbox.Sample1(TestPDTextbox.java:54)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)

Issue#2

为了解决问题#1,如果我使用 cosDictionary 属性设置 textBox 的值 即 cosDict1.setItem(COSName.V, new COSString("测试值1"));

然后在 Adob​​e Reader 中,textBox 的值未正确填充。 我必须单击文本框,然后只显示值,一旦我移出该字段,值就会再次变得不可见。

Issue#3

为了解决问题 2,我需要将 needAppearances 标志设置为 true,如下所示,然后该字段值会在 PDF 中正确显示。但在这个解决方案之后,一旦用户更改字段值,我就无法提取/解析 PDF 字段,并且我们再次解析此 PDF。

Note:-Adobe Reader 中存在此问题,在打开 PDF 时,它也会给出一些消息,例如修复表单字段。一旦我保存 PDF 并尝试解析 acroform 字段,发现所有字段都已重置或为空。无法提取任何字段名称或字段值。

因此使用 acroFormDict.setBoolean(COSName.getPDFName("NeedAppearances"), true);在代码中似乎存在风险,并且它会在 PDF 解析中产生其他问题,因此无法使用。

COSDictionary acroFormDict = new COSDictionary(); 
        acroFormDict.setBoolean(COSName.getPDFName("NeedAppearances"), true);
        acroFormDict.setItem(COSName.getPDFName("Fields"), new COSArray());

        PDAcroForm acroForm = new PDAcroForm(doc, acroFormDict);
        doc.getDocumentCatalog().setAcroForm(acroForm);

我认为,我需要为文本字段设置 PDAppearanceDictionary,但我不知道该怎么做,也不知道是否需要为每个字段或在 acroform 级别设置。

请帮我解决这个问题我应该如何解决。 我正在使用 PDFBOX 版本 1.8.10。


在上面的问题中,我通过将页面资源添加到 acroform 并使用正确的文本默认外观字符串来修复问题#1。现在我不需要将 needAppearance 标志设置为 true。

        PDFont font = PDType1Font.HELVETICA;
        PDResources res = new PDResources();
        String fontName = res.addFont(font);
        String defaultAppearance = "/"+fontName+" 7 Tf 0 g";

        COSDictionary acroFormDict = new COSDictionary(); 
        acroFormDict.setBoolean(COSName.getPDFName("NeedAppearances"), false);
        acroFormDict.setItem(COSName.getPDFName("Fields"), new COSArray());
        acroFormDict.setItem(COSName.DA, new COSString(defaultAppearance));

        PDAcroForm acroForm = new PDAcroForm(doc, acroFormDict);
        acroForm.setDefaultResources(res);

检查下面完整的更正代码:

import java.io.IOException;

import javax.swing.text.BadLocationException;

import org.apache.pdfbox.cos.COSArray;
import org.apache.pdfbox.cos.COSDictionary;
import org.apache.pdfbox.cos.COSFloat;
import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.cos.COSString;
import org.apache.pdfbox.exceptions.COSVisitorException;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDResources;
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.apache.pdfbox.pdmodel.font.PDType1Font;
import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
import org.apache.pdfbox.pdmodel.interactive.form.PDTextbox;
import org.junit.Test;

public class TestPDTextbox {
    @Test
    public void Sample1 () throws IOException, COSVisitorException, BadLocationException {


        PDDocument doc = new PDDocument();
        PDPage page = new PDPage();
        doc.addPage(page);   

        PDFont font = PDType1Font.HELVETICA;
        PDResources res = new PDResources();
        String fontName = res.addFont(font);
        String defaultAppearance = "/"+fontName+" 7 Tf 0 g";

        COSDictionary acroFormDict = new COSDictionary(); 
        acroFormDict.setBoolean(COSName.getPDFName("NeedAppearances"), false);
        acroFormDict.setItem(COSName.getPDFName("Fields"), new COSArray());
        acroFormDict.setItem(COSName.DA, new COSString(defaultAppearance));

        PDAcroForm acroForm = new PDAcroForm(doc, acroFormDict);
        acroForm.setDefaultResources(res);

        doc.getDocumentCatalog().setAcroForm(acroForm);

        COSDictionary cosDict1 = new COSDictionary();
        COSArray rect1 = new COSArray();
        rect1.add(new COSFloat(100));
        rect1.add(new COSFloat(700));
        rect1.add(new COSFloat(200));
        rect1.add(new COSFloat(750));

        cosDict1.setItem(COSName.RECT, rect1);
        cosDict1.setItem(COSName.FT, COSName.getPDFName("Tx")); // Field Type
        cosDict1.setItem(COSName.TYPE, COSName.ANNOT);
        cosDict1.setItem(COSName.SUBTYPE, COSName.getPDFName("Widget"));
        cosDict1.setItem(COSName.T, new COSString("tx1"));
        cosDict1.setItem(COSName.DA, new COSString(defaultAppearance));
//        cosDict1.setItem(COSName.V, new COSString("Test Value1"));

        PDTextbox textbox = new PDTextbox(doc.getDocumentCatalog().getAcroForm(), cosDict1);

      textbox.setValue("Test Value");

        page.getAnnotations().add(textbox.getWidget());
        acroForm.getFields().add(textbox);

         doc.save("C:\\PDF\\SampleTextbox.pdf");
         doc.close();
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

保存的文本字段值在使用 PDFBOX 生成的 PDF 中无法正确显示 的相关文章

  • 任务“:app:dexDebug”执行失败

    我目前正在处理我的项目 我决定将我的 Android Studio 更新到新版本 但在我导入项目后 它显示如下错误 Information Gradle tasks app assembleDebug app preBuild UP TO
  • Android - 如何访问 onResume 中 onCreate 中实例化的 View 对象?

    In my onCreate 方法 我正在实例化一个ImageButton View public void onCreate Bundle savedInstanceState super onCreate savedInstanceSt
  • 如何打印整个字符串池?

    我想打印包含文字的整个字符串池String使用添加的对象intern 就在垃圾收集之前 JDK有没有隐式的方法来进行这样的操作 我们如何检查字符串池 EDIT The comment suggests that there may be a
  • java.lang.Class: 在 java 程序中初始化 log4j 属性文件时出错

    我正在尝试使用 log4j 运行独立的 java 程序 但在调试时收到以下消息 控制台上没有 log4j 相关日志 log Logger 1343 java lang Class ERROR in 18b4aac2 有人可以建议这里出了什么
  • 使用 Checkstyle Plugin 时从插件调用代码时出现问题:“org.eclipse.jface”

    我正在尝试在 Rational Software Architect 7 0 0 4 上使用 eclipse cs 插件 我最近卸载了旧的 beta2 版本并安装了 beta3 插件本身按照之前的配置工作 但是每当我尝试通过 Windows
  • JTree 节点不会被直观地选择

    不知何故 我无法为我的 JTree 节点启用 选择突出显示 我正在我的项目中使用自定义单元格渲染器 这很可能导致此问题 这是完整的渲染器类代码 protected class ProfessionTreeCellRenderer exten
  • 如何对 IntStream 进行逆序排序

    我正在使用 txt 文件读取数字BufferedReader 我想颠倒该流中元素的顺序 以便在收集它们时 它们将从最高到最低排列 我不想在构建数组后进行排序 因为我不知道其中可能有多少元素 我只需要最高的 N 个元素 in new Buff
  • 使用 Spring 时实例化对象,用于测试与生产

    使用 Spring 时 应该使用 Spring 配置 xml 来实例化生产对象 并在测试时直接实例化对象 这样的理解是否正确 Eg MyMain java package org world hello import org springf
  • Google Inbox 类似 RecyclerView 项目打开动画

    目前 我正在尝试实现 Google Inbox 例如RecyclerView行为 我对电子邮件打开动画很好奇 我的问题是 该怎么做 我的意思是 他们使用了哪种方法 他们用过吗ItemAnimator dispatchChangeStarti
  • Java:从元素创建 DOM 元素,而不是文档

    如您所知 在 Java 中创建 Dom 元素的正确方法是执行以下操作 import org w3c dom Document import org w3c dom Element Document d Element e e d creat
  • spring - 强制 @Autowired 字段的 cglib 代理

    我有混合堆栈 EJB 和 Spring 为了将 Spring 自动装配到 EJB 我使用SpringBeanAutowiringInterceptor 不确定这是否会影响我遇到的问题 在尝试通过以下方式自动装配 bean 时 Scope p
  • 如何将 XMP XML 块序列化为现有的 JPEG 图像?

    我有许多 JPEG 图像 其中包含损坏的 XMP XML 块 我可以轻松修复这些块 但我不确定如何将 固定 数据写回图像文件 我目前正在使用 JAVA 但我愿意接受任何能让这项任务变得容易的事情 这是目标关于 XMP XML 的另一个问题
  • 所有junit测试后的清理

    在我的项目中 我必须在所有测试之前进行一些存储库设置 这是使用一些棘手的静态规则来完成的 然而 在所有测试之后我不知道如何进行清理 我不想保留一些神奇的静态数字来引用所有测试方法的数量 我应该一直维护它 最受赞赏的方法是添加一些侦听器 该侦
  • 从 Java 日历迁移到 Joda 日期时间

    以前 当我第一次设计股票应用相关软件时 我决定使用java util Date表示股票的日期 时间信息 后来我体会到了大部分方法java util Date已弃用 因此 很快 我重构了所有代码以利用java util Calendar 然而
  • 如何使用 Mockito 和 Junit 模拟 ZonedDateTime

    我需要模拟一个ZonedDateTime ofInstant 方法 我知道SO中有很多建议 但对于我的具体问题 到目前为止我还没有找到任何简单的解决办法 这是我的代码 public ZonedDateTime myMethodToTest
  • 如何为 Jackson 编写一个包罗万象的(反)序列化器

    当您提前知道类型时 编写自定义序列化器非常容易 例如 MyType一个人可以写一个MyTypeSerializer extends StdSerializer
  • 如何在android sdk上使用PowerMock

    我想为我的 android 项目编写一些单元测试和仪器测试 然而 我遇到了一个困扰我一段时间的问题 我需要模拟静态方法并伪造返回值来测试项目 经过一些论坛的调查 唯一的方法是使用PowerMock来模拟静态方法 这是我的 gradle 的一
  • 从一个文本文件中获取数据并将其移动到新的文本文件

    我有一个文件 里面有数据 在我的主要方法中 我读入文件并关闭文件 我调用另一种方法 在原始文件的同一文件夹内创建一个新文件 所以现在我有两个文件 原始文件和通过我调用的方法生成的文件 我需要另一种方法 从原始文件中获取数据并将其写入创建的新
  • MongoDB Java 驱动程序:MongoCore 驱动程序与 MongoDB 驱动程序与 MongoDB 异步驱动程序

    MongoDB Java 驱动程序有三种不同的驱动程序选项 核心驱动 MongoDB 驱动程序 MongoDB 异步驱动程序 The 驱动程序描述页面 https docs mongodb org ecosystem drivers jav
  • java中如何找到class文件的包

    我正在编写一个使用 class 文件的 java 程序 我希望能够读取文件系统上的 class 文件 使用 InputStream 并确定它所在的包 该 class 文件可能不在一个好的包目录结构中 它可能位于某个随机位置 我怎样才能做到这

随机推荐

  • 基于 Leaflet 和 AngularJS 的地图未正确加载

    我的基于 Leaflet 和 AngularJS 的地图无法正确加载 我不知道发生了什么 但地图图块没有按应有的方式布局 这是底图 这是我的代码 function setMapPosition scope center lat 51 505
  • 在shinyApp中使用R text2vec包和LDAvis的LDA主题模型

    以下是使用 R text2vec 包进行 LDA 主题建模的代码 library text2vec tokens docs text gt docs text a colection of text documents word token
  • 对 tsvector 中的每个元素使用 Levenshtein 函数?

    我正在尝试使用 Postgres 创建模糊搜索 并一直使用 django watson 作为基本搜索引擎来工作 我有一个名为 search tsv 的字段 它是一个 tsvector 其中包含我要搜索的模型的所有字段值 我想使用 Leven
  • 在网页中添加“导出到 Excel”按钮,以在 Web 应用程序中将 gridview 导出到 Excel

    我为诊所构建了一个患者管理软件 我需要将患者列表从 ASP net 网格视图导出到 Excel 文件 我的问题是 有没有办法将gridview导出到excel 我正在使用 vb net 和 Visual Web Developer 2010
  • 在 BeautifulSoup 中将一个标签替换为另一个标签

    我试图在 XML 文档中查找标签 并用新标签完全替换它 我认为下面应该有效 para monograph find para text Some text newpara
  • 如何在R中将减号从右移到左/从后到前?

    我已从文本文件导入数据 负数的形式为 100 右侧的减号 我应该将其转换为 100 任何想法 提前致谢 我们可以使用以下方法来做到这一点sub 我们将数字作为一个组来捕获 d 后面跟着一个 在最后 的字符串并替换为 接下来是反向引用 1 的
  • navigator.getusermedia

    我正在研究 html5 新规范 尤其是网络摄像头功能 By 按照本教程 我收到以下错误 Native web camera streaming getUserMedia is not supported in this browser 这是
  • 使用 Python OpenCV 删除图像的黑色标题部分

    我需要使用 Python CV 删除图像多个部分的黑色部分 我尝试过去噪 但没有给出令人满意的结果 例如 我需要删除表标题中的黑色部分 下图 并将标题背景转换为白色 内容为黑色 谁能帮助我选择正确的库或解决方案来克服这个问题 正如您所看到的
  • 在 Jetpack Compose 中创建垂直滑块

    我正在构建一个Android应用程序 需要在同一页面中创建多个垂直滑块用于音乐均衡器调整 但我只能从官方材料设计文档中找到水平滑块 我尝试从官方文档中实现默认滑块并使用修改器旋转它并且它可以工作 但问题是我现在无法使用调整高度Modifie
  • 如何设置 DJANGO_SETTINGS_MODULE 环境变量?

    我正在尝试修复在 django 应用程序中看到的一个不发送邮件的错误 请注意 该应用程序运行良好 只是邮件功能失败了 我尝试收集错误日志 但找不到与发送邮件相关的任何错误 所以 我做了一个例子来尝试强制错误 这是示例 from django
  • Windows 7 64 位上的 eslint-v8 Ruby gem 安装问题

    在 Windows 7 64 位 上设置 Rally App SDK 2 0p 环境时出现问题 我已经从 ruby installer org 安装了 Ruby 1 8 7 p358 并成功安装了 rake Ruby gem 但我安装时遇到
  • 使用 MediaStore 在 Android Q 中创建/复制文件

    我正在尝试找到一种方法 可以处理除媒体文件 图片 视频 音频 之外的任何文件的创建和复制 以便从 Android Q 内部存储中的一个位置复制到另一个位置 在此 我在应用程序文件夹中创建了我的文件我希望将它们移动到下载文件夹或我可以在内部存
  • iTextSharp 中的 PDF 坐标系

    现在我正在使用 iTextSharp 从 PDF 中提取线条和矩形 我使用的方法如下 PdfReader reader new PdfReader strPDFFileName var pageSize reader GetPageSize
  • 如何将 JSP 中的 ResultSet 对象发送回 HTML (JavaScript)?

    我有一个查询 MySQL 数据库的 JSP 页面 我想将 Resultset 对象作为响应对象发送到 HTML 页面 我需要结果集对象来填充表格和图表 如何将 resultSet 对象转换为 javascript 对象 如何将 result
  • 插入数据库问题...(错误字符编码)PHP/MYSQL

    我有一个提交到 mysql 数据库的表单 数据库设置为 UTF 8 GENERAL 并且行也使用相同的字符编码 但是 当我提交文本中带有 或 的表单时 它不会在这些字符之后提交任何内容 例如 这是美好的一天 它只是将其插入数据库 这是美好的
  • C 编程中读/写文本文件

    我需要将一些内容写入txt文件并读取内容 然后将它们打印在屏幕上 下面是我编写的代码 它可以正确创建内容并将内容写入文件 但无法从文件中读取并正确打印 include
  • Internet Explorer 中的 Google 地图 JavaScript API 错误

    我为 Google Maps JavaScript API v3 编写了一个非常简单的 jQuery 插件 它可以在 Firefox Chrome 等 中运行 但不能在 Internet Explorer 8 中运行 我收到的错误是以下行中
  • 从网站按钮运行 Chrome 应用程序

    我需要启动一个镀铬应用从网页按钮点击 我找到了以下资源 从 url 运行 Google Chrome 应用程序 从网页激活 Chrome 应用程序 如何通过 JavaScript 启动 Chrome 打包应用程序 这建议使用可外部连接 an
  • 使用 Pkcs10CertificationRequest 获取主题备用名称

    我目前能够解码 CSR 的值 请求的扩展除外 特别是X509v3 Subject Alternative Name 这是相关部分 我的 DecodeCSR 字符串 csr public void DecodeCsr string csrSt
  • 保存的文本字段值在使用 PDFBOX 生成的 PDF 中无法正确显示

    import java io IOException import javax swing text BadLocationException import org apache pdfbox cos COSArray import org