我正在疯狂地尝试修复这个错误,所以请帮忙:-) 我正在使用 https://pdfkit.org/
这将创建一个流,完成后将通过管道传输到 fs.createWriteStream
我的问题是代码第一次运行并生成 PDF。 下次代码运行时将创建一个零字节的文件。 我正在从 Express 上运行的 API 调用该函数。 问题似乎是 fs.createWriteStream 的异步性质。 API 返回后流结束。我似乎无法找到一种方法来阻止同时确认文件已创建。
奇怪的是,代码第一次运行再次运行时失败了:
这是管道函数;
async function _writeFile(fileObj) {
let fileStream = fs.createWriteStream(fileObj.fileName)
pipeline(
doc,
fileStream,
async (err) => {
if (err) {
console.error('PDF failed', err);
return ('Pipeline failed', err)
} else {
console.log('PDF succeeded');
}
}
)
}
这是从以下地方调用的:
exports.drawReport = async (payload) => {
var date = new Date();
const timeStamp = date.toJSON();
let path = './controllers/tmp/'
var fileName = path + timeStamp + '.' + payload.type + '.pdf'
try {
// Start Report
await _startReport(payload)
// Check Starting position on page & add status box header
if (device_card_reference == 260) {
await _deviceTitle(payload);
}
// Add Devices
await _reportDevice(payload);
// Call Footer for final page
await _reportFooter()
console.log("PDF Done - Writing File")
// File Meta Data
let fileObj = {
type: payload.type,
siteId: payload.siteId,
fileName: fileName,
timeStamp: timeStamp
}
// Create file to store PDF
await _writeFile(fileObj)
doc.end()
console.log("PDF MADE?")
return (fileObj)
} catch (err) {
console.error('MakePDF ERROR: ' + err.message);
return (err.message)
}
}
pipeline
异步运行,因此不会等待,这就是为什么 doc.end()
在文件完成之前运行
尝试将
pipeline
包装在 Promise 中,然后在流完成时解析:
// function that returns a promise
function _writeFile(fileObj) {
return new Promise((resolve, reject) => {
const fileStream = fs.createWriteStream(fileObj.fileName);
pipeline(
doc,
fileStream,
async(err) => {
if (err) {
console.error('PDF failed', err);
// err, handle in `.catch`
reject({res:'Pipeline failed', err});
} else {
console.log('PDF succeeded');
// done, resolve, to move to doc.end
resolve('PDF succeeded');
}
}
)
});
}
添加
.catch()
来处理错误:
// Create file to store PDF
await _writeFile(fileObj).catch(err => console.log(err));
或者更好的是,使用 stream Promise API
const {pipeline } = require('stream/promises');
async function _writeFile(fileObj) {
const fileStream = fs.createWriteStream(fileObj.fileName);
await pipeline(doc, fileStream);
console.log('PDF succeeded');
}