2

I used this module on Nodejs : https://github.com/bpampuch/pdfmake

Here is my code to create it :

    const fonts = {
    Roboto: {
        normal: './fonts/Roboto-Regular.ttf',
        bold: './fonts/Roboto-Medium.ttf',
        italics: './fonts/Roboto-Italic.ttf',
        bolditalics: './fonts/Roboto-Italic.ttf'
    }
};

let PdfPrinter = require('pdfmake/src/printer');
let printer = new PdfPrinter(fonts);
let fs = require('fs');


module.exports.generateFile = function (data,callback) {

    let fileName = "Logins_" + data[0]["userLogin"] + ".pdf";
    let filePath = __dirname + "/files/" + fileName;

    let logins = [ ['userLogin', 'softwarePassword', 'softwareName'] ];
    for (let obj of data) {
        let arr = [];
        for(let x in obj){
            arr.push(obj[x]);
        }
        logins.push(arr);
    }

    let docDefinition = {
        content: [
            {
                table: {
                    // headers are automatically repeated if the table spans over multiple pages
                    // you can declare how many rows should be treated as headers
                    headerRows: 1,
                    widths: [ '*', 'auto', 100, '*' ],

                    body: logins
                }
            }
        ]
    };

    try {

        let chunks = [];
        let result;

        let doc = printer.createPdfKitDocument(docDefinition);
        doc.pipe(fs.createWriteStream(filePath));
        doc.end();
        callback(null,fileName,filePath)
    } catch (err){
        callback(err);
    }
    };

I got this screen :

Any ideas guys ? In the callback, I use res.download with the filename and the filepath. I tried everything

enter image description here

jy95
  • 773
  • 13
  • 36

2 Answers2

5

Working solution tested on local and node server

Why pdfmake cannot open file is because the file stream fs is still writing to the memory block, which makes it unreadable and the downloaded PDF would be corrupted with size of 0KB.

Solution: Add an event listener to the fs.createWriteSteam and wait for fs to finish writing then send file.

var temp123;
pdfDoc.pipe(temp123 = fs.createWriteStream('./PDF/' + name), { encoding:'utf16' });

pdfDoc.end();

temp123.on('finish', async function () {
  // do send PDF file 
  res.download('name.pdf');
});
Mike
  • 14,010
  • 29
  • 101
  • 161
Marcia Ong
  • 781
  • 8
  • 15
0

Anyone still having this issue. Thanks to Nikhil Nanjappa's article I've used this snippet on a NextJs project where I generated pdf on the server-side. Works like a charm!

const pdfMakePrinter = require('pdfmake/src/printer');
const fs = require('fs');

function generatePdf(docDefinition, successCallback, errorCallback) => {
  try {
    const fontDescriptors = { ... };
    const printer = new pdfMakePrinter(fontDescriptors);
    const doc = printer.createPdfKitDocument(docDefinition);

    doc.pipe(
      fs.createWriteStream('docs/filename.pdf').on("error", (err) => {
        errorCallback(err.message);
      })
    );

    doc.on('end', () => {
      successCallback("PDF successfully created and stored");
    });
    
    doc.end();
    
  } catch(err) {
    throw(err);
  }
};