viavario/pdfgenerator

使用 AWS Lambda 上的无头 Chrome 生成的 PDF 生成器

1.0.10 2024-06-08 15:58 UTC

This package is auto-updated.

Last update: 2024-09-08 16:27:01 UTC


README

PDFGenerator 允许您使用 PHP 轻松生成任何网页的 PDF 文档或 PNG 截图。

过去,我们使用 PhantomJS、wkhtmltopdf 和 TCPDF 从给定的 URL 或 HTML 生成 PDF。然而,这些库已经不再积极开发或维护,并且缺乏对 HTML 和 CSS 中新特性的支持。Google Chrome 内置了将网页截图为 PDF 或 PNG 格式的功能,对新特性的支持更好。

通过使用 Amazon LambdaAmazon API Gateway,您可以最小化运行成本,实现可扩展的性能和灵活的安全控制。Lambda 用于运行无头 Chrome 作为按需服务,从任何网站或提交的 HTML 内容中获取截图,而无需设置服务器。您可以在 API Gateway 上配置安全控制,如 API 密钥、速率限制和配额,以保护您的截图服务免受第三方或不当使用的影响。

使用 Puppeteer 与 Chrome 通信,以编程方式加载内容并获取截图。

需求

要在 Amazon Lambda 上部署 Chrome,您需要

  1. 一个 Amazon AWS 账户 以部署 Lambda 函数
  2. 在您的本地计算机上安装 Node.js
  3. 在您的本地计算机上安装 Serverless

在 PHP 中使用此库

  1. Composer
  2. PHP 7+

在 Amazon Lambda 上部署 Chrome

  1. 访问官方 Node.js 网站,下载并按照 安装说明 在您的本地计算机上安装 Node.js。

  2. 通过 npm 安装 Serverless Framework,它已在安装 Node.js 时安装。
    打开终端并运行以下命令安装 Serverless

npm install -g serverless

接下来,您需要 设置您的凭证,以便 Serverless 能够连接到您的 Amazon AWS 账户以部署 Lambda 函数和 API Gateway。最简单的方法是创建一个新的 IAM 用户,并将自定义 JSON 策略附加到新 IAM 用户以限制 Serverless Framework 对您的 AWS 账户的访问。这样,您就不必在 https://serverless.com 上注册账户。
要限制 Serverless Framework 对您的 AWS 账户的访问,请按照以下步骤创建一个 IAM 用户 并将自定义 JSON 文件策略附加到新 IAM 用户。此 IAM 用户将有自己的 AWS 访问密钥。

  1. 登录您的 AWS 账户并转到身份与访问管理(IAM)页面。
  2. 点击“用户”,然后点击添加用户。在第一个字段中输入一个名称,以提醒您此用户与您使用Serverless Framework与服务器一起部署的服务相关,例如 serverless-servicename-agent1。通过点击复选框启用程序访问。点击下一步进入权限页面。点击创建策略。选择JSON选项卡,并添加一个JSON文件。您可以使用此gist作为指南。
  3. 完成后,选择审查策略。您可以为这个策略分配一个名称描述,然后选择创建策略。检查一切是否良好,然后点击创建用户。稍后,您可以为不同的应用程序和应用程序的不同阶段创建不同的IAM用户。也就是说,如果您不使用不同的AWS账户来处理阶段/应用程序,这是最常见的情况。
  4. 查看并复制API密钥密钥,并在以下命令中的<your-key-here><your-secret-key-here>处替换,然后运行命令
serverless config credentials --provider aws --key <your-key-here> --secret <your-secret-key-here>
  1. 在终端窗口中导航到该存储库中的screenshot-service目录,并运行以下命令安装所需的包
