Node.js使用pdf-lib下载合并PDF出现空白页问题求助
解决Node.js中使用pdf-lib合并PDF后页面空白的问题
问题根源
空白页的核心原因是axios默认会将二进制响应转换为UTF-8字符串,这会直接破坏PDF的二进制结构——即使后续转成Buffer,原始数据已经损坏,导致pdf-lib无法正确解析页面内容。流下载正常是因为流直接处理原始二进制数据,没有经过字符串转换环节。
解决方案
1. 确保axios请求正确获取二进制数据
必须在axios配置中显式设置responseType: 'arraybuffer',同时确认你的httpRequestService.createAxiosConfigAndSend不会覆盖这个配置(比如部分封装会默认设置responseType: 'json',需要保证传入的配置能覆盖默认值)。
修改下载函数:
async function downloadPdfBuffer(url) { logger.info({message: 'downloadPdfBuffer PDF', url}); try { const response = await httpRequestService.createAxiosConfigAndSend({ method: 'GET', url: url, responseType: 'arraybuffer' // 关键:强制获取二进制数组 }); return response.data; // 直接返回ArrayBuffer,无需额外转换 } catch (error) { logger.error({message: 'Error downloading PDF:', error}); throw error; } };
2. 正确加载PDF到pdf-lib
拿到ArrayBuffer后,直接用Buffer.from()转换为Node.js Buffer即可(pdf-lib支持ArrayBuffer或Buffer作为输入),不要指定'binary'编码——指定编码会让Buffer尝试用字符串逻辑解析数据,再次损坏二进制内容。
修改合并逻辑中的加载部分:
const mergedPdfPromises = settledPromises.map(async result => { if(result.status === 'fulfilled'){ const pdfBuffer = Buffer.from(result.value); const pdf = await PDFDocument.load(pdfBuffer, {ignoreEncryption:true}); const copiedPages = await mergedPdf.copyPages(pdf, pdf.getPageIndices()); copiedPages.forEach(page => mergedPdf.addPage(page)); } })
3. 完整修正后的合并函数
async function downloadAndmergePdf(pdfLinks){ const maxTwoPdfs = _.slice(pdfLinks,0,2); const allPdfs = maxTwoPdfs.map(pdfLink => downloadPdfBuffer(pdfLink)); const settledPromises = await Promise.allSettled(allPdfs); const mergedPdf = await PDFDocument.create(); const mergedPdfPromises = settledPromises.map(async result => { if(result.status === 'fulfilled'){ const pdfBuffer = Buffer.from(result.value); const pdf = await PDFDocument.load(pdfBuffer, {ignoreEncryption:true}); const copiedPages = await mergedPdf.copyPages(pdf, pdf.getPageIndices()); copiedPages.forEach(page => mergedPdf.addPage(page)); } }); await Promise.all(mergedPdfPromises); const buf = await mergedPdf.save(); fs.writeFileSync('new.pdf', buf); } downloadAndmergePdf([ 'https://www.adobe.com/support/products/enterprise/knowledgecenter/media/c4611_sample_explain.pdf', 'https://www.adobe.com/support/products/enterprise/knowledgecenter/media/c4611_sample_explain.pdf' ]);
额外检查点
- 排查
httpRequestService.createAxiosConfigAndSend内部逻辑,确保它没有修改或忽略传入的responseType配置。 - 全程避免对PDF二进制数据进行任何字符串转换操作(比如转base64再转回、调用
toString('binary')等),直接处理ArrayBuffer/Buffer即可。
内容的提问来源于stack exchange,提问作者Namit Piriya
相关产品推荐
相关产品推荐

