使用 puppeteer 生成 PDF 而不保存
Generate PDF with puppeteer without save it
我有一个用 node.js
编写的 API 托管在 heroku
上,我的前端应用程序是用 Vue.js
编写的,它在 hostinger
上。我想知道是否可以使用 puppeteer 生成 PDF 文件并立即将其发送到前端客户端而不先将其保存到磁盘?如果是的话,你能给我一些例子吗?
目前我的功能是这样的:
exports.gerarPDFAvaliacao = async (dadosAvaliacao) => {
try {
const compile = async (fileName, data) => {
const filePath = path.join(process.cwd(), 'src/templates/client/operation/', `${fileName}.hbs`);
const html = await fs.readFile(filePath, 'utf-8');
return await hbs.compile(html)(data);
}
const browser = await puppeteer.launch();
const page = await browser.newPage();
let content = await compile('avaliations', dadosAvaliacao);
await page.goto(`data:text/html,${content}`, { waitUntil: 'networkidle0' });
await page.emulateMedia('screen');
await page.pdf({
path: 'src/dist/pdf/' + dadosAvaliacao.arquivo + '.pdf',
format: 'A4',
printBackground: true
})
await browser.close();
return dadosAvaliacao.arquivo + '.pdf';
} catch (error) {
console.log('Errors => ', error);
}
};
根据 official documentation,如果您不提供路径,文件将不会保存到磁盘。
page.pdf(options) :
Options object which might have the following properties:
path The file path to save the PDF to. If path is a relative path, then it is resolved relative to current working directory. If no path is provided, the PDF won't be saved to the disk.
这意味着它应该 return 类似于生成文件的缓冲区或二进制表示形式。根据您使用的框架,您只需要 return 或将其通过管道传递给响应即可。
这只是将 pdf 输出到控制台:
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://example.com');
console.log(await page.content());
const pdf = await page.pdf();
await browser.close();
console.log(pdf) // maybe do response(pdf).type('x-pdf')
编辑:这是一个使用 express 和 puppeteer 的完整示例,returns pdf 内容直接在内存中。它在 runkit 上运行,所以我认为同样的限制适用(甚至更多)。如果您导航到示例中的 public 端点,您可以看到浏览器如何检测到它是一个 pdf 文件并正确呈现它。
- Publicurl:
https://puppeteer-express-pdf-export-w3o8ip7k207y.runkit.sh/
- Runkit 笔记本:https://runkit.com/danielo515/puppeteer-express-pdf-export
代码
const puppeteer = require ('puppeteer');
const express = require('express');
var app = express(exports);
const browser = await puppeteer.launch();
const main = async () => {
const page = await browser.newPage();
await page.goto('https://example.com');
const pdf = await page.pdf();
return pdf;
}
app.get('/', async function (req, res) {
const pdf = await main();
res.contentType("application/pdf");
res.send(pdf);
});
app.listen(3000, function(){ console.log('Listening on 3000') });
我有一个用 node.js
编写的 API 托管在 heroku
上,我的前端应用程序是用 Vue.js
编写的,它在 hostinger
上。我想知道是否可以使用 puppeteer 生成 PDF 文件并立即将其发送到前端客户端而不先将其保存到磁盘?如果是的话,你能给我一些例子吗?
目前我的功能是这样的:
exports.gerarPDFAvaliacao = async (dadosAvaliacao) => {
try {
const compile = async (fileName, data) => {
const filePath = path.join(process.cwd(), 'src/templates/client/operation/', `${fileName}.hbs`);
const html = await fs.readFile(filePath, 'utf-8');
return await hbs.compile(html)(data);
}
const browser = await puppeteer.launch();
const page = await browser.newPage();
let content = await compile('avaliations', dadosAvaliacao);
await page.goto(`data:text/html,${content}`, { waitUntil: 'networkidle0' });
await page.emulateMedia('screen');
await page.pdf({
path: 'src/dist/pdf/' + dadosAvaliacao.arquivo + '.pdf',
format: 'A4',
printBackground: true
})
await browser.close();
return dadosAvaliacao.arquivo + '.pdf';
} catch (error) {
console.log('Errors => ', error);
}
};
根据 official documentation,如果您不提供路径,文件将不会保存到磁盘。
page.pdf(options) : Options object which might have the following properties: path The file path to save the PDF to. If path is a relative path, then it is resolved relative to current working directory. If no path is provided, the PDF won't be saved to the disk.
这意味着它应该 return 类似于生成文件的缓冲区或二进制表示形式。根据您使用的框架,您只需要 return 或将其通过管道传递给响应即可。
这只是将 pdf 输出到控制台:
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://example.com');
console.log(await page.content());
const pdf = await page.pdf();
await browser.close();
console.log(pdf) // maybe do response(pdf).type('x-pdf')
编辑:这是一个使用 express 和 puppeteer 的完整示例,returns pdf 内容直接在内存中。它在 runkit 上运行,所以我认为同样的限制适用(甚至更多)。如果您导航到示例中的 public 端点,您可以看到浏览器如何检测到它是一个 pdf 文件并正确呈现它。
- Publicurl: https://puppeteer-express-pdf-export-w3o8ip7k207y.runkit.sh/
- Runkit 笔记本:https://runkit.com/danielo515/puppeteer-express-pdf-export
代码
const puppeteer = require ('puppeteer');
const express = require('express');
var app = express(exports);
const browser = await puppeteer.launch();
const main = async () => {
const page = await browser.newPage();
await page.goto('https://example.com');
const pdf = await page.pdf();
return pdf;
}
app.get('/', async function (req, res) {
const pdf = await main();
res.contentType("application/pdf");
res.send(pdf);
});
app.listen(3000, function(){ console.log('Listening on 3000') });