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

PDF.js如何将填写完成的Acroform表单PDF存储到服务器

问题根因说明

pdf.js默认示例查看器中,检测到当前加载的PDF包含Acroform表单时,会主动给下载按钮添加hidden属性隐藏,本质是早期版本对表单数据持久化导出的兼容性做的限制。你手动取消隐藏后能下载带填写数据的PDF,说明你使用的版本已经支持表单数据写入导出逻辑,仅前端UI做了隐藏限制。

实现方案步骤

1. 解除下载按钮的隐藏限制(可选)

如果需要保留前端UI的下载功能,可以找到viewer.js中关联Acroform检测和下载按钮显隐的判断逻辑,注释掉给下载按钮添加隐藏属性的代码即可。如果不需要保留UI下载按钮,可直接跳过此步骤,调用API直接导出PDF。

2. 前端导出带填写数据的PDF为Blob对象

无需触发下载按钮点击,直接调用pdf.js内置API即可导出携带最新表单数据的PDF文件:

// 等待PDF加载、表单填写完成后执行
async function exportFilledPdf() {
  // pdfViewer为pdf.js默认查看器的全局实例,二次封装版本可自行调整实例获取路径
  const pdfDocument = pdfViewer.pdfDocument;
  // 导出包含所有填写数据的完整PDF二进制流
  const savedData = await pdfDocument.saveDocument();
  // 转换为Blob对象
  return new Blob([savedData], { type: 'application/pdf' });
}

3. 前端发送POST请求上传到Servlet

使用FormData封装PDF Blob后发送请求即可:

async function uploadPdfToServlet(blob) {
  const formData = new FormData();
  // 参数名、文件名可自行调整,和服务端接收参数保持一致即可
  formData.append('filledPdf', blob, '填写完成的表单.pdf');

  try {
    const response = await fetch('/你的Servlet访问路径', {
      method: 'POST',
      body: formData
    });
    if (response.ok) {
      console.log('PDF上传成功');
    }
  } catch (error) {
    console.error('PDF上传失败', error);
  }
}

// 调用示例
exportFilledPdf().then(blob => uploadPdfToServlet(blob));

4. 服务端Servlet接收保存

Servlet 3.0及以上版本可直接使用@MultipartConfig注解实现multipart类型请求的解析:

import javax.servlet.annotation.MultipartConfig;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
import java.io.FileOutputStream;
import java.io.InputStream;

@MultipartConfig(maxFileSize = 1024 * 1024 * 50) // 单文件最大50M,可自行调整
public class PdfUploadServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) {
        try {
            // 和前端FormData的参数名保持一致
            Part pdfPart = request.getPart("filledPdf");
            InputStream pdfInputStream = pdfPart.getInputStream();
            // 自定义服务端文件保存路径
            FileOutputStream outputStream = new FileOutputStream("/服务端保存路径/用户上传表单.pdf");
            
            byte[] buffer = new byte[1024];
            int len;
            while ((len = pdfInputStream.read(buffer)) != -1) {
                outputStream.write(buffer, 0, len);
            }
            
            outputStream.close();
            pdfInputStream.close();
            response.setStatus(HttpServletResponse.SC_OK);
        } catch (Exception e) {
            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            e.printStackTrace();
        }
    }
}
注意事项
  • 若使用二次封装的pdf.js组件,需确认PDF实例的获取路径,部分封装版本会将实例挂载到自定义变量下
  • 导出的PDF默认会保留所有Acroform字段的填写数据,无需额外做字段序列化处理
  • 服务端可根据业务需求调整文件大小限制、存储路径、文件命名规则等配置

内容的提问来源于stack exchange,提问作者C. Rich

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 13:45:03