2

child_process を使用して wkhtmltopdf を実行し、html ドキュメントから PDF を作成しています。続行する前に、wkhtmltopdf がドキュメントの PDF への処理を完了するまで待ちたいと思います。wkhtmltopdf が完了シグナルを送信したときに stdout から読み取ってキャプチャすることがこれを行うための最良の方法だと思いますが、次のコードは res.send() で stdout が空であることを報告します。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();
    });
};
4

2 に答える 2

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
于 2012-06-20T00:55:46.743 に答える
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');
于 2015-02-23T23:45:22.750 に答える