INTEGRITY Документация

Создание PDF с помощью HTML и CSS

Как показано в Разверните Worker для Browser Run руководстве Browser Run можно использовать для создания скриншотов для любого заданного URL. Помимо скриншотов, вы также можете создавать полноценные PDF-документы для заданной веб-страницы, а также самостоятельно задавать разметку и стили страницы.

С помощью Browser Run PDF можно создать двумя способами:

Выберите способ, который лучше всего подходит для вашей задачи.

В следующем примере показано, как сгенерировать PDF с помощью Puppeteer.

Предварительные требования

  1. Используйте create-cloudflare CLI для создания нового скрипта Hello World для Cloudflare Worker:
npm create cloudflare@latest -- browser-worker
  1. Установка @cloudflare/puppeteer, который позволяет управлять экземпляром Browser Run:
npm i -D @cloudflare/puppeteer
  1. Добавьте привязку Browser Run в новую конфигурацию Wrangler:
{
	"browser": {
		"binding": "BROWSER",
	},
}
[browser]
binding = "BROWSER"
  1. Замените содержимое src/index.ts (или src/index.js для проектов на JavaScript) со следующим базовым скриптом:
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();
	},
};

1. Определение HTML и CSS

Вместо того чтобы использовать Browser Run для перехода по URL-адресу, указанному пользователем, сгенерируйте веб-страницу вручную и передайте её экземпляру Browser Run. Так вы сможете отрендерить любой нужный дизайн.

В этом примере мы будем принимать введённый пользователем контент (через параметр '?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-документа должен отображать бежевый фон, имитирующий сертификат, подтверждающий, что указанное пользователем имя успешно сформировало PDF с помощью Cloudflare Workers.

2. Загрузка HTML и CSS в браузер

Теперь, когда у вас есть полностью оформленный HTML-документ, можно взять его содержимое и отправить в экземпляр браузера. Создайте пустую страницу для хранения этого документа следующим образом:

const browser = await puppeteer.launch(env.BROWSER);
const page = await browser.newPage();

page.setContent() ↗ функция позволяет задать HTML-содержимое страницы из строки, поэтому можно передать созданный документ напрямую, например так:

await page.setContent(document);

3. Создание и возврат PDF

После того как ваш экземпляр Browser Run отрендерил переданные HTML и CSS, можно использовать page.pdf() ↗ команду для создания PDF-файла и возврата его клиенту.

let pdf = page.pdf({ printBackground: true });

page.pdf() вызов поддерживает количество параметров ↗, в том числе настроить размеры создаваемого PDF под конкретный формат бумаги, задать определённые поля и разрешить полностью прозрачный фон. Пока вы переопределяете только printBackground параметр, чтобы разрешить вашему body для отображения фоновых стилей.

Теперь, когда у вас есть данные PDF, верните их клиенту в Response с application/pdf тип содержимого:

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 dev

Когда скрипт запущен, можно передать ?name параметр локальному URL-адресу (например, http://localhost:8787/?name=Harley) и должны увидеть следующее:

Скриншот сгенерированного PDF-файла с именем автора на демонстрационном сертификате..


Пользовательские шрифты

Если для PDF требуется определенный шрифт, не установленный по умолчанию в окружении Browser Run, вы можете загрузить пользовательские шрифты с помощью addStyleTag. Это позволяет подключать шрифты из CDN или встраивать их в виде строк Base64 перед созданием PDF.

Подробные инструкции и примеры см. в Используйте собственный шрифт.


Динамическое создание PDF-документов решает целый ряд типичных задач: от выставления счетов клиентам до архивирования документов и формирования динамических сертификатов (как показано в приведенном здесь простом примере).