为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

缥缈止盈 2021-11-17 16:56:35
我希望有人可以帮助我解决使用 PdfBox 2.x 创建的 PDF 上的按钮和文本字段问题。我试图在我的页面上放置一个按钮,它使用 Javascript 函数在文本字段中设置日期。这很好用。然后我尝试将文本字段和按钮放在一个多页的文档中,以便文本字段和按钮出现在每个页面上,但是这样,页面上的按钮只将日期写入文本字段按钮所在的页面,我点击了。从那时起我收到了问题,即第一页上的按钮对第一页上的文本字段作出反应,但第一页是按钮作出反应的唯一页面。然后我保存了 4 个文档,每个文档一页,每个文档都运行良好。但是当最后我将 4 个文档合并为一个有 4 页的文档时,我遇到了与以前相同的问题。有人可以告诉我,这里有什么问题吗?
查看完整描述

1 回答

?
繁星coding

TA贡献1797条经验 获得超4个赞

第二种解决方案(合并)不起作用,因为 PDFBox 无法更改 JS 代码。我试图重新创建第一个解决方案(您没有显示),恕我直言,一个问题是 OpenAction 中只有 1 个日期函数。你需要 JavaScript 名称树中的每个函数(你甚至可以在没有所有函数的情况下工作,但我没有测试):


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

{

    String dest = "SO52807807.pdf";


    Map<String, PDActionJavaScript> map = new HashMap<>();

    DecimalFormat DFMM = new DecimalFormat("00");


    try (PDDocument doc = new PDDocument())

    {

        PDDocumentNameDictionary documentNameDictionary = new PDDocumentNameDictionary(doc.getDocumentCatalog());

        PDJavascriptNameTreeNode javascriptNameTreeNode = new PDJavascriptNameTreeNode();

        documentNameDictionary.setJavascript(javascriptNameTreeNode);


        COSDictionary acroFormDict = new COSDictionary();

        acroFormDict

                .setBoolean(COSName.getPDFName("NeedAppearances"), true);

        acroFormDict.setItem(COSName.FIELDS, new COSArray());


        PDAcroForm acroForm = new PDAcroForm(doc, acroFormDict);

        doc.getDocumentCatalog().setAcroForm(acroForm);


        for (int i = 0; i < 4; i++)

        {

            PDPage page = new PDPage();

            doc.addPage(page);


            PDAnnotationAdditionalActions buttonAction1 = null;

            PDActionJavaScript javascript = null;

            PDActionJavaScript tfJs = null;


            String iStr = DFMM.format(i);


            PDFont font = PDType1Font.HELVETICA;

            PDResources resources = new PDResources();

            resources.put(COSName.getPDFName("Helv"), font);

            acroForm.setDefaultResources(resources);


            PDAppearanceStream pdAppearanceStream = new PDAppearanceStream(doc);

            pdAppearanceStream.setResources(resources);


            PDTextField textField = new PDTextField(acroForm);

            textField.setPartialName("SampleField-" + iStr);


            String defaultAppearance = "/Helv 24 Tf 0 0 0 rg";

            textField.setDefaultAppearance(defaultAppearance);


            textField.setMultiline(true);


            acroForm.getFields().add(textField);


            PDAnnotationWidget fieldwidget = textField.getWidgets().get(0);

            PDRectangle rect = new PDRectangle(50, 600, 300, 70);

            fieldwidget.setRectangle(rect);

            fieldwidget.setPage(page);


            textField.setValue("Click to get Date");


            PDAppearanceCharacteristicsDictionary fieldAppearance = new PDAppearanceCharacteristicsDictionary(

                    new COSDictionary());

            fieldAppearance.setBorderColour(new PDColor(

                    new float[]

                    {

                        0, 0, 0

                    }, PDDeviceRGB.INSTANCE));

            fieldAppearance.setBackground(new PDColor(new float[]

            {

                1, 1, 1

            },

                    PDDeviceRGB.INSTANCE));

            fieldwidget.setAppearanceCharacteristics(fieldAppearance);


            fieldwidget.setPrinted(true);


            page.getAnnotations().add(fieldwidget);


            COSDictionary cosDict1 = new COSDictionary();

            COSArray buttonRect1 = new COSArray();

            buttonRect1.add(new COSFloat(50));

            buttonRect1.add(new COSFloat(575));

            buttonRect1.add(new COSFloat(150));

            buttonRect1.add(new COSFloat(550));


            cosDict1.setItem(COSName.RECT, buttonRect1);

            cosDict1.setItem(COSName.FT, COSName.getPDFName("Btn")); // Field

            // Type

            cosDict1.setItem(COSName.TYPE, COSName.ANNOT);

            cosDict1.setItem(COSName.SUBTYPE, COSName.getPDFName("Widget"));

            cosDict1.setItem(COSName.T, new COSString("Datum anzeigen"));

            cosDict1.setItem(COSName.DA,

                    new COSString("/F0 6 Tf 0 g 1 1 1 rg "));


            PDPushButton button1 = new PDPushButton(acroForm);

            javascript = new PDActionJavaScript("function date" + iStr

                    + "() {var fld" + iStr + " = this.getField('SampleField-"

                    + iStr + "'); fld" + iStr

                    + ".value = util.printd('dd mmmm yyyy',new Date());}");


            //doc.getDocumentCatalog().setOpenAction(javascript);

            map.put("date" + iStr, javascript);


            tfJs = new PDActionJavaScript("date" + iStr + "();");

            buttonAction1 = new PDAnnotationAdditionalActions();


            buttonAction1.setU(tfJs);

            button1.getWidgets().get(0).setActions(buttonAction1);


            button1.getCOSObject().addAll(cosDict1);

            acroForm.getFields().add(button1);


            PDAnnotationWidget buttonWidget1 = button1.getWidgets().get(0);


            PDAppearanceCharacteristicsDictionary buttonFieldAppearance = new PDAppearanceCharacteristicsDictionary(

                    new COSDictionary());

            COSArray borderColorArray = new COSArray();

            borderColorArray.add(new COSFloat((float) (141f / 255f)));

            borderColorArray.add(new COSFloat((float) (179f / 255f)));

            borderColorArray.add(new COSFloat((float) (226f / 255f)));

            PDColor blue = new PDColor(borderColorArray, PDDeviceRGB.INSTANCE);

            buttonFieldAppearance.setBorderColour(blue);

            buttonFieldAppearance.setBackground(blue);

            buttonFieldAppearance.setNormalCaption("Felder löschen");


            buttonWidget1.setAppearanceCharacteristics(buttonFieldAppearance);

            page.getAnnotations().add(buttonWidget1);


        }

        javascriptNameTreeNode.setNames(map);

        doc.getDocumentCatalog().setNames(documentNameDictionary);

        File file = new File(dest);

        file.getParentFile().mkdirs();

        doc.save(dest);

    }

}

2018 年 10 月 20 日更新:我对代码进行了另外两项更改:1) 中的字体名称defaultAppearance必须与默认资源(“Helv”)中的字体名称相同。2)必须在分配小部件之后而不是之前设置字段的值。(如果您考虑一下,这是有道理的 - 小部件是关于视觉的)。不这样做可能意味着在使用非 Adobe 查看器进行显示时会出现问题。


更新:25.5.2019:恕我直言,代码有点笨拙,因为不必设置大多数字典元素。可以在此答案中找到创建按钮的更好版本。


查看完整回答
反对 回复 2021-11-17
  • 1 回答
  • 0 关注
  • 246 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信