I'm trying to convert information from the database to a pdf, that the user can download from my website. I'm new to nodejs and I'm currently changing somethings on an already developed website. The goal is for the user to press a button and download a pdf document. That document should be populated with the information in the database regarding a particular entry on the website.
I'm getting the error "Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client" and don't understand why or how to solve.
"use strict";
let express = require('express'),
router = express.Router(),
asyncMiddleware = require('../utils/asyncMiddleware'),
auth = require('../middleware/authentication'),
// pdf = require('html-pdf'),
blobStream = require('blob-stream'),
pdf = require('pdfkit'),
juice = require('juice'),
{User, Report} = require('../models');
router.get('/:reportId?', auth.isLoggedIn, asyncMiddleware( async(req, res) => {
let reqUser = req.user;
//get the report
let report = await Report.findById( req.params.reportId ).populate('ownerManagerId');
if( !report ) {
req.flash('error', req.__('flash.error.reportNotFound') );
return res.redirect('back');
}
//check if user on the request is the user of the report or is the group admin stored when the report was generated
if( !reqUser._id.equals(report.ownerId) && !reqUser._id.equals(report.ownerManagerId) && req.user.role !=="admin" ){
req.flash('error', req.__('flash.error.forbiddenAccess') );
return res.redirect('back');
}
//report data
let data = {
layout: 'pdf_layout',
styles: [],
scripts: [],
user: reqUser,
lang: req.lang,
pageTitle: req.__('pageTitle-calculator-report'),
reportOwnerManager: report.ownerManagerId,
reportDate: formatDateInReport( report.createdAt ),
calcData: report.inputs,
output: report.outputs
}
//add some helper functions to ejs views
res.locals.formatNum = formatNum;
res.locals.findInputCorr = findInputCorr;
res.render('calculadora/relatorioPdf', data, (err1, html)=>{
//set headers so the file is downloaded instead of shown in browser
const stream = res.writeHead(200, {
'Content-Type': 'application/pdf',
'Content-disposition': `attachment; filename=relatorio-${report.id}.pdf`
});
buildPDF(
(chunk) => stream.write(chunk),
() => stream.end()
);
function buildPDF() {
const doc = new pdf();
doc.on('data', dataCallback);
doc.end('data', endCallback);
doc.pipe(res);
doc.end();
}
});//render
}))//get
Thank you
I realized that pdfkit was not able to stream the html response to a pdf file and download it.
I used wkhtmltopdf instead, successfully.