NodeJS:使用读取它们获得的缓冲区将两个PDF文件合并为一个
Posted
技术标签:
【中文标题】NodeJS:使用读取它们获得的缓冲区将两个PDF文件合并为一个【英文标题】:NodeJS: Merge two PDF files into one using the buffer obtained by reading them 【发布时间】:2016-08-14 10:56:41 【问题描述】:我正在使用 fill-pdf npm 模块来填充模板 pdf,它会创建从磁盘读取并作为缓冲区返回给回调的新文件。我有两个文件,我对其执行相同的操作。我想在那里合并两个缓冲区以形成一个可以发送回客户端的 pdf 文件。我尝试了不同的缓冲区连接方法。可以使用 Buffer.concat 连接缓冲区,例如,
var newBuffer = Buffer.concat([result_pdf.output, result_pdf_new.output]);
新缓冲区的大小也是输入缓冲区大小的总和。但是当newBuffer
作为响应发送给客户端时,它仍然只显示数组中最后提到的文件。
res.type("application/pdf");
return res.send(buffer);
有什么想法吗?
【问题讨论】:
Merging PDFs in Node的可能重复 【参考方案1】:正如@MechaCode 所述,创建者已停止支持HummusJS
。
所以我想给你两个解决方案。
使用node-pdftk npm 模块
以下示例代码使用node-pdftk
npm 模块进行组合
两个 pdf 缓冲区无缝衔接。
const pdftk = require('node-pdftk');
var pdfBuffer1 = fs.readFileSync("./pdf1.pdf");
var pdfBuffer2 = fs.readFileSync("./pdf2.pdf");
pdftk
.input([pdfBuffer1, pdfBuffer2])
.output()
.then(buf =>
let path = 'merged.pdf';
fs.open(path, 'w', function (err, fd)
fs.write(fd, buf, 0, buf.length, null, function (err)
fs.close(fd, function ()
console.log('wrote the file successfully');
);
);
);
);
node-pdftk npm 模块的要求是你需要安装 PDFtk 库。你们中的一些人可能会发现这种开销/乏味。所以我有另一个使用 pdf-lib 库的解决方案。
使用pdf-lib npm 模块
const PDFDocument = require('pdf-lib').PDFDocument
var pdfBuffer1 = fs.readFileSync("./pdf1.pdf");
var pdfBuffer2 = fs.readFileSync("./pdf2.pdf");
var pdfsToMerge = [pdfBuffer1, pdfBuffer2]
const mergedPdf = await PDFDocument.create();
for (const pdfBytes of pdfsToMerge)
const pdf = await PDFDocument.load(pdfBytes);
const copiedPages = await mergedPdf.copyPages(pdf, pdf.getPageIndices());
copiedPages.forEach((page) =>
mergedPdf.addPage(page);
);
const buf = await mergedPdf.save(); // Uint8Array
let path = 'merged.pdf';
fs.open(path, 'w', function (err, fd)
fs.write(fd, buf, 0, buf.length, null, function (err)
fs.close(fd, function ()
console.log('wrote the file successfully');
);
);
);
我个人更喜欢使用 pdf-lib npm 模块。
【讨论】:
谢谢! pdf-lib 很棒 可以说这是使用 PDF-LIB 的更好示例github.com/Hopding/pdf-lib#copy-pages【参考方案2】:这是我们在 Express 服务器中用于合并 PDF blob 列表的内容。
const PDFRStreamForBuffer, createWriterToModify, PDFStreamForResponse = require('hummus');
const WritableStream = require('memory-streams');
// Merge the pages of the pdfBlobs (javascript buffers) into a single PDF blob
const mergePdfs = pdfBlobs =>
if (pdfBlobs.length === 0) throw new Error('mergePdfs called with empty list of PDF blobs');
// This optimization is not necessary, but it avoids the churn down below
if (pdfBlobs.length === 1) return pdfBlobs[0];
// Adapted from: https://***.com/questions/36766234/nodejs-merge-two-pdf-files-into-one-using-the-buffer-obtained-by-reading-them?answertab=active#tab-top
// Hummus is useful, but with poor interfaces -- E.g. createWriterToModify shouldn't require any PDF stream
// And Hummus has many Issues: https://github.com/galkahana/HummusJS/issues
const [firstPdfRStream, ...restPdfRStreams] = pdfBlobs.map(pdfBlob => new PDFRStreamForBuffer(pdfBlob));
const outStream = new WritableStream();
const pdfWriter = createWriterToModify(firstPdfRStream, new PDFStreamForResponse(outStream));
restPdfRStreams.forEach(pdfRStream => pdfWriter.appendPDFPagesFromPDF(pdfRStream));
pdfWriter.end();
outStream.end();
return outStream.toBuffer();
;
module.exports = exports =
mergePdfs,
;
【讨论】:
hummusJs 现在不受创建者支持。【参考方案3】:HummusJS 支持使用 appendPDFPagesFromPDF 方法合并 PDF
使用流处理缓冲区的示例:
const hummus = require('hummus');
const memoryStreams = require('memory-streams');
/**
* Concatenate two PDFs in Buffers
* @param Buffer firstBuffer
* @param Buffer secondBuffer
* @returns Buffer - a Buffer containing the concactenated PDFs
*/
const combinePDFBuffers = (firstBuffer, secondBuffer) =>
var outStream = new memoryStreams.WritableStream();
try
var firstPDFStream = new hummus.PDFRStreamForBuffer(firstBuffer);
var secondPDFStream = new hummus.PDFRStreamForBuffer(secondBuffer);
var pdfWriter = hummus.createWriterToModify(firstPDFStream, new hummus.PDFStreamForResponse(outStream));
pdfWriter.appendPDFPagesFromPDF(secondPDFStream);
pdfWriter.end();
var newBuffer = outStream.toBuffer();
outStream.end();
return newBuffer;
catch(e)
outStream.end();
throw new Error('Error during PDF combination: ' + e.message);
;
combinePDFBuffers(PDFBuffer1, PDFBuffer2);
【讨论】:
请使用,PDFBuffer1、PDFBuffer2的类型是什么 @M.Abulsoud 他们都是Buffers 填充了二进制 PDF 数据。就我而言,我使用 Puppeteer 的 page.pdf() 方法创建了缓冲区 以下是作者合并pdf的示例:github.com/galkahana/HummusJS/blob/master/tests/… 我正在尝试在 React 组件中使用它,但这似乎是不可能的。我错过了什么? @ZachEsposito Puppeteer 的 page.pdf() 返回一个缓冲区以上是关于NodeJS:使用读取它们获得的缓冲区将两个PDF文件合并为一个的主要内容,如果未能解决你的问题,请参考以下文章