PDF.js 设置字段值?

问题描述 投票:0回答:2

我希望你们一切都好。我已经使用 Mozilla 的 PDF.js 一段时间了。我们使用它来显示要在移动应用程序上填写的 PDF 表单。一切都很好,我只是想实现一个功能,您可以缓存用户条目,以便他们可以从中断的地方恢复。由于一些原因,我不能只下载 PDF 来保存它,然后在他们想要恢复时加载它。

本质上,我想存储所有用户条目和每个条目的字段 ID,我已经开始工作,然后当用户想要恢复时,我希望它加载空 PDF,然后自动重新填充具有缓存条目的所有字段。

我知道我可以设置单独的文本字段,但是当我这样做时,它不适用于注释存储,因此当我解析表单时,这些字段将被读取为空白。

我尝试了以下几行代码来尝试设置 id 为“5R”的字段值

PDFViewerApplication.pdfDocument.annotationStorage.setValue('5R', "Shirboogle");
PDFViewerApplication.pdfDocument.annotationStorage.getAll()['5R'].value = "Shirboogle";
var objs = await PDFViewerApplication.pdfDocument.getFieldObjects();
objs['Address 1 Text Box'][0].value = "Shirboogle";
// and
objs['Address 1 Text Box'][0].defaultValue = "Shirboogle";
// This will actually set the value of the text field, but when I look for it in annotationStorage OR
// getFieldObjects() the value is still unchanged.
document.getElementById('pdfjs_internal_id_5R').value = 'Shapoopsies';

以及许多其他尝试。我已经查遍了,似乎没有什么可用的,所以如果您有任何想法请告诉我!

javascript html forms pdf pdf.js
2个回答
1
投票
  • 如果有人遇到此问题,这是我想出的解决方案。它似乎非常适合我的用例,但可能不足以满足所有情况。我想我至少应该分享我的工作内容。

  • 它基本上手动设置所有内容。我仍然需要制作一些 UI 元素来设置 if 语句,但无论如何。这是我的代码。祝你好运:)


function getFieldValue(id) {
    return PDFViewerApplication.pdfDocument.annotationStorage.getAll()[id].value;
}


async function getFieldObjById(id) {
    var objs = await PDFViewerApplication.pdfDocument.getFieldObjects();
    for(var i=0; i<Object.values(objs).length; i++) {
        if(Object.values(objs)[i][0].id == id) {
            return Object.values(objs)[i][0];
        }
    }
}

async function setFieldValue(id, val) {
    var fElementId = "pdfjs_internal_id_" + id;
    var fObject = await getFieldObjById(id);
    var objType = fObject.type;
    
    // Depending on the element type we set the value accordingly.
    if(objType == 'text') {
        document.getElementById(fElementId).value = val;
        PDFViewerApplication.pdfDocument.annotationStorage.setValue(id, {value: val});
    }

    else if(objType == 'checkbox') {
        document.getElementById(fElementId).checked = val;
        PDFViewerApplication.pdfDocument.annotationStorage.setValue(id, {value: val});
    }

    else if(objType == 'combobox') {
        document.getElementById(fElementId).selectedIndex = val;
        var sLabel = document.getElementById(fElementId).options[document.getElementById(fElementId).selectedIndex].label;
        PDFViewerApplication.pdfDocument.annotationStorage.setValue(id, {value: sLabel});
    }

}

0
投票

好吧我解决了!我解决了它,我的意思是,我发现了一个 github 问题,其中有人在 pdf-lib 中遇到了非常相似的问题,并改编了我从该问题中学到的知识来解决我的问题。本质上,您可以从较低级别的

acroForm
API 获取必需的字段。

最终解决方案:

  const bytes = fs.readFileSync('form-cms1500.pdf')
  const pdfDoc = await PDFDocument.load(bytes);
  const form = pdfDoc.getForm();
  const allfields = form.acroForm.getAllFields()
  allfields[32][0].setValue(allfields[32][0].getOnValue())
  const pdfBytes = await pdfDoc.save()
  await fs.writeFileSync('test.pdf', pdfBytes)

其中#32 字段是我想要标记的复选框。我通过打印字段名称及其索引发现它是#32。

事实证明 pdf.js 对于更新字段非常不友好,所以最好的选择就是不要使用它。

© www.soinside.com 2019 - 2024. All rights reserved.