使用pdfMake通过Node Express将PDF内容提供回浏览器

时间:2017-02-21 16:35:07

标签: angularjs node.js pdfmake

我正在使用pdfmake库在我的node express应用程序中生成PDF文档,并希望将这些文件直接发送回客户端以触发浏览器自动下载文件。

作为参考点,我一直在使用以下示例作为我的快速中间件:

https://gist.github.com/w33ble/38c5e0220d491148de1c https://github.com/bpampuch/pdfmake/issues/489

我已选择发回缓冲响应,因此我的中间件的关键部分如下所示:

function createPDFDocument(docDefinition, callback) {
  var fontDescriptors = {
    Roboto: {
      normal: './src/server/fonts/Roboto-Regular.ttf',
      bold: './src/server/fonts/Roboto-Medium.ttf',
      italics: './src/server/fonts/Roboto-Italic.ttf',
      bolditalics: './src/server/fonts/Roboto-MediumItalic.ttf'
    }
  };

  var printer = new Printer(fontDescriptors);
  var pdfDoc = printer.createPdfKitDocument(docDefinition);

  // buffer the output
  var chunks = [];

  pdfDoc.on('data', function(chunk) {
    chunks.push(chunk);
  });
  pdfDoc.on('end', function() {
    var result = Buffer.concat(chunks);
    callback(result);
  });
  pdfDoc.on('error', callback);

  // close the stream
  pdfDoc.end();

}

在我的角度应用程序中,我使用的是$ resource服务,其端点定义如下:

this.resource = $resource('api/document-requests/',
    null,
    <any>{
        'save': {
            method: 'POST',
            responseType: 'arraybuffer'
        }
});

当我尝试这个时,我没有得到任何浏览器下载,我在Chrome浏览器中收到的回复如下:

enter image description here

响应标题如下:

enter image description here

所以看起来我不是一百万英里,我已经四处搜索并找到了提及转换为Blob的解决方案,但我认为只有当我回复文档的Base64编码字符串时才有意义。

有人可以在这里建议我的问题吗?

由于

3 个答案:

答案 0 :(得分:2)

这是路由器:

router.get('/get-pdf-doc', async (req, res, next)=>{ try {
    var binaryResult = await createPdf();
    res.contentType('application/pdf').send(binaryResult);
} catch(err){
    saveError(err);
    res.send('<h2>There was an error displaying the PDF document.
      '</h2>Error message: ' + err.message);
}});

这是一个返回pdf的函数。

const PdfPrinter = require('pdfmake');
const Promise = require("bluebird");

createPdf = async ()=>{
  var fonts = {
    Helvetica: {
        normal: 'Helvetica',
        bold: 'Helvetica-Bold',
        italics: 'Helvetica-Oblique',
        bolditalics: 'Helvetica-BoldOblique'
  };
  var printer = new PdfPrinter(fonts);
  var docDefinition = {
    content: [
        'First paragraph',
        'Another paragraph, this time a little bit longer to make sure,'+ 
           ' this line will be divided into at least two lines'
    ],
    defaultStyle: {
        font: 'Helvetica'
    }
  };
  var pdfDoc = printer.createPdfKitDocument(docDefinition);

  return new Promise((resolve, reject) =>{ try {
    var chunks = [];
    pdfDoc.on('data', chunk => chunks.push(chunk));
    pdfDoc.on('end', () => resolve(Buffer.concat(chunks)));
    pdfDoc.end();
  } catch(err) {
    reject(err);
  }});
};

答案 1 :(得分:0)

对我来说似乎一切都很好,唯一缺少的是触发下载的逻辑。

请查看此CodePen作为示例。

我在这里使用base64编码数据,但你也可以使用二进制数据,不要忘记更改href,我提到{{1} }}

答案 2 :(得分:0)

我也有问题从Node.js提供PDF文件,所以我使用了phantomjs。您可以查看此repository以获取完整的代码库和实施。

console.log('Loading web page')

const page = require('webpage').create()
const args = require('system').args
const url = 'www.google.com'

page.viewportSize = { width: 1024, height: 768 }
page.clipRect = { top: 0, left: 0 }

page.open(url, function(status) {
  console.log('Page loaded')

  setTimeout(function() {
    page.render('docs/' + args[1] + '.pdf')
    console.log('Page rendered')
    phantom.exit()
  }, 10000)
})