PDFBox Avoid Хотите сохранить изменения перед закрытием? - PullRequest
1 голос
/ 23 мая 2019

В настоящее время я пытаюсь добавить кнопку к существующей странице PDF, которая после нажатия кнопки закрывает текущую вкладку. Я добился этого с помощью следующего кода, используя 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();
        }

Основная проблема, с которой я сталкиваюсь в настоящее время, заключается в том, что каждый раз, когда я открываю документ и нажимаю на кнопку, он открывает приглашение «Сохранить изменения в xyz.pdf перед закрытием? Осматривая, я обнаружил, что настройка «NeedAppearances» в false удаляет это приглашение, но затем не отображает окно, на которое нужно щелкнуть. Есть ли способ, чтобы оно показывало окно, но все равно выходило из pdf без этого приглашения?

- Update-- Похоже, что если вы сохраните документ после его открытия, вы можете нажать кнопку, чтобы закрыть его без проблем. Может быть, другое решение может быть сохранить его правильно после его создания? Не уверен, как это будет работать, хотя.

1 Ответ

2 голосов
/ 23 мая 2019

Удаление записи / NeedAppearances является правильным, но вам также необходимо создать внешний вид, здесь: черная рамка. Я также добавил текст.

    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);
...