惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

D
Docker
I
InfoQ
L
LangChain Blog
阮一峰的网络日志
阮一峰的网络日志
Y
Y Combinator Blog
博客园_首页
Martin Fowler
Martin Fowler
宝玉的分享
宝玉的分享
A
About on SuperTechFans
Apple Machine Learning Research
Apple Machine Learning Research
Vercel News
Vercel News
T
The Blog of Author Tim Ferriss
C
Check Point Blog
B
Blog RSS Feed
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Engineering at Meta
Engineering at Meta
B
Blog
爱范儿
爱范儿
Stack Overflow Blog
Stack Overflow Blog
aimingoo的专栏
aimingoo的专栏
WordPress大学
WordPress大学
F
Fortinet All Blogs
月光博客
月光博客
GbyAI
GbyAI

mafeifan 的编程技术分享

mafengwo-mp3-downloader | mafeifan 的编程技术分享 示例页面 | mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 查看 default namespace 下的 default service account名称 mafeifan 的编程技术分享 检查日志 | mafeifan 的编程技术分享 bridge fdb show dev flannel.1 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享
mafeifan 的编程技术分享
2026-01-16 · via mafeifan 的编程技术分享

wkhtmltopdf 是用C实现的生成pdf的开源软件。可以基于网址或html生成对应的PDF文件。 对OSX, linux, windows平台都提供了对应的支持。

snappy是一个对wkhtmltopdf封装的类库,使用非常简单。

而这里介绍的 laravel-snappy 则又是对snappy的封装,只不过方便集成到Laravel框架中。

在使用 laravel-snappy 之前我建议先浏览下 wkhtmltopdf官方文档 wkhtmltopdf下载后之后就是一个bin二进制文件,提供了非常多的参数。

这里介绍下怎么在Laravel6中使用laravel-snappy并生成pdf文件

  1. 首先下载安装wkhtmltopdf,以Ubuntu为例,来到https://wkhtmltopdf.org/downloads.html下载对应的版本

bash

# 下载安装包
wget https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6-1/wkhtmltox_0.12.6-1.
bionic_amd64.deb
# 安装
sudo dpkg -i wkhtmltox_0.12.6-1.bionic_amd64.deb
# 如果报错,如缺少依赖,可以执行下面这个
sudo apt-get -f install

# 检查是否安装成功 
which wkhtmltopdf
# 输出
/usr/local/bin/wkhtmltopdf
which wkhtmltoimage
# 输出
/usr/local/bin/wkhtmltoimage
  1. 按照 laravel-snappy 教程,添加Facade,生成config/snappy.php

  2. 新建resources/views/pos/receipt-pdf.blade.php模板, 这里面有一些变量需要Controller传给视图,需要注意字体和图片的引用。

html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>RECEIPT</title>
    <style type="text/css">
        .container-fluid {
            width: 100%;
            padding-right: 15px;
            padding-left: 15px;
            margin-right: auto;
            margin-left: auto;
        }
        @font-face {
            font-family: 'Microsoft YaHei';
            src: url('file://{{ public_path('fonts/msyh.ttc') }}') format('truetype');
            font-weight: normal;
            font-style: normal;
        }
        body {
            font-family: 'Microsoft YaHei';
            margin: 20px 40px;
            color: #222222;
        }
        thead {
            display: table-header-group;
        }
        tfoot {
            display: table-row-group;
        }
        tr {
            page-break-inside: avoid;
        }
        .mt-5 {
            margin-top: 3rem;
        }
        .mb-5 {
            margin-bottom: 3rem;
        }
        .font-bolder {
            font-weight: bolder;
        }
        .text-center {
            text-align: center;
        }
        .bottom-none {
            border-bottom: none !important;
        }
        .float-left {
            float: left !important;
        }
        .float-right {
            float: right !important;
        }
        .text-gray {
            color: #95aac9;
        }
        .text-danger {
            color: #dc3545 !important;
        }
        .table-receipt td {
            padding: 5px;
        }
        .table-items tr > td {
            border-bottom: 1px solid #dee2e6;
            padding: 15px;
        }
        .table-items tr > td:first-child {
            padding-left: 0;
        }
        .table-items tr > td:last-child {
            padding-right: 0;
        }
        tr.header {
            color: #95aac9;
        }
        tr.header > td {
            padding-top: 25px
        }
    </style>
