在 NodeJS 中使用 PDFMake 下载 PDF 失败
PDF download fails using PDFMake in NodeJS
我向我的 NodeJS API 添加了一个端点,以便能够使用库 PDFMake 生成和下载 PDF。我能够在服务器端生成和上传 PDF,但在浏览器站点上,PDF 已下载并失败,上面有 0 KB,我试图为它找到解决方案。
我知道文件是在 writeStream
完成写入之前下载的,但添加了一个额外的功能,如:
pdf.on("finish", async () => {
res.download(pdf);
res.send("PDF generated");
});
这没有帮助,但增加了一个额外的错误:
UnhandledPromiseRejectionWarning: RangeError [ERR_HTTP_INVALID_STATUS_CODE]: Invalid status code: undefined
我不知道如何解决这个问题,希望得到帮助。很可能是我遗漏的东西。
负责这些功能的代码是:
路由器
router.get("/pdf/all", async (req, res) => {
const movies = await movie.getMovies();
try {
const pdf = await generatePdf(movies, "all");
pdf.on("finish", async () => {
res.download(pdf);
res.send("PDF generated");
});
} catch (err) {
// Errors
res.status(err.status).json({ message: err.message });
throw new Error(error.message);
}
});
生成PDF
const generatePdf = (movies, name) => {
return new Promise((resolve, reject) => {
try {
let fonts = {
Roboto: {
normal: "Helvetica",
bold: "Helvetica-Bold",
italics: "Helvetica-Oblique",
bolditalics: "Helvetica-BoldOblique"
}
};
let printer = new pdfMaker(fonts);
const pdfTemplate = template(movies);
const pdfStream = printer.createPdfKitDocument(pdfTemplate, {});
const filePath = path.join(
__dirname,
uploads + "/" + pdfDir + `${name}.pdf`
);
console.log(filePath);
pdfStream.pipe(writeStream(filePath));
pdfStream.end();
resolve(filePath);
} catch (err) {
console.log(err);
reject(err);
}
});
};
我建议您为 generatePdf
尝试以下代码:
const generatePdf = (movies, name) => {
return new Promise((resolve, reject) => {
try {
let fonts = {
Roboto: {
normal: "Helvetica",
bold: "Helvetica-Bold",
italics: "Helvetica-Oblique",
bolditalics: "Helvetica-BoldOblique"
}
};
let printer = new pdfMaker(fonts);
const pdfTemplate = template(movies);
const pdfStream = printer.createPdfKitDocument(pdfTemplate, {});
const filePath = path.join(
__dirname,
uploads + "/" + pdfDir + `${name}.pdf`
);
console.log(filePath);
let stream = pdfStream.pipe(writeStream(filePath));
stream.on('finish', function(){
pdfStream.end();
resolve(filePath);
}
} catch (err) {
console.log(err);
reject(err);
}
});
};
代码应该等待 pdfStream.pipe
完成文件和 resolving
filePath
此外,您不能在 res.download
之后使用 res.send
,因为下载会将响应设置为文件,您无法再向客户端发送另一个响应。
我向我的 NodeJS API 添加了一个端点,以便能够使用库 PDFMake 生成和下载 PDF。我能够在服务器端生成和上传 PDF,但在浏览器站点上,PDF 已下载并失败,上面有 0 KB,我试图为它找到解决方案。
我知道文件是在 writeStream
完成写入之前下载的,但添加了一个额外的功能,如:
pdf.on("finish", async () => {
res.download(pdf);
res.send("PDF generated");
});
这没有帮助,但增加了一个额外的错误:
UnhandledPromiseRejectionWarning: RangeError [ERR_HTTP_INVALID_STATUS_CODE]: Invalid status code: undefined
我不知道如何解决这个问题,希望得到帮助。很可能是我遗漏的东西。
负责这些功能的代码是: 路由器
router.get("/pdf/all", async (req, res) => {
const movies = await movie.getMovies();
try {
const pdf = await generatePdf(movies, "all");
pdf.on("finish", async () => {
res.download(pdf);
res.send("PDF generated");
});
} catch (err) {
// Errors
res.status(err.status).json({ message: err.message });
throw new Error(error.message);
}
});
生成PDF
const generatePdf = (movies, name) => {
return new Promise((resolve, reject) => {
try {
let fonts = {
Roboto: {
normal: "Helvetica",
bold: "Helvetica-Bold",
italics: "Helvetica-Oblique",
bolditalics: "Helvetica-BoldOblique"
}
};
let printer = new pdfMaker(fonts);
const pdfTemplate = template(movies);
const pdfStream = printer.createPdfKitDocument(pdfTemplate, {});
const filePath = path.join(
__dirname,
uploads + "/" + pdfDir + `${name}.pdf`
);
console.log(filePath);
pdfStream.pipe(writeStream(filePath));
pdfStream.end();
resolve(filePath);
} catch (err) {
console.log(err);
reject(err);
}
});
};
我建议您为 generatePdf
尝试以下代码:
const generatePdf = (movies, name) => {
return new Promise((resolve, reject) => {
try {
let fonts = {
Roboto: {
normal: "Helvetica",
bold: "Helvetica-Bold",
italics: "Helvetica-Oblique",
bolditalics: "Helvetica-BoldOblique"
}
};
let printer = new pdfMaker(fonts);
const pdfTemplate = template(movies);
const pdfStream = printer.createPdfKitDocument(pdfTemplate, {});
const filePath = path.join(
__dirname,
uploads + "/" + pdfDir + `${name}.pdf`
);
console.log(filePath);
let stream = pdfStream.pipe(writeStream(filePath));
stream.on('finish', function(){
pdfStream.end();
resolve(filePath);
}
} catch (err) {
console.log(err);
reject(err);
}
});
};
代码应该等待 pdfStream.pipe
完成文件和 resolving
filePath
此外,您不能在 res.download
之后使用 res.send
,因为下载会将响应设置为文件,您无法再向客户端发送另一个响应。