【发布时间】:2022-06-24 05:17:53
【问题描述】:
我正在尝试从我的文件系统上的模板创建一个多页文档,但我却在文档中的所有页面上出现了相同页面标题的奇怪行为。有什么想法我在这里做错了吗?
我不太明白的是我们添加页面的方式。为什么我们需要在下面的例子中引用
newDoc
,而我们在做
await newDoc.copyPages(page, [0])
?而不仅仅是
newDoc.addPage(page)
?
会不会是因为在复制数据流的时候两个页面的字段名相同,所以表单字段
Title
被覆盖了?
注意: 我已经知道 StackOverflow 没有 pdf-lib.js.org 的标签,不要与其他 pdf 库混淆。
const payload = {
rows: [{
id: 1,
title: 'Foo',
},{
id: 2,
title: 'Bar'
},
formData: {
hello: 'World',
lorum: 'Ipsum'
}
]
}
const makePdf = async (payload) => {
const newDoc = await PDFDocument.create()
newDoc.getForm().acroForm.dict.set(PDFName.of('NeedAppearances'), PDFBool.True)
for (const row of payload.rows) {
await addPage(row, payload.formData, newDoc)
}
return newDoc
}
const addPage = async (dataRow, formData, newDoc) => {
const rowId = dataRow.id
let templateName
switch(true) {
case (rowId === 1):
templateName = 'foo'
break
case (rowId === 2):
templateName = 'bar'
break
}
const templatePath = path.join(__dirname, `../templates/pdfs_/${templateName}.pdf`)
const template = await fs.readFileSync(templatePath)
const page = await PDFDocument.load(template)
const form = page.getForm()
form.acroForm.dict.set(PDFName.of('NeedAppearances'), PDFBool.True)
switch(templateName) {
case 'foo':
foo(form, formData)
break
case 'bar':
bar(form, formData)
}
// dataRow.title logs correct strings ie: 'Foo' & 'Bar'
form.getField('Title').setText(dataRow.title)
const [firstPage] = await newDoc.copyPages(page, [0])
return await newDoc.addPage(firstPage)
}
const bar = (form, formData) => {
form.getField('Lorum').setText(formData.lorum)
}
const foo = (form, payload) => {
form.getField('Hello').setText(formData.hello)
}
return makePdf(payload)
// Produces 2 page pdf with the same title
// [[ title: Foo, Hello: World ], [title: Foo, Lorum: Ipsum ]]
-
How to Ask - 你想达到什么目的?可以分享一下模板示例吗?
-
每个标题字段,每个页面上的不同文本
-
看我的回答,我想这就是你要找的东西
-
@yeya 感谢您的回复。我试图为每一行加载一个新模板,我看到你所有页面只有一个模板。如果我将
loadTemplate
函数移到for
循环中,它可能会起作用。您还需要将pdfSample.templateDoc
传递给addDocPage
函数吗?我已经有一段时间没有使用 JS 类了,但我会尝试一下,让你知道它是否有效。 -
是的,您可以为每个文件调用 loadTemplate。不,您不需要填充 templateDoc,因为 loadTemplate 在每个 loadTemplate 上都保存到
this
。如果它回答了您的问题,请接受答案。