</head>
<body>
<div class="container-fluid">
    <div class="text-center">
        <img height="auto" src="{{ public_path('images/logo-black.png') }}"/>
        <h1>Receipt from {{data_get($companyInfo, 'comName')}}</h1>
        <p class="text-gray" style="font-size: 18pt">Transaction ID: {{ $transactionID }}</p>
    </div>
    <table border="0" cellpadding="0" cellspacing="0" style="width: 100%" class="table-receipt">
        <thead>
        <tr class="header">
            <td align="left">INVOICED FROM</td>
            <td align="right">INVOICED TO</td>
        </tr>
        </thead>
        <tbody>
        <tr class="font-bolder">
            <td>{{ data_get($companyInfo, 'comName')}}</td>
            <td align="right">Guest</td>
        </tr>
        <tr>
            <td>{{ data_get($companyInfo, 'comAddress1')}}</td>
            <td align="right">--</td>
        </tr>
        <tr>
            <td>{{ data_get($companyInfo, 'comAddress2')}}</td>
            <td align="right">--</td>
        </tr>
        <tr class="header">
            <td>INVOICE ID</td>
            <td align="right">PAYMENT AT</td>
        </tr>
        <tr class="font-bolder">
            <td>{{ $transactionID }}</td>
            <td align="right">{{ date('m-d-Y') }} at {{ date('H:i:s') }}</td>
        </tr>
        <tr class="header">
            <td>PAGE</td>
            <td align="right">PAYMENT METHOD</td>
        </tr>
        <tr class="font-bolder">
            <td>1 of 1</td>
            <td align="right">{{ data_get($payMethod, 'label') }}</td>
        </tr>
        </tbody>
    </table>
    <hr class="mt-5" style="border: 1px solid #95aac9;opacity: 10%;">
    <h3 class="text-gray text-center">THANK YOU FOR YOUR ORDER!</h3>
    <h3 class="text-gray text-center">WE HOPE TO SEE YOU AGAIN SOON!</h3>
</div>
</body>
</html>
  1. Controller中添加生成pdf方法 sendReceiptEmail是发送发票到客户邮箱中,需要先调用exportToPDF生成pdf格式的发票,然后作为邮箱附件发送出去。

php

    public function exportToPDF($pdfData) {
        $blade = 'pos.receipt-pdf';
        $pdf = \App::make('snappy.pdf.wrapper');
        // 传给pdf视图模板的变量,有可能是从数据库或session中获取,这里不展开
        $body = \View::make($blade, $pdfData)->render();
        $pdf->loadHTML($body)->setPaper('a4');
        // 这里的参数其实是wkhtmltopdf的,文档里都可以查到,由于我们引用了本地图片和字体,需要开启本地访问文件权限
        $pdf->setOption('enable-local-file-access', true);
        $pdf->setOption('margin-top', '5mm');
        $pdf->setOption('margin-bottom', '5mm');
        $pdf->setOption('margin-left', '5mm');
        $pdf->setOption('margin-right', '5mm');
        return $pdf;
    }

    public function sendReceiptEmail(Request $request) {
        // 保存pdf的临时路径
        $pdfPath = storage_path('app/order-receipt/tmp/tmp.pdf');
        if (file_exists($pdfPath)) {
            \File::delete($pdfPath);
        }
        
        // 先获取pdf需要的数据
        $pdfData = $this->processPdfData($request);
        
        // 生成pdf
        $pdf = $this->exportToPDF($pdfData);

        // 保存成功,作为附件发送出去
        if ($pdf->save($pdfPath)) {
            Mail::to('mafeifan@qq.com')
                ->send(new PosOrderReceipt());
        }
    }

app/Mail/PosOrderReceipt.php

php

<?php

namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;

class PosOrderReceipt extends Mailable
{
    use Queueable, SerializesModels;

    /**
     * Create a new message instance.
     *
     * @return void
     */
    public function __construct()
    {

    }

    /**
     * Build the message.
     *
     * @return $this
     */
    public function build()
    {
        $location = storage_path('app/order-receipt/tmp/tmp.pdf');
        return $this
            ->view('emails.pos.order-receipt', [
            ])
            ->attach($location, [
                'as' => 'receipt.pdf',
                'mime' => 'application/pdf']);
    }
}

注意事项 ​

  1. 如果不开启enable-local-file-access引用本地文件时会报类似Blocked access to file /DemoProjectPath/public/images/logo-black.png↵的错误
  2. 而且路径storage_path('app/order-receipt/tmp/tmp.pdf')也需要有访问权限,可使用chmod 755解决

参考 ​

https://segmentfault.com/a/1190000018988358

https://wkhtmltopdf.org/usage/wkhtmltopdf.txt