缓冲区中的 wkhtmltopdf 响应
wkhtmltopdf response in a buffer
所以,我编写了一个小代码,使用名为 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,获取缓冲区相同的 return 将缓冲区返回给客户端 以便浏览器开始下载文件,我也有一个代码,这里是 return buffer in response in express
片段
......
......
res.writeHead(200, {
'Content-Type': 'application/pdf',
'Content-disposition': 'attachment;filename=certificate.pdf',
'Content-Length': buffer.length,
})
res.end(buffer)
......
......
通过上面的代码我们可以将二进制数据写回给客户端,他可以把它保存在任何他想保存的地方。
但主要问题是如何获取正在生成的文件的缓冲区。
请说明,编码愉快:)
我建议简单地将 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}!`))
所以,这里是将缓冲流更改为异步等待行为的解决方案,这里是我制定的通用解决方案:
免责声明:对于较大的数据流来说,这不是一个好的做法,但如果您知道结果缓冲区会很少 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.
}
谢谢,编码愉快:)
所以,我编写了一个小代码,使用名为 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,获取缓冲区相同的 return 将缓冲区返回给客户端 以便浏览器开始下载文件,我也有一个代码,这里是 return buffer in response in express
片段
......
......
res.writeHead(200, {
'Content-Type': 'application/pdf',
'Content-disposition': 'attachment;filename=certificate.pdf',
'Content-Length': buffer.length,
})
res.end(buffer)
......
......
通过上面的代码我们可以将二进制数据写回给客户端,他可以把它保存在任何他想保存的地方。
但主要问题是如何获取正在生成的文件的缓冲区。
请说明,编码愉快:)
我建议简单地将 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}!`))
所以,这里是将缓冲流更改为异步等待行为的解决方案,这里是我制定的通用解决方案:
免责声明:对于较大的数据流来说,这不是一个好的做法,但如果您知道结果缓冲区会很少 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.
}
谢谢,编码愉快:)