簡體   English   中英

使用 PDFBox 將計算腳本添加到 pdf 表單域

[英]Add calculation script to pdf form fields with PDFBox

也許有人可以幫我解決這個問題。 我有一個 java 應用程序,它使用 flying-saucer-pdf 從 HTML 模板生成一個 PDF 文件。 由於不支持 JavaScript,我打算在使用 PDFBox 創建 PDF 后添加我的 JavaScript。

我想添加 JavaScript 以從字段 A 中讀取一個值,根據該值計算一個新的總和並將其寫入另一個字段 B。每次輸入字段 A 中的值更改時都應進行此計算。

但我的問題是,我不知道如何將我的 JavaScript 添加到現有的 PDF 文件中。 我在網上找到了這個關於如何添加 JavaScript 的示例,但它只顯示了如何向 PDF 的打開事件注冊一個動作。這沒有幫助,因為我想按照Acrobat JS 開發人員指南中計算腳本下的描述添加計算.

我想我必須以某種方式修改 Documents PDAcroForm 甚至還有一個getScriptingHandler() -方法,看起來很有希望,它在我的文檔中是 null。 到目前為止,我添加 JavaScript 的代碼如下所示:

try (var document = PDDocument.load(pdfFile)) {
  var documentDocumentCatalog = document.getDocumentCatalog();
  var documentAcroForm = documentDocumentCatalog.getAcroForm();
  var javascriptString = FileUtils.readFileToString(
                           javascriptFile, 
                           StandardCharsets.UTF_8,
                         );
  var javascript = new PDActionJavaScript(javascriptString);
  documentAcroForm.getScriptingHandler().calculate(javascript, "99");
} catch (IOException e) {
  e.printStackTrace();
}

>>更新<<

感謝您的投入,我已經設法實現了計算新值的目標。 我的 Java 代碼現在看起來像這樣:

try (var document = PDDocument.load(pdfFile)) {
  var catalog = document.getDocumentCatalog();
  var acroForm = catalog.getAcroForm();

  var fieldActions = new PDFormFieldAdditionalActions();
  var javascriptString = FileUtils.readFileToString(javascriptFile, StandardCharsets.UTF_8);
  var actionJavaScript = new PDActionJavaScript(javascriptString);
  actionJavaScript.setAction(javascriptString);
  fieldActions.setC(actionJavaScript);

  var field = (PDTextField) acroForm.getField("fieldA");
  field.setActions(fieldActions);
  var coArray = new COSArray();
  coArray.add(field);
  acroForm.getCOSObject().setItem(COSName.CO, coArray);

  document.save(pdfFile);
} catch (IOException e) {
  e.printStackTrace();
}

我的 JavaScript 代碼如下所示:

calculateValue("fieldA", "fieldB");

function calculateValue(sourceFieldName, targetFieldName) {
    this.getField(sourceFieldName).value = Math.floor(this.getField(targetFieldName).value / 2 - 5)
}

這行得通,雖然我偶然發現了一些奇怪的行為,但也許我只是誤解了 change 事件。 使用此代碼,即使我只將“fieldA”添加到重新計算順序,似乎任何字段中的任何更改都會觸發事件。 我真正想要實現的是,只有特定字段的更改才會觸發另一個特定字段的重新計算。 這是重新計算應該如何工作嗎?

>>更新2<<

沒關系,我只是犯了錯誤,並在每次重新計算事件時更新了兩個字段......在調整我的 JavaScript 之后,現在一切都按預期進行。

還有一個問題,如何在文檔中全局添加 JavaScript function 然后在現場事件中調用它?

謝謝您的幫助!

在 PDF 級別上,它看起來像這樣:

//The text field
10 0 obj
<</AA<</C 12 0 R>>/AP<</N 100 0 R>>/F 4/FT/Tx/Ff 2/MK<</BC[0.0 0.0 0.0]>>/P 23 0 R/Rect[339.288 570.374 443.231 589.985]/Subtype/Widget/T(Textfield10)/Type/Annot/V(7)>>
endobj

//The JS function which writes the result of 'Textfield1'+'Textfield3' into Textfield10
12 0 obj
<</JS(AFSimple_Calculate\("SUM", new Array \("Textfield1", "Textfield3"\)\);)/S/JavaScript>>
endobj

14 0 obj
<</CO[10 0 R]/DA(/Helv 0 Tf 0 g )/Fields[10 0 R 16 0 R 18 0 R] ...>>

因此,正如您所見,附加操作 (AA) 屬性是要使用的關鍵。 在 web 或SO上有幾個關於如何做到這一點的答案。 它看起來像這樣:

PDFormFieldAdditionalActions pdFormFieldAdditionalActions = new PDFormFieldAdditionalActions();
PDActionJavaScript jsSumAction = new PDActionJavaScript();
jsSumAction .setAction("AFSimple_Calculate\("SUM", new Array \("Textfield1", "Textfield3"\)\);");
pdFormFieldAdditionalActions.setC((PDAction) jsSumAction);

請注意,此處使用的 JS 語法是 *dobe JS 語法 - 因此它可能不適用於其他查看器。 但無論如何,這就是 PDF 中 JS 腳本的問題,也是 PDF/A 中禁止使用它的原因之一……

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM