我正在尝试创建一个简单的pdf多页文档中的字段。为此,我有一个模板pdf,在代码中,我根据需要多次克隆这个模板,以便创建文档本身。
问题是在其中插入一些数据。我尝试插入到文档中的数据类型不应该在不同的页面中改变。相反,它在所有页面中保持静态,就像“pages”数字表示文档中包含的页面数。
现在,在我的模板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表单中所有字段的信息。信息为:字段名称、字段小部件宽度、字段字体和字体大小
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)
}
}
}
}
结果是,在第一页中,字段“shipper”的值为“david”;在第二页中,字段“shipper”为空。
这里有一个图像。第一页:
// 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)
你想要的是有相同领域的sereval视觉表示。这是通过为这样一个字段设置几个注释小部件来实现的。
在PDF中,当一个字段只有一个注释小部件时,它们共享一个公共字典。当它有几个时,注释小部件就在字段的子列表中。
当您需要为一个字段创建多个注释小部件时,您需要使用new PDAnnotationWidget()
创建注释小部件,而不是调用field.getWidgets().get(0)
并使用该小部件。必须将这些小部件添加到一个列表中,并且必须将此列表分配给具有setWidgets()
的字段。对于每个小部件,必须调用setRectangle()
和setPage()
和setParent()
。
在新的CreateMultiWidgetsForm.java示例中有一个这样的示例。setParent()
方法在2.0.3中尚不可用(但将在2.0.4中使用)。在这个答案中,它被替换为一个以不那么优雅的方式做同样事情的调用。
public final class CreateMultiWidgetsForm
{
private CreateMultiWidgetsForm()
{
}
public static void main(String[] args) throws IOException
{
// Create a new document with 2 empty pages.
PDDocument document = new PDDocument();
PDPage page1 = new PDPage(PDRectangle.A4);
document.addPage(page1);
PDPage page2 = new PDPage(PDRectangle.A4);
document.addPage(page2);
// 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);
// Add a new AcroForm and add that to the document
PDAcroForm acroForm = new PDAcroForm(document);
document.getDocumentCatalog().setAcroForm(acroForm);
// Add and set the resources and default appearance at the form level
acroForm.setDefaultResources(resources);
// Acrobat sets the font size on the form level to be
// auto sized as default. This is done by setting the font size to '0'
String defaultAppearanceString = "/Helv 0 Tf 0 g";
acroForm.setDefaultAppearance(defaultAppearanceString);
// Add a form field to the form.
PDTextField textBox = new PDTextField(acroForm);
textBox.setPartialName("SampleField");
// Acrobat sets the font size to 12 as default
// This is done by setting the font size to '12' on the
// field level.
// The text color is set to blue in this example.
// To use black, replace "0 0 1 rg" with "0 0 0 rg" or "0 g".
defaultAppearanceString = "/Helv 12 Tf 0 0 1 rg";
textBox.setDefaultAppearance(defaultAppearanceString);
// add the field to the AcroForm
acroForm.getFields().add(textBox);
// Specify 1st annotation associated with the field
PDAnnotationWidget widget1 = new PDAnnotationWidget();
PDRectangle rect = new PDRectangle(50, 750, 250, 50);
widget1.setRectangle(rect);
widget1.setPage(page1);
widget1.getCOSObject().setItem(COSName.PARENT, textBox);
// Specify 2nd annotation associated with the field
PDAnnotationWidget widget2 = new PDAnnotationWidget();
PDRectangle rect2 = new PDRectangle(200, 650, 100, 50);
widget2.setRectangle(rect2);
widget2.setPage(page2);
widget2.getCOSObject().setItem(COSName.PARENT, textBox);
// set green border and yellow background for 1st widget
// if you prefer defaults, just delete this code block
PDAppearanceCharacteristicsDictionary fieldAppearance1
= new PDAppearanceCharacteristicsDictionary(new COSDictionary());
fieldAppearance1.setBorderColour(new PDColor(new float[]{0,1,0}, PDDeviceRGB.INSTANCE));
fieldAppearance1.setBackground(new PDColor(new float[]{1,1,0}, PDDeviceRGB.INSTANCE));
widget1.setAppearanceCharacteristics(fieldAppearance1);
// set red border and green background for 2nd widget
// if you prefer defaults, just delete this code block
PDAppearanceCharacteristicsDictionary fieldAppearance2
= new PDAppearanceCharacteristicsDictionary(new COSDictionary());
fieldAppearance2.setBorderColour(new PDColor(new float[]{1,0,0}, PDDeviceRGB.INSTANCE));
fieldAppearance2.setBackground(new PDColor(new float[]{0,1,0}, PDDeviceRGB.INSTANCE));
widget2.setAppearanceCharacteristics(fieldAppearance2);
List <PDAnnotationWidget> widgets = new ArrayList<PDAnnotationWidget>();
widgets.add(widget1);
widgets.add(widget2);
textBox.setWidgets(widgets);
// make sure the annotations are visible on screen and paper
widget1.setPrinted(true);
widget2.setPrinted(true);
// Add the annotations to the pages
page1.getAnnotations().add(widget1);
page2.getAnnotations().add(widget2);
// set the field value
textBox.setValue("Sample field");
document.save("MultiWidgetsForm.pdf");
document.close();
}
}
我正在使用PDFbox下载PDF。我想在中间添加一些新页面。 此代码在PDF结尾处插入新页面。如何在另一个位置插入页面?
嗨,我是拉威尔的新手,我在将数据插入数据库和抛出错误时遇到了麻烦 msgstr"Countable():参数必须是实现可数的数组或对象" 我想在数据库中添加所有注册员工的出勤信息 控制器 叶片输出: 模型类员工出席扩展模型{// } 模型2 命名空间App; 使用Illumb\Database\Elount\Model; 类employee_data扩展模型{//protected$fillabe
在一个带桶的表格中进行这种多次插入,这样行吗?是否影响台面的铲斗?
问题内容: 我正在寻找一种刷新页面时停止在数据库中插入或发送数据的方法。 这是我的代码: user_details_page.php Confirm_page.php 因此,每次我刷新确认page.php时,都会将数据发送到数据库。如何停止呢? 问题答案: 将用户带到新页面: 通过这样做,刷新的用户将得到刷新,这意味着它将不会重复执行两次插入操作。 最好的建议 :如果没有,请检查用户是否首先存在!
我想我在这段代码中遇到了一点问题:当我试图在数据库中插入值时,我遇到了一个错误。
问题内容: 我试图在 Flask-SQLAlchemy中 建立多对多关系,但似乎我不知道如何填写 “多对多标识符数据库” 。您能帮我了解我在做什么错以及应该怎么看吗? 然后是我的标识符数据库: 到目前为止,当我尝试将数据插入数据库时,看起来像这样。 现在我的问题是,由于我真的无法创建“ student_identifier”对象,如何将其添加到多对多数据库?如果可以的话,它可能看起来像这样: