前端合并多个PDF blob后仅显示第一页的问题如何解决
问题原因
PDF是具备严格结构化格式的二进制文件,每个独立的PDF文件都包含独有的文件头、页对象树、交叉引用表、文件尾标记。你当前直接将多个PDF的Blob拼接为一个新Blob的操作,只会把多份PDF的二进制数据简单堆叠,PDF阅读器解析时只会识别第一份PDF的完整结构,后续拼接的内容会被判定为无效冗余数据,因此只会显示第一份PDF的内容。
修复方案
你可以借助前端PDF处理库pdf-lib完成PDF的页级合并,改造后的代码逻辑如下:
首先在项目中引入pdf-lib依赖,如果是Node.js/npm项目可直接执行安装命令:
npm install pdf-lib
改造后的downloadAll函数代码:
import { PDFDocument } from 'pdf-lib' async downloadAll() { const cals = this.state.calibrations // 批量下载所有PDF的ArrayBuffer数据 const pdfBuffers = await Promise.all(cals.map(async (cal) => { try { const res = await fetch(api_url + this.state.user.company + '/blobs/' + cal.blob_id + '/download', { headers: { Authorization: this.state.auth_token } }) return await res.arrayBuffer() } catch (e) { console.log(e) return null } })) // 过滤掉下载失败的空数据 const validPdfs = pdfBuffers.filter(buf => buf !== null) if (validPdfs.length === 0) return // 创建新的空白PDF文档 const mergedPdf = await PDFDocument.create() for (const pdfBuf of validPdfs) { // 加载单个PDF文档 const singlePdf = await PDFDocument.load(pdfBuf) // 拷贝当前PDF的所有页到合并文档 const pages = await mergedPdf.copyPages(singlePdf, singlePdf.getPageIndices()) pages.forEach(page => mergedPdf.addPage(page)) } // 序列化合并后的PDF为二进制数据 const mergedPdfBytes = await mergedPdf.save() // 转Blob并打开新标签页 const blob = new Blob([mergedPdfBytes], { type: 'application/pdf' }) window.open(URL.createObjectURL(blob), '_blank') }
注:上述代码将你原来的计数器异步等待逻辑替换为更稳妥的
Promise.all写法,无需手动维护计数判断所有下载任务是否完成。
内容的提问来源于stack exchange,提问作者ekinser
相关产品推荐
相关产品推荐

