2012-06-20 5 views
2

child_process를 사용하여 wkhtmltopdf를 실행하여 html 문서에서 PDF를 작성합니다. 계속 진행하기 전에 wkhtmltopdf가 문서를 PDF로 처리 할 때까지 기다리고 싶습니다. wkhtmltopdf가 완료 신호를 보낼 때 stdout에서 읽는 것이 가장 좋은 방법이라고 생각하지만 다음 코드는 res.send()에서 stdout이 비어 있다고보고합니다. stdout에서 데이터를 제공 할 때 어떻게 이벤트를 발생시킬 수 있습니까?Node.js - 파일 쓰기가 완료 될 때까지 대기

코드 : 당신은 wkhtmltopdf를 잡았다가 발생했습니다

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

. 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 
+0

전혀이 경우 이유를 설명 할 수 있습니까? – Menztrual

+0

@tehlulz 다른 프로세스/파일 설명자 (예 :'wkhtmltopdf foo.html - | gzip> foo.gz')로 출력물을 파이프하는 동안 진행 상황을 볼 수 있도록하는 것이 좋습니다. –

+0

이 마법은 무엇입니까! : P – Menztrual

0

난 그냥 Heroku가에 Node.js를 통해 작업이 점점 완료 나는 작은 장애물의 몇 가지를 극복했다 이후 게시 싶었어요. Heroku가의 삼나무-14 스택에

// 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(); 

, 나는 표준 출력에 쓸 wkhtmltopdf를 가져올 수 없습니다. 서버는 항상 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'); 
관련 문제