You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 08:24:04