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

如何在React JS中从列表数据生成多页PDF并实现一键批量打印

React 批量生成多份PDF并一键打印实现方案

前置准备

你已经实现的单条数据生成PDF逻辑可以直接复用,目前社区常用的PDF生成方案为@react-pdf/renderer或jsPDF + html2canvas,以下逻辑对两种方案都兼容。

步骤1:批量生成多份PDF

首先维护选中项的状态,全选时将所有列表数据存入选中数组,复用单PDF生成逻辑遍历生成所有PDF文件:

// 假设你已经封装了单条数据生成PDF的方法,入参为单条列表项,返回PDF的Blob对象
import { generateSinglePdf } from './your-existing-pdf-util';

// 批量生成PDF方法
const generateAllSelectedPdfs = async (selectedList) => {
  const pdfTasks = selectedList.map(async (item) => {
    const pdfBlob = await generateSinglePdf(item);
    return {
      blob: pdfBlob,
      name: `report-${item.id}.pdf` // 自定义每份PDF的文件名
    }
  });
  // 等待所有PDF生成完成,返回Blob数组
  return Promise.all(pdfTasks);
};

如果你使用@react-pdf/renderer,generateSinglePdf的逻辑可以参考:

import { pdf } from '@react-pdf/renderer';
import SinglePdfTemplate from './SinglePdfTemplate'; // 你已有的单PDF组件

const generateSinglePdf = async (item) => {
  return pdf(<SinglePdfTemplate data={item} />).toBlob();
};

步骤2:实现一键打印功能

推荐使用合并PDF为单个文件后打印的方案,仅触发一次打印弹窗,用户体验更好,可规避浏览器拦截多次弹窗的问题:

import { PDFDocument } from 'pdf-lib'; // 用于合并PDF的依赖

// 合并多个PDF Blob为单个Blob
const mergePdfBlobs = async (pdfBlobList) => {
  const mergedPdf = await PDFDocument.create();
  for (const blob of pdfBlobList) {
    const pdfBytes = await blob.arrayBuffer();
    const currentPdf = await PDFDocument.load(pdfBytes);
    const pages = await mergedPdf.copyPages(currentPdf, currentPdf.getPageIndices());
    pages.forEach(page => mergedPdf.addPage(page));
  }
  const mergedBytes = await mergedPdf.save();
  return new Blob([mergedBytes], { type: 'application/pdf' });
};

// 一键打印入口方法
const handlePrintAll = async (selectedList) => {
  // 加loading状态的逻辑可以自行补充
  const pdfList = await generateAllSelectedPdfs(selectedList);
  const mergedPdfBlob = await mergePdfBlobs(pdfList.map(item => item.blob));
  
  // 触发打印
  const pdfUrl = URL.createObjectURL(mergedPdfBlob);
  const printWindow = window.open(pdfUrl, '_blank');
  
  printWindow.onload = () => {
    printWindow.print();
    // 打印完成后释放资源
    printWindow.onfocus = () => {
      URL.revokeObjectURL(pdfUrl);
      printWindow.close();
    };
  };
};

如果你不需要合并文件,也可以选择依次打印单份PDF,该方案会多次触发打印弹窗,仅适合小批量场景:

const handlePrintAllSequentially = async (selectedList) => {
  const pdfList = await generateAllSelectedPdfs(selectedList);
  for (const pdfItem of pdfList) {
    const pdfUrl = URL.createObjectURL(pdfItem.blob);
    const printWindow = window.open(pdfUrl, '_blank');
    // 等待当前PDF打印完成再处理下一份
    await new Promise(resolve => {
      printWindow.onload = () => {
        printWindow.print();
        printWindow.onfocus = () => {
          URL.revokeObjectURL(pdfUrl);
          printWindow.close();
          resolve();
        };
      };
    });
  }
};

注意事项

  • 数据量较大时建议添加loading状态和进度提示,避免用户误判页面卡顿
  • 必须调用URL.revokeObjectURL释放生成的临时URL,避免内存泄漏
  • 如果需要批量下载所有PDF,可以配合jszip将所有Blob打包为Zip文件下载

内容的提问来源于stack exchange,提问作者faysal neowaz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 16:45:04