【问题标题】:wkhtmltopdf response in a buffer缓冲区中的 wkhtmltopdf 响应
【发布时间】:2019-12-03 19:05:17
【问题描述】:

所以,我编写了一个小代码,使用名为Wkhtmltopdf的库将 html 字符串转换为 pdf

这是我写的代码:

index.js

const express = require('express')
const app = express()
app.use(express.json())
const port = 3000
const compiledHtml = '<h1> This is testing </h1>'
app.post('/gc', async (req, res) => {
   wkhtmltopdf(compiledHtml, {
      pageSize: 'A4',
      orientation: 'Landscape',
      marginLeft: '1mm',
      marginTop: '1mm'
   }).pipe(fs.createWriteStream('out.pdf')) //--->(A)
   console.log('All done')
   res.send(compiledHtml)
})
app.listen(port, () => console.log(`Example app listening on port ${port}!`))

在这段代码中,我创建了 REST 调用POST,它们生成 pdf 并保存在名为 out.pdf 的文件中(上面的等式 (A))在运行脚本的同一文件夹中。

但实际上我想在 内存 中生成 pdf,获取相同的 缓冲区返回缓冲区到客户端,以便浏览器开始下载文件,我也有一个代码,这是在 response 中返回 buffer 的代码快递

sn-p

......
......
res.writeHead(200, {
  'Content-Type': 'application/pdf',
  'Content-disposition': 'attachment;filename=certificate.pdf',
  'Content-Length': buffer.length,
})
res.end(buffer)
......
......

通过上面的代码,我们可以将二进制数据写回客户端,客户端可以将其保存到任何他想要的地方。

但主要的问题是如何获取正在生成的文件的缓冲区。

请提供一些轻松愉快的编码:)

【问题讨论】:

    标签: node.js express pdf wkhtmltopdf


    【解决方案1】:

    因此,这是将缓冲流更改为异步等待行为的解决方案,这是我提出的通用解决方案:

    免责声明:对于较大的流来说,这不是一个好的做法,但可以在您知道结果缓冲区只有几 KB 的情况下使用

    const streamToBuffer = (streamObjectToRead) => {
       const chunks = []
       return new Promise((resolve, reject) => {
          streamObjectToRead
            .on('data', chunk => chunks.push(chunk))
            .on('end', () => resolve(Buffer.concat(chunks)))
            .on('error', err => reject(err))
       }) 
    }
    

    现在为了使用这个,你可以这样使用:

    const someAsyncFunction = async () => {
    
        ......
        ...... //some code
    
        const stream = <FUNCTION THAT RETURNS A STREAM> // like wkhtmltopdf(compiledHtml, optionsObject)
    
        const fullBufferAfterReadingFullStream = await streamToBuffer(stream)
        ..... // do whatever you want to do with that buffer, eg: Writing to file, sending back to response in express framework.
    }
    

    感谢和快乐编码:)

    【讨论】:

      【解决方案2】:

      我建议简单地将 wkhtmltopdf 的输出通过管道传输到 res 对象,这样可以避免完全创建缓冲区。

      const express = require('express')
      const app = express()
      app.use(express.json())
      const port = 3000
      const compiledHtml = '<h1> This is testing </h1>'
      app.post('/gc', async (req, res) => {
         res.writeHead(200, {
            'Content-Type': 'application/pdf',
            'Content-disposition': 'attachment;filename=certificate.pdf',
         });
      
         wkhtmltopdf(compiledHtml, {
            pageSize: 'A4',
            orientation: 'Landscape',
            marginLeft: '1mm',
            marginTop: '1mm'
         }).pipe(res)
         console.log('All done')
      });
      app.listen(port, () => console.log(`Example app listening on port ${port}!`))
      

      【讨论】:

      • 在这种情况下我不能设置'Content-Length': buffer.length,,因为我不知道它会是什么。
      • 不需要设置content-length header,将transfer-encoding header设置成chunked,客户端就可以下载文件了。
      猜你喜欢
      • 2020-04-20
      • 2013-06-17
      • 2012-04-12
      • 1970-01-01
      • 2021-05-14
      • 2021-07-14
      • 2019-01-10
      • 2020-09-30
      • 2017-06-14
      相关资源
      最近更新 更多