PDFBox Avoid Do you want to save changes before closing

痴心易碎 提交于 2020-01-05 05:10:21

问题


I am currently trying to add a button to an existing pdf page that upon clicking the button it closes the current tab. I have achieved that with the following code using PDFbox 2.0.15...

try {

            InputStream pdfInput = new FileInputStream(new File("C:\\Users\\justi\\Desktop\\test\\real.pdf"));
            PDDocument doc = PDDocument.load(pdfInput);
            PDPage page = doc.getPage(0);
//            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());

//            PDDocumentCatalog pdCatalog = doc.getDocumentCatalog();
//            PDAcroForm acroForm = pdCatalog.getAcroForm();

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

            PDActionJavaScript javascript = new PDActionJavaScript("function validate(index){ app.alert(index); }");
            doc.getDocumentCatalog().setOpenAction( javascript );

            COSDictionary cosDict = new COSDictionary();
            PDPushButton button = new PDPushButton(acroForm);
            cosDict = button.getCOSObject();
            COSArray rect = new COSArray();
            rect.add(new COSFloat(100));
            rect.add(new COSFloat(10));
            rect.add(new COSFloat(200));
            rect.add(new COSFloat(60));


            cosDict.setItem(COSName.RECT, rect);
            cosDict.setItem(COSName.FT, COSName.getPDFName("Btn")); // Field Type
            cosDict.setItem(COSName.TYPE, COSName.ANNOT);
            cosDict.setItem(COSName.SUBTYPE, COSName.getPDFName("Widget"));
            cosDict.setItem(COSName.T, new COSString("Btn"+1));
            cosDict.setItem(COSName.V, new COSString("Validate"));
            cosDict.setItem(COSName.DA, new COSString("/Helv 7 Tf 0 g"));
            cosDict.setInt(COSName.FF, 65536);

//            button.setValue("Validate Button");

            PDActionJavaScript tfJs = new PDActionJavaScript("this.closeDoc();");
            PDAnnotationAdditionalActions tfAction = new PDAnnotationAdditionalActions();
            tfAction.setU(tfJs);
            button.getWidget().setActions(tfAction);

            PDColor colourBlack = new PDColor(new float[] { 0, 0, 0 }, PDDeviceRGB.INSTANCE);
            PDAppearanceCharacteristicsDictionary fieldAppearance =
                    new PDAppearanceCharacteristicsDictionary(new COSDictionary());
            fieldAppearance.setBorderColour(colourBlack);
            button.getWidget().setAppearanceCharacteristics(fieldAppearance);

            page.getAnnotations().add(button.getWidget());

            acroForm.getFields().add(button);

            doc.save("C:\\Users\\justi\\Desktop\\test\\test2.pdf");
            doc.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

The main problem I am currently having is that everytime I open the document and click on the button it opens a prompt that says "Do you want to save changes to xyz.pdf before closing? Looking around I found out that setting the "NeedAppearances" to false removes this prompt but then does not show the box to click on. Is there a way to make it show the box but still exit out of the pdf without that prompt?

--Update-- It appears that if you save the document after you open it you can then click the button to close it no problem. Maybe another solution could be to save it correctly after I generate it? Not sure how that would work tho.


回答1:


Removing the /NeedAppearances entry is correct, but you also need to create an appearance, here: a black border. I've also added a text.

    PDAnnotationWidget widget = button.getWidgets().get(0);
    PDAppearanceDictionary appearanceDictionary = new PDAppearanceDictionary();
    PDAppearanceStream appearanceStream = new PDAppearanceStream(doc);
    appearanceStream.setResources(new PDResources());
    try (PDPageContentStream cs = new PDPageContentStream(doc, appearanceStream))
    {
        PDRectangle bbox = new PDRectangle(widget.getRectangle().getWidth(), widget.getRectangle().getHeight());
        appearanceStream.setBBox(bbox);
        cs.setNonStrokingColor(0, 0, 0); // black
        cs.addRect(bbox.getLowerLeftX() + 0.5f, bbox.getLowerLeftY() + 0.5f, bbox.getWidth() - 1, bbox.getHeight() - 1);
        cs.stroke();

        // put some useful text
        cs.setFont(PDType1Font.HELVETICA, 20);
        cs.beginText();
        cs.newLineAtOffset(20, 20);
        cs.showText("Close");
        cs.endText();
    }
    appearanceDictionary.setNormalAppearance(appearanceStream);
    widget.setAppearance(appearanceDictionary);


来源:https://stackoverflow.com/questions/56267694/pdfbox-avoid-do-you-want-to-save-changes-before-closing

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!