Я хочу создать PDF-файл через java, который содержит два списка. Выбор элемента списка 1 должен изменить элементы списка 2. Я узнал, что для этого требуется javascript. Как я могу закодировать это в java. Я использую pdfbox до сих пор.
Я много гуглил, но не смог найти полный пример. Пожалуйста, смотрите ниже мой код, который создает список, текстовое поле и поле подписи.
import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.pdmodel.*;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.pdmodel.encryption.InvalidPasswordException;
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.apache.pdfbox.pdmodel.font.PDType1Font;
import org.apache.pdfbox.pdmodel.interactive.action.PDAction;
import org.apache.pdfbox.pdmodel.interactive.action.PDActionJavaScript;
import org.apache.pdfbox.pdmodel.interactive.action.PDAnnotationAdditionalActions;
import org.apache.pdfbox.pdmodel.interactive.action.PDFormFieldAdditionalActions;
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationWidget;
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAppearanceDictionary;
import org.apache.pdfbox.pdmodel.interactive.annotation.PDAppearanceStream;
import org.apache.pdfbox.pdmodel.interactive.form.*;
import java.awt.*;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
public class PDFCreate {
public static void main(String[] args) {
System.out.println("Creating pdf docoument including signature field");
try {
// Create a new document with an empty page.
PDDocument document = new PDDocument();
PDPage page = new PDPage(PDRectangle.A4);
document.addPage(page);
// Adobe Acrobat uses Helvetica as a default font and
// stores that under the name '/Helv' in the resources dictionary
PDFont font = PDType1Font.HELVETICA;
PDResources resources = new PDResources();
resources.put(COSName.getPDFName("Helv"), font);
PDDocumentCatalog pdCatalog = document.getDocumentCatalog();
PDAcroForm pdAcroForm = new PDAcroForm(document);
pdCatalog.setAcroForm(pdAcroForm);
pdAcroForm.setDefaultResources(resources);
String defaultAppearanceString = "/Helv 0 Tf 0 g";
pdAcroForm.setDefaultAppearance(defaultAppearanceString);
PDTextField textBox = new PDTextField(pdAcroForm);
textBox.setPartialName("newTextField");
defaultAppearanceString = "/Helv 12 Tf 0 g";
textBox.setDefaultAppearance(defaultAppearanceString);
pdAcroForm.getFields().add(textBox);
PDAnnotationWidget widget = textBox.getWidgets().get(0);
PDRectangle rect = new PDRectangle(50, 750, 200, 50);
widget.setRectangle(rect);
widget.setPage(page);
// make sure the annotation is visible on screen and paper
widget.setPrinted(true);
// Add the annotation to the page
page.getAnnotations().add(widget);
textBox.setValue("value in newly created text field");
PDListBox pdListBox = new PDListBox(pdAcroForm);
pdListBox.setPartialName("newListBox");
List<String> displayList = Arrays.asList("option 1", "option 2", "option 3");
List<String> exportList = Arrays.asList("option 1 key", "option 2 key", "option 3");
pdListBox.setOptions(exportList, displayList );
defaultAppearanceString = "/Helv 12 Tf 0 g";
pdListBox.setDefaultAppearance(defaultAppearanceString);
pdAcroForm.getFields().add(pdListBox);
PDAnnotationWidget widget2 = pdListBox.getWidgets().get(0);
PDRectangle rect2 = new PDRectangle(50, 680, 200, 50);
widget2.setRectangle(rect2);
widget2.setPage(page);
// make sure the annotation is visible on screen and paper
widget2.setPrinted(true);
PDFormFieldAdditionalActions pdFormFieldAdditionalActions = new PDFormFieldAdditionalActions();
PDActionJavaScript jsChangedAction = new PDActionJavaScript();
jsChangedAction.setAction("app.alert(\"On 'change' action\")");
pdFormFieldAdditionalActions.setC((PDAction) jsChangedAction);
pdListBox.setActions(pdFormFieldAdditionalActions);
// Add the annotation to the page
page.getAnnotations().add(widget2);
pdListBox.setValue("option 2 key");
PDRectangle rect3 = new PDRectangle(50, 150, 200, 50);
PDAppearanceDictionary appearanceDictionary = new PDAppearanceDictionary();
PDAppearanceStream appearanceStream = new PDAppearanceStream(document);
appearanceStream.setBBox(rect3.createRetranslatedRectangle());
appearanceStream.setResources(resources);
appearanceDictionary.setNormalAppearance(appearanceStream);
PDPageContentStream contentStream = new PDPageContentStream(document, appearanceStream);
contentStream.setStrokingColor(Color.BLACK);
contentStream.setNonStrokingColor(Color.LIGHT_GRAY);
contentStream.setLineWidth(2);
contentStream.addRect(0, 0, rect3.getWidth(), rect3.getHeight());
contentStream.fill();
contentStream.moveTo(1 * rect3.getHeight() / 4, 1 * rect3.getHeight() / 4);
contentStream.lineTo(2 * rect3.getHeight() / 4, 3 * rect3.getHeight() / 4);
contentStream.moveTo(1 * rect3.getHeight() / 4, 3 * rect3.getHeight() / 4);
contentStream.lineTo(2 * rect3.getHeight() / 4, 1 * rect3.getHeight() / 4);
contentStream.moveTo(3 * rect3.getHeight() / 4, 1 * rect3.getHeight() / 4);
contentStream.lineTo(rect3.getWidth() - rect3.getHeight() / 4, 1 * rect3.getHeight() / 4);
contentStream.stroke();
contentStream.setNonStrokingColor(Color.DARK_GRAY);
contentStream.beginText();
contentStream.setFont(font, rect3.getHeight() / 5);
contentStream.newLineAtOffset(3 * rect3.getHeight() / 4, -font.getBoundingBox().getLowerLeftY() * rect3.getHeight() / 5000);
contentStream.showText("Customer");
contentStream.endText();
contentStream.close();
PDSignatureField signatureField = new PDSignatureField(pdAcroForm);
signatureField.setPartialName("SignatureField");
PDAnnotationWidget widget3 = signatureField.getWidgets().get(0);
widget3.setAppearance(appearanceDictionary);
widget3.setRectangle(rect3);
widget3.setPage(page);
page.getAnnotations().add(widget3);
pdAcroForm.getFields().add(signatureField);
PDFormFieldAdditionalActions pdFormAdditionalActions = new PDFormFieldAdditionalActions();
String javaScript = "app.alert( {cMsg: 'this is an example', nIcon: 3,"
+ " nType: 0,cTitle: 'PDFBox Javascript example' } );";
PDActionJavaScript PDAjavascript = new PDActionJavaScript(javaScript);
pdFormAdditionalActions.setC(PDAjavascript);
/* PDActionJavaScript(PDAjavascript); */
pdListBox.setActions(pdFormAdditionalActions);
pdListBox.getActions().getCOSObject().addAll(pdFormAdditionalActions.getCOSObject());
//document.getDocumentCatalog().setOpenAction(PDAjavascript);
document.save("create from empty.pdf");
for (PDField pdField : pdAcroForm.getFields()) {
System.out.println(pdField.getFullyQualifiedName() + " " + pdField.getFieldType() + " " + pdField.getValueAsString());
}
document.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
измененное действие в моем коде никогда не дает никакого эффекта. Что еще более важно, мне нужна помощь, чтобы добавить действие, которое изменит записи второго списка на основе выбранного элемента первого списка. Заранее спасибо!
Вы не добавили виджет поля в список аннотаций страницы. И прямоугольника нет.
Спасибо за ваши Коментарии. Теперь я вставил свой полный код. Мне все еще нужна помощь, чтобы добавить действие, которое изменит записи второго списка на основе выбранного элемента первого списка. Заранее спасибо!
В javadoc и спецификации упоминается, что вы должны иметь запись /CO в акроформе. Однако PDAcroForm не предлагает эту функцию. Что немного помогает, так это: COSArray coArray = new COSArray(); coArray.add(pdListBox); pdAcroForm.getCOSObject().setItem(COSName.CO, coArray);
. Теперь появляется сообщение, если я изменяю список, а затем нажимаю на текстовое поле. Я не знаю, этого ли ты хотел.
Другой альтернативой может быть использование PDAnnotationAdditionalActions
с виджетом и setU()
, см. здесь: stackoverflow.com/questions/56192573
Спасибо за вашу помощь! Теперь мне удалось заполнить список два в зависимости от выбора первого списка. Я столкнулся с новой проблемой: я больше не могу подписать документ после изменения. Я могу подписать до того, как сделать выбор в списке. Я открыл новый вопрос для этого.
Пожалуйста, ответьте на этот вопрос сами, чтобы помочь другим, так как я не знаю, какое изменение кода было бы лучше.
// Следующее решило проблему:
// Определяем содержимое списка.
String javaScript = " + "this.getField('signatureField').display=display.hidden;" + "var formReady = false;" + "var anacredit = { '-': [['-', '-'] ], " + " 'Люксембург': [[ '-', '-'], ['LU01 Entreprise individuelle', 'LU01'],[ 'LU06 Société anonyme', 'LU06'] ,['LU14 Société civile' ,'LU14']] , " + " 'Германия': [[ '-', '-'], ['DE201 Aktiengesellschaft', 'DE201'], ['DE602 EV', 'DE602'], ['DE205 Investmentaktiengesellschaft', 'DE205']], " + " 'Греция': [[ '-', '-'], ['GR906 Εταιρία Περιορισμένης Ευθύνης/Etería', 'GR906'], ['GR912 GR'9π'αο '], ['GR999 Λοιπά', 'GR999']] };";
// javascript для списка 1
String jsListBox0 = "var f = this.getField('домицилирование');" + "var r = this.getField('legalForm');" + " console.println('dom ' + f.value + 'lF' + r.value);" + "if (event.willCommit)" + "{ console.println('dom EC' + event.change + ' EV' + event.value + ' ECE ' + event.changeEx); " + " r.setItems( anacredit [событие.значение] );" + "this.getField('signatureField').display=display.hidden;" + "r.значение = '-';" + "}";
// связанный код Java для списка 1
jsKeystrokeAction.setAction (jsListBox0); fieldActions.setK(jsKeystrokeAction); место жительства.setActions(fieldActions);
// javascript для списка 2
String jsListBox2 = "var lb = this.getField('legalForm'); var d = this.getField('домицилирование');" + "var sf = this.getField('signatureField');" + "if (!event.willCommit)" + "{ console.println('lF' + lb.value + 'EC' + event.change + 'EV' + event.value + 'ECE' + event.changeEx); " + " if ((event.changeEx =='-') || (event.changeEx == null)) sf.display = display.hidden;" + "else sf.display = display.visible}";
// связанный код Java для списка 2
jsKeyStrokeAction.setAction(jsListBox2); fieldActions2.setK(jsKeyStrokeAction); LegalForm.setActions(fieldActions2);
Привет приятель! Добавьте дополнительную информацию, используя кнопку редактировать вопроса, а не раздел комментариев. Спасибо за Ваше понимание.