0

I use pdfmake to generate pdf in nodejs and send the data to my angular request page. I can generate pdf. but my issue is when i download the pdf its name looks like "16064905-c4aa-4d40-96db-ca7464c38858.pdf".how can i set custom name to my .pdf file?

here is my code

pdfHandler.createPdfBinary(courseDetail, function(binary) {
    res.header('content-type', 'application/pdf');                                  
    res.send(binary);
}, function(error) {
    res.send('ERROR:' + error);
});

exports.createPdfBinary = function(courseDetail,callback) {
    var docDefinition = {...};
    var pdfDoc = printer.createPdfKitDocument(docDefinition);
    var chunks = [];
    var result;

    pdfDoc.on('data', function(chunk) {
        chunks.push(chunk);
    });

    pdfDoc.on('end', function() {
        result = Buffer.concat(chunks);
        callback(result);

    });

    pdfDoc.end();
}
Endless
  • 34,080
  • 13
  • 108
  • 131
MANJU MOHAN
  • 23
  • 1
  • 5

2 Answers2

0

inside your pdfDoc.on('end', function()

callback(null, result.toString('base64'));

When you receive result from callback add the following code and pass your result to method

inside your callback result

b64toBlob(result, 'application/pdf');

file download method

function b64toBlob(b64Data, contentType, sliceSize) {
  contentType = contentType || '';
  sliceSize = sliceSize || 512;

  var byteCharacters = atob(b64Data);
  var byteArrays = [];

  for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) {
    var slice = byteCharacters.slice(offset, offset + sliceSize);

    var byteNumbers = new Array(slice.length);
    for (var i = 0; i < slice.length; i++) {
      byteNumbers[i] = slice.charCodeAt(i);
    }

    var byteArray = new Uint8Array(byteNumbers);

    byteArrays.push(byteArray);
  }

  var blob = new Blob(byteArrays, {
    type: contentType
  });
  if (blob) {
    saveAs(blob, 'your_file_name.pdf'); /// TODO change with your filename
  } else {
    throw 'Could not generate blob';
  }
}

you need one more package to add in your code FileSaver

for more detail check out my GitHub example https://github.com/daupawar/MeteorAsyncPdfmake

Rohan Pawar
  • 1,875
  • 22
  • 40
0

I would have done it a lite bit more different. Btw Content-Disposition is what you can use to set a custom name for files

let fileName = 'sample.pdf'
let stream = pdfHandler.createPdfBinary(courseDetail)
res.header('Content-Type', 'application/pdf')
res.header('Content-Disposition', 'attachment; filename=' + fileName)
stream.pipe(res)

// instead of buffering all chunks and concatenating everything
// we simply just return the stream, so no callback is necessary
// ...this is also better for memory
exports.createPdfBinary = courseDetail => {
    var docDefinition = {...}
    return printer.createPdfKitDocument(docDefinition)
}
Endless
  • 34,080
  • 13
  • 108
  • 131