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

4
我正在使用pdfmake库在我的Node Express应用程序中生成PDF文档,并希望将这些文档直接发送回客户端,以触发浏览器自动下载文件。
作为参考,我一直在使用以下示例来编写我的Express中间件:

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

}

在我的Angular应用程序中,我正在使用$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编码的文档字符串时才相关。

有人能建议我的问题可能是什么吗?

谢谢


我实际上找到了一种方法,但是我不得不利用phantomjs的pdf功能。 - Akinjide
3个回答

4
这里有一个路由器:
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);
  }});
};

0

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

请参考CodePen

在这里,我使用的是base64编码的数据,但是您也可以使用二进制数据,只需要不要忘记更改href,其中我提到scope.dataURL = base64....


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)
})

我宁愿知道为什么我的当前解决方案不起作用,而不是必须使用另一个库。 - mindparse
这只是一个建议。 - Akinjide

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接