我正在使用child_process运行wkhtmltopdf来从html文档构建PDF。我想等到wkhtmltopdf在我继续之前将文档处理成PDF格式。我认为当wkhtmltopdf发送完成信号时从stdout读取捕获是最好的方法,但是下面的代码报告stdout在res.send()时是空的。当stdout为我提供数据时,如何设置要触发的事件?
代码:
var buildPdf = function(error){
var pdfLetter;
var child = exec('wkhtmltopdf temp.html compensation.pdf', function(error, stdout, stderr) {
if (error)
res.send({
err:error.message
});
else
res.send({
output : stdout.toString()
});
// sendEmail();
});
};
答案 0 :(得分:4)
你遇到了一个wkhtmltopdf陷阱。它不会将状态信息写入STDOUT,而是将其写入STDERR。
$ node -e \
"require('child_process').exec( \
'wkhtmltopdf http://stackoverflow.com/ foo.pdf', \
function(err, stdout, stderr) { process.stdout.write( stderr ); } );"
Loading pages (1/6)
content-type missing in HTTP POST, defaulting to application/octet-stream
Counting pages (2/6)
Resolving links (4/6)
Loading headers and footers (5/6)
Printing pages (6/6)
Done
答案 1 :(得分:0)
我刚刚通过Heroku上的Node.js完成了这项工作,并希望发布,因为我必须克服几个小障碍。
// Spin up a new child_process to handle wkhtmltopdf.
var spawn = require('child_process').spawn;
// stdin/stdout, but see below for writing to tmp storage.
wkhtmltopdf = spawn('./path/to/wkhtmltopdf', ['-', '-']);
// Capture stdout (the generated PDF contents) and append it to the response.
wkhtmltopdf.stdout.on('data', function (data) {
res.write(data);
});
// On process exit, determine proper response depending on the code.
wkhtmltopdf.on('close', function (code) {
if (code === 0) {
res.end();
} else {
res.status(500).send('Super helpful explanation.');
}
});
res.header('Content-Type', 'application/octet-stream');
res.header('Content-Disposition', 'attachment; filename=some_file.pdf');
res.header('Expires', '0');
res.header('Cache-Control', 'must-revalidate, post-check=0, pre-check=0');
// Write some markup to wkhtmltopdf and then end the process. The .on
// event above will be triggered and the response will get sent to the user.
wkhtmltopdf.stdin.write(some_markup);
wkhtmltopdf.stdin.end();
在Heroku的Cedar-14堆栈上,我无法通过wkhtmltopdf写入stdout。服务器始终以Unable to write to destination
回复。诀窍是写入./.tmp
然后将写入的文件流回给用户 - 很简单:
wkhtmltopdf = spawn('./path/to/wkhtmltopdf', ['-', './.tmp/some_file.pdf']);
wkhtmltopdf.on('close', function (code) {
if (code === 0) {
// Stream the file.
fs.readFile('./.tmp/some_file.pdf', function(err, data) {
res.header('Content-Type', 'application/octet-stream');
res.header('Content-Disposition', 'attachment; filename=' + filename);
res.header('Expires', '0');
res.header('Cache-Control', 'must-revalidate, post-check=0, pre-check=0');
res.send(data);
});
} else {
res.status(500).send('Super helpful explanation.');
}
});
res.header('Content-Type', 'application/octet-stream');
res.header('Content-Disposition', 'attachment; filename=' + filename);
res.header('Expires', '0');
res.header('Cache-Control', 'must-revalidate, post-check=0, pre-check=0');