Saltar al contenido

NodeJS: combine dos archivos PDF en uno usando el búfer obtenido al leerlos

Después de indagar en diferentes repositorios y páginas de internet al terminar hemos hallado la respuesta que te enseñaremos ahora.

Solución:

HummusJS admite la combinación de archivos PDF utilizando su método appendPDFPagesFromPDF

Ejemplo usando flujos para trabajar con búferes:

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);

Como mencionó @MechaCode, el creador ha dejado de admitir HummusJS.

Así que me gustaría darte 2 soluciones.

  1. Usando el módulo node-pdftk npm

    El siguiente código de ejemplo utiliza node-pdftk Módulo npm para combinar dos búferes de pdf sin problemas.

    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');
                    );
                );
            );
        );
    

    El requisito para el módulo node-pdftk npm es que necesita instalar la biblioteca PDFtk. Algunos de ustedes pueden encontrar esto sobrecargado / tedioso. Entonces tengo otra solución usando la biblioteca pdf-lib.

  2. Usando el módulo 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');
            ); 
        ); 
    ); 
    
    

Personalmente, prefiero usar el módulo pdf-lib npm.

Esto es lo que usamos en nuestro servidor Express para fusionar una lista de blobs en PDF.

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://stackoverflow.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,
;

Si conservas algún recelo o forma de arreglar nuestro enunciado eres capaz de realizar una ilustración y con mucho placer lo estudiaremos.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *