我正在嘗試創建一個簡單的pdf多頁文檔,其中包含字段。要做到這一點,我有一個模板pdf,它在代碼中根據需要多次克隆此模板以創建文檔本身。PDFBox將數據插入多頁文檔
問題出現在插入一些數據。我嘗試插入文檔的數據類型不應該跨頁面更改。而不是,它在所有頁面中保持靜態,就像表示這個文檔包含的頁面數量的「頁面」數字一樣。
現在,在我的模板pdf中,我有一些文本字段,比如「Shipper1」和「Pages」。我希望能夠將我的數據插入到這些文本字段中,以便文檔中的所有頁面在其「Shipper1」和「Pages」字段中都具有此值。
我的代碼目前只在第一頁上做。它完美地顯示數據。另一方面,當我轉到另一頁時,數據不會顯示在那裏。它只是顯示一個空的字段。
這裏就是我發起PDF文檔代碼:
static void initiatePdf() {
// Initiate a new PDF Box object and get the acro form from it
File file = new File(Constants.Paths.EMPTY_DOC)
PDDocument tempDoc
Evaluator evaluator = new Evaluator(metaHolder)
int numPages = evaluator.getNumOfPagesRequired(objects)
FieldRenamer renamer = new FieldRenamer()
PDResources res = new PDResources()
COSDictionary acroFormDict = new COSDictionary()
List<PDField> fields = []
Closure isFieldExist = {List<PDField> elements, String fieldName ->
elements.findAll{it.getFullyQualifiedName() == fieldName}.size() > 0
}
for(int i = 0; i < numPages; i++) {
tempDoc = new PDDocument().load(file)
PDDocumentCatalog docCatalog = tempDoc.getDocumentCatalog()
PDAcroForm acroForm = docCatalog.acroForm
PDPage page = (PDPage) docCatalog.getPages().get(0)
renamer.setCurrentForm(acroForm)
if(i == 0) {
res = acroForm.getDefaultResources()
acroFormDict.mergeInto(acroForm.getCOSObject())
renamer.renameFields(1)
} else
renamer.renameFields(i*10+1)
List<PDField> newFields = acroForm.fields.findAll { PDField newField ->
isFieldExist(fields, newField.getFullyQualifiedName()) == false
}
fields.addAll(newFields)
document.addPage(page)
}
PDAcroForm acroForm = new PDAcroForm(document, acroFormDict);
acroForm.setFields(fields)
acroForm.setDefaultResources(res);
document.documentCatalog.setAcroForm(acroForm)
}
幾件事情第一: metaHolder
實例保存所有 駐留在ACRO表單中的字段的信息。信息是:字段名稱,字段控件寬度,字段字體和字體大小
evaluator
是Evaluator
類的實例。其目的是分析動態數據並確定將包含所有文本數據的頁面數量。
這裏就是我試圖填充文本字段:
static void populateData() {
def properties = ["$Constants.Fields.SHIPPER" : "David"]
FieldPopulater populater = new FieldPopulater(document, metaHolder)
populater.populateStaticFields(properties)
}
FieldPopulater類:
package app.components
import app.StringUtils
import app.components.entities.DGObject
import app.components.entities.FieldMeta
import org.apache.pdfbox.pdmodel.PDDocument
import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm
import org.apache.pdfbox.pdmodel.interactive.form.PDField
/**
* Created by David on 18/10/2016.
*/
class FieldPopulater {
PDAcroForm acroForm
FormMetaHolder metaHolder
FieldPopulater(PDDocument document, FormMetaHolder metaHolder) {
this.acroForm = document.getDocumentCatalog().acroForm
this.metaHolder = metaHolder
}
void populateStaticFields(properties) {
List<PDField> fields = []
properties.each {fieldName, data ->
FieldMeta fieldMeta = metaHolder.getMetaData(fieldName)
fields = acroForm.fields.findAll { PDField field ->
String currentName = field.getFullyQualifiedName()
char lastChar = currentName[-1]
if(Character.isDigit(lastChar)) {
currentName = currentName.substring(0,currentName.size()-1)
}
currentName == fieldName
}
if(fields.size() > 1) {
int counter = 1
String tempData = data
String currentFitData
while(tempData.isEmpty() != true) {
int maxWords = Utils.getMaxWords(tempData, fieldMeta)
currentFitData = StringUtils.getTextByWords(tempData, maxWords)
tempData = StringUtils.chopTextByWords(tempData, maxWords)
PDField field = fields.find{it.getFullyQualifiedName()[-1] == "$counter"}
field?.setValue(currentFitData)
counter++
}
} else {
PDField tempField = fields[0]
tempField.setValue(data)
}
}
}
}
其結果是,在第一頁,現場「託運人」有一個值「David」 在第二頁中,「託運人」字段爲空。
這是一張圖片。第一頁:
第二頁:
這裏有什麼問題嗎?
更新:我試圖將每個新的acro表單的小部件添加到當前頁面,以便每個字段都會有幾個孩子小部件代表該字段,但它仍然不起作用。
// All the widgets that are associated with the fields
List<PDAnnotationWidget> widgets = acroForm.fields.collect {PDField field -> field.getWidgets().get(0)}
page.annotations.addAll(widgets)
更新:我也試過一個字段的當前窗口小部件添加到小部件的父字段的集合。這裏是代碼:
List<PDAnnotationWidget> widgets = []
// All the widgets that are associated with the fields
acroForm.fields.each {PDField field ->
PDAnnotationWidget widget = field.widgets.get(0)
// Adding the following widget to the page and to the field's list of annotation widgets
widgets.add(widget)
fields.find {it.getFullyQualifiedName() == field.getFullyQualifiedName()}?.widgets.add(widget)
}
page.annotations.addAll(widgets)
這裏已經很晚了,所以只是一個簡單的提示:跨頁面具有相同的值,您的字段需要有多個註釋小部件,即每個頁面上有一個小部件。該領域必須將這些小部件作爲孩子。每個頁面都必須在其註釋列表中包含此小部件。獲取一些現有的表單文檔(或者創建一個帶有Adobe Acrobat的文檔,如果有的話),並使用PDFDebugger進行查看。 –
我試圖做你所說的,即在頁面中添加一個acro表單的小部件,但問題依然存在。我在帖子中添加了我寫的代碼 –
不需要每個頁面都有一個獨立的小部件。即該字段必須有兩個孩子小部件。我爲自己做了一個備忘錄來擴大acroform的例子。 –