问题
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