分享一个用 PHP 开发 PDF 文件生成工具,支持 HTML 模板、API 调用、Docker 部署

一、简介

  • 该工具采用前后端分离的开发方式,后端基于 ThinkPHP 框架(开发相关的API),前端使用Ant Design Pro框架(开发相关页面)
  • 提供多用户管理,PDF模板管理、审核、预览等功能,提供 PDF 生成的开放API
  • 主要功能特点是:可以通过调用相关接口,根据后台PDF模板或者根据提供HTML代码动态渲染生成 PDF 文件
  • 支持使用 Docker 一键快速部署启用
  • 该项目的github地址参考:github.com/luler/hello_pdf_templat...
  • 该项目的主要技术架构和工作原理参考下图:

Laravel

二、安装

  • 提前安装好Docker、docker-compose软件运行环境
  • 拉取源代码
    git clone https://github.com/luler/hello_pdf_template.git
  • 进入代码根目录,根据需要编辑docker-compose.yml配置文件,参考如下内容:
    version: '3'
    services:
    php_nginx:
      image: registry.cn-shenzhen.aliyuncs.com/luler/linux_php_nginx:php7.3
      restart: always
      privileged: true
      ports:
        - 12345:80
      volumes:
        - ./config/init.sh:/init.sh #初始化脚本
        - ./runtime/wwwlogs:/home/wwwlogs #nginx日志
        - ./code:/home/wwwroot #代码、sqlite数据
        - ./config/nginx/conf:/usr/local/nginx/conf #nginx配置
        - ./config/php/etc:/usr/local/php/etc #php-fpm配置
  • 直接在根目录下执行下面命令一键启动
    docker-compose up -d
    启动之后,服务正常运行,即可访问使用
    Laravel

三、使用

1. 登录后台,创建PDF模板

  • 安装完成之后,服务运行在12345端口上,可以打开浏览器访问:http://ip:12345/,默认登录账号密码:admin/admin
    Laravel

  • 进入模板列表,新增一个模板
    点击新增模板按钮
    Laravel
    填写模板内容,支持富文本、纯代码的编辑方式,兼容各种HTML语法。下面是测试简单的购物单模板(使用了thinkphp的模板渲染引擎)

    <h1>发票</h1>
    <p>发票号码:{$code}</p>
    <p>日期:{$date}</p>
    <p>客户:{$client}</p>
    <table border="1" cellspacing="0" style="border-collapse:collapse; width:100%">
      <thead>
          <tr>
              <th>商品</th>
              <th>图片</th>
              <th>数量</th>
              <th>单价</th>
              <th>金额</th>
          </tr>
      </thead>
      <tbody>
      {foreach $list as $key=>$vo } 
          <tr>
              <td>{$vo.name}</td>
              <td><img width=80 height=80 src="{$vo.image}"></td>
              <td>{$vo.num}</td>
              <td>{$vo.price}</td>
              <td>{$vo.money}</td>
          </tr>
      {/foreach}
          <tr>
              <td colspan="4">总计</td>
              <td>{$total_money}</td>
          </tr>
      </tbody>
    </table>
    <p>备注:感谢您的购买!</p>

    可以预览生成
    Laravel

2. 模板创建完成后,可以调用 API 生成PDF文件

  • 获取访问凭证接口
    接口(POST):/api/getAccessToken
    请求参数(json):
    {
      "type": 1, //默认1
      "appid": "admin", //账号
      "appsecret": "admin" //密码
    }
    返回(json):
    {
      "message": "获取成功",
      "code": 200,
      "info": {
          "access_token": "Bearer eyJ0eXAiOiJKV1Q...", //访问凭证
          "token_type": "Bearer",
          "expires_in": 864000, //有效时间,单位秒
          "user_info": { //用户信息
              "id": "1",
              "title": "admin",
              ...
          }
      }
    }
  • 根据后台模板创建PDF接口
    接口(POST):/api/downloadPdf
    请求参数(json):
    {
      "authorization": "Bearer eyJ0eXAiOiJKV1QiLCJhbG", //访问凭证
      "code": "689966350ed4d",  //模板代码
      "param": { //模板参数(thinkphp模板渲染引擎)
         "key": "value"
      }
    }
    返回(json):
    {
      "message": "获取成功",
      "code": 200,
      "info": {
          "file_url": "http://ip:12345/backend/pdf/689a0c01ec349.pdf" //生成临时PDF
      }
    }
  • 根据HTML格式内容渲染生成PDF文件接口
    接口(POST):/api/downloadPdf
    请求参数(json):
    {
      "authorization": "Bearer eyJ0eXAiOiJKV1QiLCJhbG", //访问凭证
      "content": "<h1>这是一个测试</h1><ul><li>1111111</li></ul>",  //HTML代码
      "render_direction": 1 //渲染方向,1-纵向(默认),2-横向
    }
    返回(json):
    {
      "message": "获取成功",
      "code": 200,
      "info": {
          "file_url": "http://ip:12345/backend/pdf/689a0c01ec349.pdf" //生成临时PDF
      }
    }
  • 在Postman中调用接口生成PDF文件示例截图
    Laravel

四、总结

  • 可以使用Docker快速部署,默认数据库是sqlite,无需外部依赖,但生产环境建议切换到mysql
  • 该工具定位赋能组件,生成的PDF文件默认不会永久保存,定期1天清理,可调整参数控制
  • 该工具可以作为系统开发的解耦组件,帮助业务系统快速生成各种特定模板的PDF文件

线上部署了一个临时试用:cas.luler.top/?search=62109f1f0ef2...

本作品采用《CC 协议》,转载必须注明作者和本文链接
我只想看看蓝天
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 4

目前我是用playwright/puppeteer 的 page->pdf 这种方式处理生成 PDF,你可以参考下。

3周前 评论
luler (楼主) 3周前
xiaoguo0426 (作者) 3周前
yangweijie

wkhtmltopdf 不是只要html支持的样式大部分都行吗?

3周前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!