使用 PDFBox 2.x 在 PDF 上放置一个按钮

我希望有人可以帮助我解决使用 PdfBox 2.x 创建的 PDF 上的按钮和文本字段问题。

我试图在我的页面上放置一个按钮,它使用 Javascript 函数在文本字段中设置日期。这很好用。

然后我尝试将文本字段和按钮放在一个多页的文档中,以便文本字段和按钮出现在每个页面上,但是这样,页面上的按钮只将日期写入文本字段按钮所在的页面,我点击了。

从那时起我收到了问题,即第一页上的按钮对第一页上的文本字段作出反应,但第一页是按钮作出反应的唯一页面。

然后我保存了 4 个文档,每个文档一页,每个文档都运行良好。但是当最后我将 4 个文档合并为一个有 4 页的文档时,我遇到了与以前相同的问题。

有人可以告诉我,这里有什么问题吗?


缥缈止盈
浏览 247回答 1
1回答

繁星coding

第二种解决方案(合并)不起作用,因为 PDFBox 无法更改 JS 代码。我试图重新创建第一个解决方案(您没有显示),恕我直言,一个问题是 OpenAction 中只有 1 个日期函数。你需要 JavaScript 名称树中的每个函数(你甚至可以在没有所有函数的情况下工作,但我没有测试):public static void main(String[] args) throws IOException{&nbsp; &nbsp; String dest = "SO52807807.pdf";&nbsp; &nbsp; Map<String, PDActionJavaScript> map = new HashMap<>();&nbsp; &nbsp; DecimalFormat DFMM = new DecimalFormat("00");&nbsp; &nbsp; try (PDDocument doc = new PDDocument())&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; PDDocumentNameDictionary documentNameDictionary = new PDDocumentNameDictionary(doc.getDocumentCatalog());&nbsp; &nbsp; &nbsp; &nbsp; PDJavascriptNameTreeNode javascriptNameTreeNode = new PDJavascriptNameTreeNode();&nbsp; &nbsp; &nbsp; &nbsp; documentNameDictionary.setJavascript(javascriptNameTreeNode);&nbsp; &nbsp; &nbsp; &nbsp; COSDictionary acroFormDict = new COSDictionary();&nbsp; &nbsp; &nbsp; &nbsp; acroFormDict&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .setBoolean(COSName.getPDFName("NeedAppearances"), true);&nbsp; &nbsp; &nbsp; &nbsp; acroFormDict.setItem(COSName.FIELDS, new COSArray());&nbsp; &nbsp; &nbsp; &nbsp; PDAcroForm acroForm = new PDAcroForm(doc, acroFormDict);&nbsp; &nbsp; &nbsp; &nbsp; doc.getDocumentCatalog().setAcroForm(acroForm);&nbsp; &nbsp; &nbsp; &nbsp; for (int i = 0; i < 4; i++)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PDPage page = new PDPage();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; doc.addPage(page);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PDAnnotationAdditionalActions buttonAction1 = null;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PDActionJavaScript javascript = null;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PDActionJavaScript tfJs = null;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; String iStr = DFMM.format(i);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PDFont font = PDType1Font.HELVETICA;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PDResources resources = new PDResources();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; resources.put(COSName.getPDFName("Helv"), font);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; acroForm.setDefaultResources(resources);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PDAppearanceStream pdAppearanceStream = new PDAppearanceStream(doc);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pdAppearanceStream.setResources(resources);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PDTextField textField = new PDTextField(acroForm);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; textField.setPartialName("SampleField-" + iStr);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; String defaultAppearance = "/Helv 24 Tf 0 0 0 rg";&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; textField.setDefaultAppearance(defaultAppearance);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; textField.setMultiline(true);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; acroForm.getFields().add(textField);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PDAnnotationWidget fieldwidget = textField.getWidgets().get(0);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PDRectangle rect = new PDRectangle(50, 600, 300, 70);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fieldwidget.setRectangle(rect);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fieldwidget.setPage(page);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; textField.setValue("Click to get Date");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PDAppearanceCharacteristicsDictionary fieldAppearance = new PDAppearanceCharacteristicsDictionary(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; new COSDictionary());&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fieldAppearance.setBorderColour(new PDColor(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; new float[]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 0, 0, 0&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }, PDDeviceRGB.INSTANCE));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fieldAppearance.setBackground(new PDColor(new float[]&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1, 1, 1&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; },&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PDDeviceRGB.INSTANCE));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fieldwidget.setAppearanceCharacteristics(fieldAppearance);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fieldwidget.setPrinted(true);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; page.getAnnotations().add(fieldwidget);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; COSDictionary cosDict1 = new COSDictionary();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; COSArray buttonRect1 = new COSArray();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; buttonRect1.add(new COSFloat(50));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; buttonRect1.add(new COSFloat(575));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; buttonRect1.add(new COSFloat(150));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; buttonRect1.add(new COSFloat(550));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cosDict1.setItem(COSName.RECT, buttonRect1);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cosDict1.setItem(COSName.FT, COSName.getPDFName("Btn")); // Field&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // Type&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cosDict1.setItem(COSName.TYPE, COSName.ANNOT);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cosDict1.setItem(COSName.SUBTYPE, COSName.getPDFName("Widget"));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cosDict1.setItem(COSName.T, new COSString("Datum anzeigen"));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; cosDict1.setItem(COSName.DA,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; new COSString("/F0 6 Tf 0 g 1 1 1 rg "));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PDPushButton button1 = new PDPushButton(acroForm);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; javascript = new PDActionJavaScript("function date" + iStr&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; + "() {var fld" + iStr + " = this.getField('SampleField-"&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; + iStr + "'); fld" + iStr&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; + ".value = util.printd('dd mmmm yyyy',new Date());}");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //doc.getDocumentCatalog().setOpenAction(javascript);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; map.put("date" + iStr, javascript);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; tfJs = new PDActionJavaScript("date" + iStr + "();");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; buttonAction1 = new PDAnnotationAdditionalActions();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; buttonAction1.setU(tfJs);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; button1.getWidgets().get(0).setActions(buttonAction1);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; button1.getCOSObject().addAll(cosDict1);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; acroForm.getFields().add(button1);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PDAnnotationWidget buttonWidget1 = button1.getWidgets().get(0);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PDAppearanceCharacteristicsDictionary buttonFieldAppearance = new PDAppearanceCharacteristicsDictionary(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; new COSDictionary());&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; COSArray borderColorArray = new COSArray();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; borderColorArray.add(new COSFloat((float) (141f / 255f)));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; borderColorArray.add(new COSFloat((float) (179f / 255f)));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; borderColorArray.add(new COSFloat((float) (226f / 255f)));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; PDColor blue = new PDColor(borderColorArray, PDDeviceRGB.INSTANCE);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; buttonFieldAppearance.setBorderColour(blue);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; buttonFieldAppearance.setBackground(blue);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; buttonFieldAppearance.setNormalCaption("Felder löschen");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; buttonWidget1.setAppearanceCharacteristics(buttonFieldAppearance);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; page.getAnnotations().add(buttonWidget1);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; javascriptNameTreeNode.setNames(map);&nbsp; &nbsp; &nbsp; &nbsp; doc.getDocumentCatalog().setNames(documentNameDictionary);&nbsp; &nbsp; &nbsp; &nbsp; File file = new File(dest);&nbsp; &nbsp; &nbsp; &nbsp; file.getParentFile().mkdirs();&nbsp; &nbsp; &nbsp; &nbsp; doc.save(dest);&nbsp; &nbsp; }}2018 年 10 月 20 日更新:我对代码进行了另外两项更改:1) 中的字体名称defaultAppearance必须与默认资源(“Helv”)中的字体名称相同。2)必须在分配小部件之后而不是之前设置字段的值。(如果您考虑一下,这是有道理的 - 小部件是关于视觉的)。不这样做可能意味着在使用非 Adobe 查看器进行显示时会出现问题。更新:25.5.2019:恕我直言,代码有点笨拙,因为不必设置大多数字典元素。可以在此答案中找到创建按钮的更好版本。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java