javascript - Koa中如何发送生成的文件

标签 javascript pdf stream koa

我需要制作一个包含用户内容的 pdf 文件并将其发回。我选择了 pdfmake,因为这样就可以制作表格了。 我使用 Koa.js;

router.post('/pdf', koaBody(), async ctx => {
      const doc = printer.createPdfKitDocument(myFunctionGeneratePDFBody(ctx.request.body));
      doc.pipe(ctx.res, { end: false });
      doc.end();
      ctx.res.writeHead(200, {
        'Content-Type': 'application/pdf',
        "Content-Disposition": "attachment; filename=document.pdf",
      });
      ctx.res.end();
    });

并出现错误

Error [ERR_STREAM_WRITE_AFTER_END]: write after end
        at write_ (_http_outgoing.js:572:17)
        at ServerResponse.write (_http_outgoing.js:567:10)
        at PDFDocument.ondata (_stream_readable.js:666:20)
        at PDFDocument.emit (events.js:182:13)
        at PDFDocument.EventEmitter.emit (domain.js:442:20)
        at PDFDocument.Readable.read (_stream_readable.js:486:10)
        at flow (_stream_readable.js:922:34)
        at resume_ (_stream_readable.js:904:3)
        at process._tickCallback (internal/process/next_tick.js:63:19)

但是保存在中间文件中并发送其工作...

router.post('/pdf', koaBody(), async ctx => {
  await new Promise((resolve, reject) => {
    const doc = printer.createPdfKitDocument(generatePDF(ctx.request.body));
    doc.pipe(fs.createWriteStream(__dirname + '/document.pdf'));
    doc.end();
    doc.on('error', reject);
    doc.on('end', resolve);
  })
    .then(async () => {
      ctx.res.writeHead(200, {
        'Content-Type': 'application/pdf',
        'Content-Disposition': 'attachment; filename=document.pdf',
      });
      const stream = fs.createReadStream(__dirname + '/document.pdf');
      return new Promise((resolve, reject) => {
        stream.pipe(ctx.res, { end: false });
        stream.on('error', reject);
        stream.on('end', resolve);
      });
    });
  ctx.res.end();
});

最佳答案

我刚刚遇到了同样的问题,你的问题帮助了我,我已经解决了这个问题:你正在立即结束响应/流,而它还没有完全写完。问题是 doc.end() 在写入完成之前立即返回。诀窍是让您的文档在完成后结束流(这样就不再 end: false)并等待此事件,例如使用 Promise。

固定代码如下所示:

router.post('/pdf', koaBody(), async ctx => {
      const doc = printer.createPdfKitDocument(myFunctionGeneratePDFBody(ctx.request.body));
      doc.pipe(ctx.res);
      doc.end();
      ctx.res.writeHead(200, {
        'Content-Type': 'application/pdf',
        "Content-Disposition": "attachment; filename=document.pdf",
      });
      return new Promise(resolve => ctx.res.on('finish', resolve));
    });

关于javascript - Koa中如何发送生成的文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54362004/

相关文章:

java - 从 Itext PDF 字节数组转换为多页 TIFF 文件

java - 如何将 json 内容从 jackson 流式传输到 org.apache.http.entity.InputStreamEntity?

javascript - 无法使用javascript设置下载文件的下载名称

javascript - 函数声明数组中的对象未定义 - 不!它不是!-?

java - 这个 java.io.IOException : Error: Expected a long type, 实际 ='930[299' 告诉了什么?

java - 合作流消费者的设计思路?

java - 使用 CSV2TableLayout 解析 CSV 但出现问号

javascript - 是 'isArraylike' 吗?

javascript - 从div中取出文本,插入文本区域,进行编辑,文本区域不显示?

pdf - 如何打开原始PDF?