OS: ubuntu 20.04 Nodejs: 14.18.3 npm: 6.14.15 pdfMake: 0.1.72 (for create pdf files from a file or db queries)
Currently, I try make a pdf from a file (it could be a db query) and I want to send it to the client through stream. Send chunks of data to the users to avoid buffering the server's ram.
I've already send it to the user, but it takes to much time to download a 300kb pdf, almost 15 secs.
I've seem that every chunk received in the client is 16kb, that is the unchangeable (I think) sizes of the res object.
I use a readable stream coming from pdfMake library and try to pipe into the res object (express).
Here is the creation of the file (pdfMake library)
let bigfile = fs.readFileSync('./bigfile.txt', 'utf8');
function docDefinition() {
let content = [{
text: 'This is a header',
alignment: 'center',
fontSize: 25,
margin: [0,0,0,0]
}]
content.push({ text: bigfile })
let docDefinition = {
content: content
}
return docDefinition
}
Here, I generate the row pdf itself "as a readable stream" and pass it to my express route in a callback
const generatePdf = (docDefinition, callback) => {
try {
const fontDescriptors = {
Roboto: {
normal: path.join(__dirname, '/fonts/Roboto-Regular.ttf'),
bold: path.join(__dirname, '/fonts/Roboto-Medium.ttf'),
italics: path.join(__dirname, '/fonts/Roboto-Italic.ttf'),
bolditalics: path.join(__dirname, '/fonts/Roboto-MediumItalic.ttf'),
},
};
const printer = new pdfMakePrinter(fontDescriptors);
const doc = printer.createPdfKitDocument(docDefinition);
/* something to add, **const = doc** has its own event for streaming (I guess)
doc.on('data', chunk => {
// send current chunk to client somehow
})
doc.on('end', chunk => {
// finished the streaming
})
*/
callback(doc)
} catch (error) {
throw error;
}
}
My main server.js, were I try to send the pdf to the user in a chuncked transafer way
app.get('/file', (req, res) => {
generatePdf(
docDefinition,
readable => {
res.set({
"Content-Type": "application/pdf",
"Transfer-Encoding": "chunked",
"Connection": "keep-alive"
});
console.log('res.HighWaterMark', res.writableHighWaterMark);
console.log('readable highWaterMark', readable._readableState.highWaterMark);
readable.pipe(res)
readable.end()
})
})
I just try to streaming a video in my browser and It was very easy cos the fs internal module. But here I using a external library (pdfmake) to make my readable stream. I'm very beginner with streams in node. I very appreciate any suggestion o help with that particular problem. :S
The source code could be fund here: https://github.com/biagiola/streamPDFtoClient