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

推荐订阅源

Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
T
Troy Hunt's Blog
Scott Helme
Scott Helme
T
Threat Research - Cisco Blogs
T
Tenable Blog
L
LINUX DO - 热门话题
V
Visual Studio Blog
I
Intezer
Blog — PlanetScale
Blog — PlanetScale
Cisco Talos Blog
Cisco Talos Blog
A
Arctic Wolf
C
Cyber Attacks, Cyber Crime and Cyber Security
F
Fortinet All Blogs
aimingoo的专栏
aimingoo的专栏
Know Your Adversary
Know Your Adversary
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
N
Netflix TechBlog - Medium
SecWiki News
SecWiki News
I
InfoQ
Microsoft Security Blog
Microsoft Security Blog
Project Zero
Project Zero
W
WeLiveSecurity
Microsoft Azure Blog
Microsoft Azure Blog
A
About on SuperTechFans
Recorded Future
Recorded Future
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Vercel News
Vercel News
S
Securelist
Spread Privacy
Spread Privacy
L
LangChain Blog
云风的 BLOG
云风的 BLOG
G
Google Developers Blog
MongoDB | Blog
MongoDB | Blog
Google DeepMind News
Google DeepMind News
Recent Commits to openclaw:main
Recent Commits to openclaw:main
D
Darknet – Hacking Tools, Hacker News & Cyber Security
C
CERT Recently Published Vulnerability Notes
罗磊的独立博客
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
The Last Watchdog
The Last Watchdog
Attack and Defense Labs
Attack and Defense Labs
博客园 - 司徒正美
Help Net Security
Help Net Security
L
Lohrmann on Cybersecurity
人人都是产品经理
人人都是产品经理
Forbes - Security
Forbes - Security
Hacker News - Newest:
Hacker News - Newest: "LLM"
PCI Perspectives
PCI Perspectives
博客园 - 【当耐特】
T
Tor Project blog

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 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 几种方法 | mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 check the export on the very top of this document so we can use $do mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 mafeifan 的编程技术分享 运维自动化之ANSIBLE | mafeifan 的编程技术分享 延伸 -- 关于前端路由 xdebug 3 和 2 的区别
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