如部署 Browser Run Worker 指南所示,Browser Run 可用于为任意给定 URL 生成屏幕截图。除屏幕截图外,你还可以为给定网页生成完整 PDF 文档,也可以自行提供网页 markup 和样式。
你可以通过两种方式使用 Browser Run 生成 PDF:
- Quick Actions:使用 /pdf 端点。如果你不需要自定义渲染行为,这是理想选择。
- Puppeteer 或 Playwright:在 Workers 中使用浏览器自动化,以获得额外的控制和自定义能力。
选择最适合你用例的方式。
以下示例展示如何使用 Puppeteer 生成 PDF。
- 使用
create-cloudflareCLI 生成新的 Hello World Cloudflare Worker 脚本:
npm create cloudflare@latest -- browser-workeryarn create cloudflare browser-workerpnpm create cloudflare@latest browser-worker- 安装
@cloudflare/puppeteer,以便控制 Browser Run 实例:
npm i -D @cloudflare/puppeteeryarn add -D @cloudflare/puppeteerpnpm add -D @cloudflare/puppeteerbun add -d @cloudflare/puppeteer- 在新的 Wrangler 配置中添加 Browser Run 绑定:
{
"browser": {
"binding": "BROWSER",
},
}[browser]
binding = "BROWSER"- 将
src/index.ts(JavaScript 项目为src/index.js)的内容替换为以下骨架脚本:
import puppeteer from "@cloudflare/puppeteer";
const generateDocument = (name: string) => {};
export default {
async fetch(request, env) {
const { searchParams } = new URL(request.url);
let name = searchParams.get("name");
if (!name) {
return new Response("Please provide a name using the ?name= parameter");
}
const browser = await puppeteer.launch(env.BROWSER);
const page = await browser.newPage();
// Step 1: Define HTML and CSS
const document = generateDocument(name);
// Step 2: Send HTML and CSS to our browser
await page.setContent(document);
// Step 3: Generate and return PDF
return new Response();
},
};与其使用 Browser Run 导航到用户提供的 URL,不如手动生成网页,然后将该网页提供给 Browser Run 实例。这允许你渲染任何你想要的设计。
在本示例中,我们将接收用户提供的 content(通过 ?name= 参数),并在最终 PDF 文档中输出该名称。
首先,用以下内容填充 generateDocument 函数:
const generateDocument = (name: string) => {
return `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<style>
html,
body,
#container {
width: 100%;
height: 100%;
margin: 0;
}
body {
font-family: Baskerville, Georgia, Times, serif;
background-color: #f7f1dc;
}
strong {
color: #5c594f;
font-size: 128px;
margin: 32px 0 48px 0;
}
em {
font-size: 24px;
}
#container {
flex-direction: column;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
}
</style>
</head>
<body>
<div id="container">
<em>This is to certify that</em>
<strong>${name}</strong>
<em>has rendered a PDF using Cloudflare Workers</em>
</div>
</body>
</html>
`;
};此 HTML 文档应渲染米色背景,模仿证书样式,显示用户提供的名称已成功使用 Cloudflare Workers 渲染 PDF。
现在你有了完整样式的 HTML 文档,可以获取内容并发送到浏览器实例。按如下方式创建空页面以存储此文档:
const browser = await puppeteer.launch(env.BROWSER);
const page = await browser.newPage();然后可以使用 page.setContent() ↗ 函数从字符串设置页面的 HTML 内容,因此可以直接传入创建的文档:
await page.setContent(document);Browser Run 实例现在渲染你提供的 HTML 和 CSS,你可以使用 page.pdf() ↗ 命令生成 PDF 文件并返回给客户端。
let pdf = page.pdf({ printBackground: true });page.pdf() 调用支持多种选项 ↗,包括将生成 PDF 的尺寸设置为特定纸张大小、设置特定边距以及允许完全透明背景。目前,你仅覆盖 printBackground 选项以允许 body 背景样式显示。
现在你有了 PDF 数据,在 Response 中以 application/pdf content type 返回:
return new Response(pdf, {
headers: {
"content-type": "application/pdf",
},
});完整的 Worker 脚本现如下所示:
import puppeteer from "@cloudflare/puppeteer";
const generateDocument = (name: string) => {
return `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<style>
html, body, #container {
width: 100%;
height: 100%;
margin: 0;
}
body {
font-family: Baskerville, Georgia, Times, serif;
background-color: #f7f1dc;
}
strong {
color: #5c594f;
font-size: 128px;
margin: 32px 0 48px 0;
}
em {
font-size: 24px;
}
#container {
flex-direction: column;
display: flex;
align-items: center;
justify-content: center;
text-align: center
}
</style>
</head>
<body>
<div id="container">
<em>This is to certify that</em>
<strong>${name}</strong>
<em>has rendered a PDF using Cloudflare Workers</em>
</div>
</body>
</html>
`;
};
export default {
async fetch(request, env) {
const { searchParams } = new URL(request.url);
let name = searchParams.get("name");
if (!name) {
return new Response("Please provide a name using the ?name= parameter");
}
const browser = await puppeteer.launch(env.BROWSER);
const page = await browser.newPage();
// Step 1: Define HTML and CSS
const document = generateDocument(name);
// // Step 2: Send HTML and CSS to our browser
await page.setContent(document);
// // Step 3: Generate and return PDF
const pdf = await page.pdf({ printBackground: true });
// Close browser since we no longer need it
await browser.close();
return new Response(pdf, {
headers: {
"content-type": "application/pdf",
},
});
},
};你可以通过以下方式运行此脚本进行测试:
npx wrangler devyarn wrangler devpnpm wrangler dev脚本运行后,你可以向本地 URL 传递 ?name 参数(例如 http://localhost:8787/?name=Harley),应该会看到以下内容:
.
如果你的 PDF 需要 Browser Run 环境中未预装的字体,可以使用 addStyleTag 加载自定义字体。这允许你在生成 PDF 之前从 CDN 注入字体或将其嵌入为 Base64 字符串。
有关说明和示例,请参阅使用自定义字体。
动态生成 PDF 文档解决了许多常见用例,从向客户开具发票到归档文档,再到创建动态证书(如本简单示例所示)。