编程

使用 Browsershot 生成 PDF 发票

650 2023-08-10 15:34:00

开发票很无聊,手动写发票更是如此,这就是为什么你应该在应用程序中自动化整个过程。

发票是任何业务中非常重要的一部分。通过让你的 Laravel 应用程序自动生成发票,你可以让你的用户的生活变得更轻松,我们都知道这意味着他们会呆得更长,更热衷于使用你的应用程序。

在本文中,我将向您展示如何使用 Spatie 的 Browsershot 包自动生成发票PDF。继续阅读,了解如何操作!

制作发票视图

要生成 PDF, 我们首先需要一个网页用来展示 PDF 本身。因此,我设置了一个视图,显示一个A4大小的div,如下所示:<div style=“width:210mm;height:297mm;padding:25mm19mm”></div>。一旦设置好,你就可以让你的内部网页设计师免费运行。

设置 Browsershot

为了将 HTML 转换为 PDF,我使用了 Spatie 的 Browsershot 包。它有很好的文档,使用起来很愉快。

开工

由于这需要一些时间,而且我们不想让用户等待,我们将使用队列作业来生成 pdf。以下是我的设置:我做了一个生成 pdf 的 Job,然后向一个签名的 url 发送一个 post 请求,将发票上传到相应订单。我保持简单,您可以在这里使用 S3 或类似的东西。我添加此 post 请求的原因是,我们的工作程序将在与我们的 web 应用程序不同的虚拟机中运行,因此无法访问 web 应用程序的文件系统。如下是 handle 方法:

// Add a private property $order here and set it in the __construct() method.

/**
 * Execute the job.
 *
 * @return void
 */
public function handle()
{
    try {
        Browsershot::html(view('invoice.invoice', ['order' => $this->order])->render())
            ->noSandbox()
            ->waitUntilNetworkIdle()
            ->format('A4')
            ->showBackground()
            ->savePdf("temp.pdf");

        $postRoute = URL::signedRoute('orderinvoices.store', ['order' => $this->order]);
        Http::attach('invoice', file_get_contents('temp.pdf'), 'invoice.pdf')
            ->post($postRoute)
            ->throw();
    }
    catch (\Exception $exception )
    {
        Log::error($exception);
    }
}

这里需要注意的是:需要使用 noSandbox()方法来避免 Puppeter 使用的无头 Chrome 浏览器出现错误。因为我自己创建了我们传递的HTML代码,所以我不太担心安全风险。你可以在这里阅读更多关于Chrome沙箱的信息。