npm install
  1. 打开screenshot-service/serverless.yml,将第10行的区域更改为您希望部署到Amazon AWS的区域,以及第27行对应所需Lambda层的引用。有关可用区域和Lambda层对应引用的更多信息,请参阅https://github.com/shelfio/chrome-aws-lambda-layer和[https://docs.aws.amazon.com/general/latest/gr/rande.html#regional-endpoints]{https://docs.aws.amazon.com/general/latest/gr/rande.html#regional-endpoints}
  region: eu-west-3
  ...
    layers: # reference to the already existing layer with Chrome
      - arn:aws:lambda:eu-west-3:764866452798:layer:chrome-aws-lambda:31
  1. 接下来,将截图服务部署到Amazon AWS
serverless deploy --stage production
  1. 在命令输出中,您可以找到GET和POST请求的端点。
    Output of serverless deploy

如果您尚未为截图服务配置任何API密钥,只需复制GET请求的端点URL,将?filename=screenshot.png&url=[您的网站URL]追加到端点URL,然后在浏览器中打开即可。

请注意,您必须将API的/capture - GET -方法请求中的API密钥必需设置为,才能在没有API密钥的情况下测试此功能。

  1. 转到Amazon API Gateway
  2. 打开截图服务的API
  3. 资源面板下点击/capture下的GET
  4. 点击方法请求
  5. 点击API密钥必需旁边的铅笔图标,将设置从更改为,然后点击复选标记图标以保存设置。
  6. 点击操作按钮,从菜单中选择部署API以重新部署API,以测试没有API密钥的GET请求。

验证截图服务正常工作后,请确保将API密钥必需设置为,以防止未经授权的使用或访问。

例如:https://##########.execute-api.eu-west-3.amazonaws.com/dev/capture?filename=screenshot.png&url=https://www.google.com/finance/quote/TSLA:NASDAQ?hl=en返回了谷歌财经上的特斯拉股票截图

Example screenshot

保护您的截图服务

为了防止未经授权的使用或访问,您可以为API Gateway设置API密钥。如果未为截图服务设置API密钥,其他人可能会使用您的安装来创建截图,这将增加您的账单。确保您保护了您的API Gateway非常重要。

确保重新部署API,以便API密钥需求生效!

有关如何设置API密钥的说明,请参阅https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-setup-api-key-with-console.html

本库的安装

composer require viavario\pdfgenerator

使用方法

<?php
include_once __DIR__.'/vendor/autoload.php';

use viavario\pdfgenerator\PDFGenerator;

// This is invoke URL of the API Gateway or the endpoint returned by the
// serverless deploy command without `capture` at the end
$endpoint = 'https://##########.execute-api.eu-west-3.amazonaws.com/dev/';
$apiKey = '<your-api-key>'; // Your API Key configured in the API Gateway
$filename = 'screenshot.pdf'; // Change to screenshot.png to get a PNG image

$generator = new PDFGenerator($endpoint, $apiKey);
$generator->setURL('https://google.com')
    ->setFilename($filename)
    ->setMargins('1.5cm')
    ->setFormat('A4')
    // The screenshot service automatically increases the height of the viewport
    // to take a full page screenshot
    ->setViewportSize(1920, 1080)
    ->setOrientation(PDFGenerator::ORIENTATION_PORTRAIT);

try {
    $tempfile = $generator->generate();
    // Change the Content-Type to image/png if you changed the extension of the
    // filename to .png
    header('Content-Type: application/pdf');
    echo $tempfile;
}
catch (\Exception $e) {
    echo $e->getMessage();
}

方法

PDFGenerator::__construct

描述

public __construct (string $endpoint, string $apiKey)

类构造函数。

参数

  • (string) $endpoint : 终端URL
  • (string) $apiKey : AWS Lambda函数的API密钥

返回值

void

PDFGenerator::displayHeaderFooter

描述

public displayHeaderFooter (bool $displayHeaderFooter)

显示页眉和页脚模板。

参数

  • (bool) $displayHeaderFooter : 设置为true以在PDF文档中显示页眉和页脚

返回值

PDFGenerator

PDFGenerator::generate

描述

public generate (string $filename)

生成截图。

参数

  • (string) $filename : 要写入的文件名(默认为null,将导致方法返回二进制数据)

返回值

mixed

