ReactJS中如何将react-pdf生成的PDF与本地上传的现有PDF合并
直接拼接ArrayBuffer的方式无法实现PDF合并:PDF是具备固定结构化格式的文件,包含文件头、页面索引、交叉引用表、文件尾等元信息,简单拼接二进制内容会破坏文件结构,导致PDF阅读器仅能识别到最后一份有效PDF的内容。
使用专门处理PDF的前端库pdf-lib即可实现需求,操作步骤如下:
步骤1:安装依赖
npm install @pdf-lib/core # 或使用yarn yarn add @pdf-lib/core
步骤2:修改合并逻辑代码
首先引入依赖:
import { PDFDocument } from '@pdf-lib/core'
修改按钮的点击事件逻辑:
const LazyDownloadPDFButton = (number, date, totalHours, formattedHours) => ( <Button className={classes.download} onClick={async () => { // 生成react-pdf的PDF内容 const doc = <InvoicePDF number={number} date={date} totalHours={totalHours} formattedHours={formattedHours} /> const asPdf = pdf() asPdf.updateContainer(doc) const generatedPdfBuffer = await (await asPdf.toBlob()).arrayBuffer() // 处理用户上传的PDF const selectedFile = fileRef.current?.files?.[0] // 无选中文件时直接下载生成的PDF if (!selectedFile) { const blob = await asPdf.toBlob() saveAs(blob, `PDF${number}.pdf`) return } const uploadPdfBuffer = await selectedFile.arrayBuffer() // 合并两个PDF const generatedPdfDoc = await PDFDocument.load(generatedPdfBuffer) const uploadPdfDoc = await PDFDocument.load(uploadPdfBuffer) const mergedPdfDoc = await PDFDocument.create() // 先加入上传PDF的所有页面 const uploadPages = await mergedPdfDoc.copyPages(uploadPdfDoc, uploadPdfDoc.getPageIndices()) uploadPages.forEach(page => mergedPdfDoc.addPage(page)) // 再加入react-pdf生成的PDF的所有页面,调换顺序可调整合并后页面排布 const generatedPages = await mergedPdfDoc.copyPages(generatedPdfDoc, generatedPdfDoc.getPageIndices()) generatedPages.forEach(page => mergedPdfDoc.addPage(page)) // 导出合并后的PDF并下载 const mergedPdfUint8 = await mergedPdfDoc.save() const finalBlob = new Blob([mergedPdfUint8], { type: 'application/pdf' }) saveAs(finalBlob, `PDF${number}.pdf`) }} > Download </Button> )
优化建议
- 在文件选择input中添加
accept=".pdf"属性,限制用户仅能选择PDF文件,避免格式错误:
<input ref={fileRef} type='file' accept=".pdf" style={{ display: 'none' }} />
- 可添加异常捕获逻辑,处理PDF加载、合并过程中可能出现的错误。
内容的提问来源于stack exchange,提问作者poPaTheGuru
相关产品推荐
相关产品推荐

