statikbe/laravel-puppeteer-pdf-converter

这是AWS Lambda上Statik Puppeteer PDF转换API的便捷封装。

v1.2.1 2024-03-14 15:54 UTC

README

Laravel Puppeteer PDF Converter

Laravel Puppeteer PDF转换器

Latest Version on Packagist Total Downloads

这是一个将HTML页面转换为PDF的服务的便捷封装。该服务使用Puppeteer.js,并在Statik内部开发。该服务的代码尚未开源,但可按要求分享。

安装

您可以通过composer安装此包

composer require statikbe/laravel-puppeteer-pdf-converter

您可以使用以下命令发布配置文件

php artisan vendor:publish --tag="puppeteer-pdf-converter-config"

这是发布配置文件的内容

<?php

return [
    /*
     * The URL to the AWS Lambda API to convert HTML to PDF with Puppeteer.
     */
    'pdf_conversion_api' => env('PDF_CONVERSION_API'),

    /*
     * If the url is generated from a route name, a signed URL is created with a time-to-live (TTL). This is useful
     * when sensitive data is available on the URL, so it can only be accessed from a signed url.
     * Note: you need to check if the signature is valid in the controller of the route.
     */
    'temporary_signed_route_ttl' => 10,     // in minutes

    /*
     * If you develop with this library locally, you can setup NGROK or some other tunneling service to make your local
     * computer publicly avaialable for the PDF service, so you can test the PDF conversion while developing.
     */
    'ngrok_app_url' => env('NGROK_APP_URL'),

    /*
     * The paper width of the PDF (defaults to A4) (see Puppeteer docs for details, https://pptr.cn/#?product=Puppeteer&version=v10.4.0&show=api-pagepdfoptions)
     */
    'pdf_width' => null,

    /*
     * The paper height of the PDF (defaults to A4) (see Puppeteer docs for details, https://pptr.cn/#?product=Puppeteer&version=v10.4.0&show=api-pagepdfoptions)
     */
    'pdf_height' => null,

    /*
     * The scale of the web page rendering, allows to zoom in or out of the page (defaults to 1, must be between 0.1 and 2)
     */
    'pdf_scale' => 1,

    /*
     * The paper top margin (provide units in "px" or "cm", e.g. "40px")
     */
    'paper_margin_top' => null,

    /*
     * The paper bottom margin (provide units in "px" or "cm", e.g. "40px")
     */
    'paper_margin_bottom' => null,

    /*
     * The paper left margin (provide units in "px" or "cm", e.g. "40px")
     */
    'paper_margin_left' => null,

    /*
     * The paper right margin (provide units in "px" or "cm", e.g. "40px")
     */
    'paper_margin_right' => null,
];

配置

必需:您需要在.env文件中使用键PDF_CONVERSION_API设置API的URL。

可选:其他配置是可选的。您可以设置默认的Puppeteer配置,例如纸张边距、缩放和纸张宽度和高度。纸张宽度和高度默认为A4。有关可能的Puppeteer配置的更多信息,请参阅Puppeteer文档

您还可以在创建PDF时手动设置PDF配置,请参阅以下内容。但是,请注意,配置文件中设置的默认配置始终作为基础,并由代码中的手动选项覆盖。如果在配置文件或手动选项中将值设置为null,则不会将选项发送到服务(即禁用该选项)。

使用方法

该库允许将HTML页面转换为PDF,用于路由名称(使用convertRoute())或URL(使用convertUrl())。

如果您想覆盖配置文件中设置的PDF选项,您可以创建一个PdfOptions对象。

//set options and get pdf from conversion API
try {
    $pdfOptions = new PdfOptions();
    $pdfOptions->setScale(0.6)
        ->setPageMargins(new PdfPageMargin(40, PdfPageMargin::MARGIN_IN_PIXELS));
    $pdfUrl = PuppeteerPdfConverter::convertRoute('report_index', ['organisation' => $organisation], 'report.pdf', $pdfOptions);
    return redirect($pdfUrl);
}
catch(PdfApiException $exception){
    Log::error(sprintf('PDF report could not be created: %s (for organisation: %s)', $exception->getMessage(), $organisation));
    return view('pdf_error', ['error' => $exception->getMessage()]);
}

可能会发生以下异常

  • TimeoutException:由于PDF转换服务运行在AWS Lambda上,可能会因冷启动问题而超时。如果20秒内没有响应,则将抛出此异常。您可以使用此异常实现重试机制。
  • UnsuccessfulHttpResponseException:当给定的URL返回的HTTP状态不是成功状态(在200范围内)时,将抛出此异常,以避免在PDF中渲染错误页面。
  • ConversionException:如果在服务或Puppeteer库中发生内部错误,将返回此异常。
  • PdfApiException:此异常是所有上述异常的父类,因此可以用于在单个捕获子句中捕获所有上述异常(如示例所示)。
  • InvalidMarginUnitException:如果边距的单位不是px或cm,则抛出此异常。

临时URL

该库可以生成临时签名URL。如果您需要从需要授权的路由生成PDF,这将很有用。PDF服务无法登录到您的应用程序。但是,通过使用临时签名URL,我们可以验证应用程序已生成该URL,且没有人篡改它。

您需要在HTML页面的控制器中检查URL的签名是否有效。有关示例,请参阅本地开发部分。

本地开发

PDF转换服务在云端运行。对于本地开发,您可以在本地运行它或使用隧道服务来公开您的本地Web服务器。此类隧道软件的例子有NgrokExpose。或者如果您使用Valet,有共享命令

valet share

如果您使用Ngrok,可以启动服务(将APP_URL替换为您的.env文件中APP_URL键的值)

ngrok http -host-header=APP_URL 80

然后,您可以在.env文件中配置隧道URL,键为NGROK_APP_URL。您也可以在此变量中设置Valet或Expose的URL。例如

NGROK_APP_URL=http://dba0-94-224-113-240.ngrok.io

如果您使用临时签名URL,有一个方便的函数可以检查是否已配置本地隧道(即NGROK_APP_URL是否已设置,并且环境设置为local)。

PuppeteerPdfConverter::isLocalTunnelConfigured();

这可以用来绕过控制器中的有效签名检查。因为生成的URL中会替换NGROK_APP_URL,所以签名将不再有效,因此我们需要绕过$request->hasValidSignature()检查。

更新日志

有关最近更改的更多信息,请参阅更新日志

贡献

您可以使用Github问题跟踪器,并欢迎Pull Requests!

鸣谢

许可证

MIT许可证(MIT)。有关更多信息,请参阅许可证文件