フィールドがある簡単なPDFの複数ページ文書を作成しようとしています。これを行うために、私はテンプレートpdfを持っています。このpdfは、ドキュメント自体を作成するために必要なだけこのテンプレートをクローンします。複数ページの文書にデータを挿入するPDFBox
いくつかのデータを挿入すると問題が発生します。ドキュメントに挿入しようとするデータの種類は、ページ間で変更されることは想定されていません。それよりむしろ、このドキュメントに含まれるページの数を表す「ページ」桁のように、すべてのページに静的にとどまります。
私のテンプレートの中には、「Shipper1」や「Pages」のようなテキストフィールドがあります。このテキストフィールドにデータを挿入して、ドキュメント内のすべてのページに「Shipper1」と「Pages」フィールドにこの値を設定できるようにしたいと考えています。
現在のところ、自分のコードでは最初のページにしか表示されません。それはデータを完全に示しています。一方、私が別のページに行くと、データはそこに表示されません。空のフィールドが表示されます。
が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
インスタンスはアクロフォームの中に存在するすべての フィールドに関する情報を保持している。ここ
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"の 2番目のページでは、 "Shipper"フィールドは空です。
ここに画像があります。最初のページ:
2ページ目:
は、ここでの問題は何ですか?
更新:すべてのフィールドがフィールドを表すいくつかの子供ウィジェットになるように、新しい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)
UPDATE:フィールドの現在のウィジェットを親フィールドのウィジェットのコレクションに追加しようとしました。ここでは、コードは次のとおりです。
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)
ここに遅れているので、簡単なヒント:ページに同じ値を設定するには、フィールドごとに複数の注釈ウィジェット、つまりすべてのページに1つの注釈ウィジェットが必要です。フィールドには、これらのウィジェットが子供として必要です。ページにはそれぞれ、アノテーションリストにこのウィジェットが含まれている必要があります。このような機能を持つ既存のフォームドキュメントを入手(またはAdobe Acrobatを使用している場合はAdobe Acrobatで作成)し、PDFDebuggerで表示します。 –
私はあなたが言ったこと、つまりアクロフォームのウィジェットをページに追加しようとしましたが、問題は残っています。投稿したコードを投稿に追加しました –
いいえ、すべてのページに別々のウィジェットが必要です。私。フィールドには2つの子供用ウィジェットが必要です。私はacroformの例を拡張するために自分自身にメモを作った。 –