如果没有指定文件名,则生成的文件作为二进制数据返回。
如果指定了文件名,则当文件成功写入时返回true,否则返回false。
PDFGenerator::omitBackground

隐藏默认的白色背景,并允许捕获具有透明度的截图。默认为false。

描述

public omitBackground (bool $omitBackground)

(bool) $omitBackground : 设置为true以省略白色背景

参数

  • PDFGenerator::preferCSSPageSize

返回值

PDFGenerator

将页面中声明的任何CSS @page大小优先于宽度和高度或格式选项中声明的大小。默认为false,这将调整内容以适应纸张大小。

描述

public preferCSSPageSize (bool $preferCSSPageSize)

(bool) $preferCSSPageSize : 设置为true以启用CSS页面大小

参数

  • PDFGenerator::printBackground

返回值

PDFGenerator

设置为true以打印背景。

描述

public printBackground (bool $printBackground)

(bool) $printBackground : 设置为true以打印背景

参数

  • PDFGenerator::setContent

返回值

PDFGenerator

设置内容。

描述

public setContent (string $content)

(string) $content : 要截图的HTML内容

参数

  • PDFGenerator::setFilename

返回值

PDFGenerator

设置文件名。

描述

public setFilename (string $filename)

(string) $filename : 设置输出文件名。只允许扩展名.pdf和.png。

参数

  • PDFGenerator::setFooterTemplate

返回值

PDFGenerator

设置页脚模板。

描述

public setFooterTemplate (string $html)

应该是有效的HTML标记,并使用以下类将打印值注入其中

打印日期的日期格式

  • 标题 文档标题
  • URL 文档位置
  • 页码 当前页码
  • 总页数 文档中的总页数
  • (string) $html : HTML标记

参数

  • PDFGenerator::setFormat

返回值

PDFGenerator

设置页面格式。

描述

public setFormat (void)

格式选项如下

Letter: 8.5in x 11in

  • Legal: 8.5in x 14in
  • Tabloid: 11in x 17in
  • Ledger: 17in x 11in
  • A0: 33.1in x 46.8in
  • A1: 23.4in x 33.1in
  • A2: 16.54in x 23.4in
  • A3: 11.7in x 16.54in
  • A4: 8.27in x 11.7in
  • A5: 5.83in x 8.27in
  • A6: 4.13in x 5.83in
  • A7: 2.91in x 4.13in

参数

A8: 2.06in x 2.91in

返回值

PDFGenerator

A9: 1.44in x 2.06in

描述

public setHeaderTemplate (string $html)

A10: 1.02in x 1.44in

打印日期的日期格式

  • 标题 文档标题
  • URL 文档位置
  • 页码 当前页码
  • 总页数 文档中的总页数
  • (string) $html : HTML标记

参数

  • PDFGenerator::setFormat

返回值

PDFGenerator

A11: 0.71in x 1.02in

描述

public setHttpAuthentication (void)

A12: 0.5in x 0.71in

参数

A8: 2.06in x 2.91in

返回值

PDFGenerator

This function has no parameters.

描述

public setMargins (string $margins, string $right, string $bottom, string $left)

PDFGenerator::setHeaderTemplate

参数

  • 设置页眉模板。
  • PDFGenerator::setHttpAuthentication
  • 设置HTTP认证的用户名和密码。
  • PDFGenerator::setMargins

返回值

PDFGenerator

设置页面的边距。

(string) $margins : 顶部边距,或所有边距

描述

public setOrientation (string $orientation)

(string) $right : 右边距

参数

  • (string) $bottom : 底部边距

返回值

PDFGenerator

(string) $left : 左边距

描述

public setURL (string $url)

return this instance

参数

  • PDFGenerator::setOrientation

返回值

PDFGenerator

设置页面方向。

描述

public setViewportSize (void)

(string) $orientation : PDFGenerator::ORIENTATION_LANDSCAPE 或 PDFGenerator::ORIENTATION_PORTRAIT

参数

A8: 2.06in x 2.91in

返回值

PDFGenerator