PDF.js渲染PDF无Acroforms表单,如何开启表单填写支持功能?
PDF.js开启Acroforms表单填写功能解决方案
你当前的实现仅使用Canvas完成了PDF静态内容渲染,PDF.js的表单交互功能需要额外开启配置、添加独立的注解交互层才能生效,具体修改步骤如下:
1. 调整HTML结构与依赖
你需要补充容器层、注解层,以及引入Worker依赖,修改后代码如下:
<body> <!-- 新增容器包裹canvas和注解层,用于定位对齐 --> <div class="pdf-container"> <canvas id="pdf-render"></canvas> <!-- 新增表单注解层,用于承载可交互的表单元素 --> <div id="annotation-layer" class="annotationLayer"></div> </div> <script src="https://mozilla.github.io/pdf.js/build/pdf.js"></script> <script> // 必须配置对应版本的worker地址,和pdf.js版本保持一致 pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://mozilla.github.io/pdf.js/build/pdf.worker.js'; </script> <script src="js/main.js"></script> <style> .pdf-container { position: relative; width: fit-content; margin: 0 auto; } #pdf-render { display: block; } .annotationLayer { position: absolute; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; } /* 表单元素恢复交互能力 */ .annotationLayer input, .annotationLayer select, .annotationLayer textarea { pointer-events: auto; box-sizing: border-box; } </style> </body>
2. 修改main.js渲染逻辑
需要在文档加载时开启表单相关配置,页面渲染完成后追加表单注解层的渲染逻辑,修改后完整代码如下:
const url = 'pdf.pdf'; let pdfDoc = null, pageNum = 1, pageIsRendering = false, pageNumIsPending = null; const scale = 1, canvas = document.querySelector('#pdf-render'), ctx = canvas.getContext('2d'), // 新增:获取注解层DOM annotationLayer = document.querySelector('#annotation-layer'); // Render the page const renderPage = num => { pageIsRendering = true; // Get page pdfDoc.getPage(num).then(page => { // Set scale const viewport = page.getViewport({ scale }); canvas.height = viewport.height; canvas.width = viewport.width; const renderCtx = { canvasContext: ctx, viewport }; page.render(renderCtx).promise.then(() => { // 新增:渲染表单注解层 page.getAnnotations().then(annotations => { annotationLayer.innerHTML = ''; pdfjsLib.AnnotationLayer.render({ viewport: viewport.clone({ dontFlip: true }), div: annotationLayer, annotations: annotations, page: page, renderForms: true, // 必须开启,才能渲染可交互的表单元素 }); }); pageIsRendering = false; if (pageNumIsPending !== null) { renderPage(pageNumIsPending); pageNumIsPending = null; } }); }); }; // Check for pages rendering const queueRenderPage = num => { if (pageIsRendering) { pageNumIsPending = num; } else { renderPage(num); } }; // Get Document 新增:开启表单相关配置 pdfjsLib .getDocument({ url: url, enableScripting: true, // 开启PDF内嵌脚本支持,多数动态表单依赖该配置 enableXfa: true, // 支持XFA类型表单(可选,仅当你需要兼容XFA表单时开启) annotationMode: pdfjsLib.AnnotationMode.ENABLE_FORMS // 仅开启表单类注解,不需要其他注解可不用开全量 }) .promise.then(pdfDoc_ => { pdfDoc = pdfDoc_; renderPage(pageNum); }) .catch(err => { // Display error console.error('PDF加载失败', err); });
3. 附加说明
- 如果需要导出用户填写完成的PDF,可以调用
pdfDoc.saveDocument()获取填写后的数据,自行处理下载逻辑 - 表单元素的样式可以通过覆盖
.annotationLayer下的原生表单控件CSS自定义,适配自己的页面风格
内容的提问来源于stack exchange,提问作者Tamas
相关产品推荐
相关产品推荐

