夜雨聆风学习资料网

ARTICLE · 1035580

jquick-pdf 超详细入门教程:Java 轻量级 HTML 模板生成 PDF 工具

jquick-pdf 超详细入门教程:Java 轻量级 HTML 模板生成 PDF 工具

jquick-pdf 超详细入门教程:Java 轻量级 HTML 模板生成 PDF 工具

引入

Java 后端做 PDF 导出,最先遇到的往往不是业务难题,而是排版难题:用底层 API 逐个创建页面、字体、段落与表格,代码会迅速膨胀成一套“坐标计算器”,改一个标题或间距就要重新编译;中文字体、长文本分页与服务端输出,又会变成隐性维护成本。jquick-pdf 把数据和版式分开:Java 准备数据,类 HTML 模板描述页面,渲染器输出 PDF。本文先走通一次完整生成。

核心讲解

版本基线与入口类

本文以仓库事实 io.github.paohaijiao:jquick-pdfx:4.0.0 和 JDK 8+ 为准。核心入口是 com.github.paohaijiao.executor.JQuickPdfFactory,它接收模板、变量与页面配置,返回 PDF 的 byte[]。模板常用 <pdf><body>,固定文字必须用单引号(如 '订单确认单'),变量用 {...},已注册资源替换 &{...}

  • 布局与分页:按字体、边距与尺寸计算位置,并在超出页面时处理分页。
  • 渲染输出:PDFBox 渲染器写入内存流,工厂取出最终字节。
  • 工厂内部持有 JContext 与 JPdfConfig,因此一次请求应创建一次工厂,不要跨请求复用带有业务变量的实例。

    三种执行方式对比

    方法
    模板来源
    适用场景
    executeContent(String)
    内存字符串
    单元测试、动态拼装的短模板
    executeResource(String)
    classpath 资源
    随制品发布的版本化模板,如 "report.txt"
    executeFile(String)
    磁盘文件
    外置模板目录、需要单独更新的版式

    三者都返回 byte[],既可写文件,也可直接写 HTTP 响应流。

    bind 与 bindAll 语义

    bind(String,Object) 绑定单变量,bindAll(Map<String,Object>) 批量绑定;变量名必须与 {name} 只做取值替换,&{name} 用于图表、模板、树或 SVG 等已注册资源。变量应通过绑定传入,禁止把用户输入拼进标签或 style,否则可能破坏语法并引入注入风险。

    样式与单位要点

    样式写在 style 属性中,以分号分隔,属性名支持驼峰与连字符互为别名,可在同一声明中混用。尺寸可用 pxptmmcminpx 按 96 DPI 折算(1px = 0.75pt)。常用属性包括 widthheightminHeightmaxWidthrelativePositionmargin*padding*verticalAlignmentbackgroundColorborderborderRadiusopacity;文字可用 fontFamilyNamesfontSizefontColorbolditalicunderlinetextAlignmentcharacterSpacingborder 采用“类型 宽度 颜色”,如 solid 1px #999borderRadius 支持 1~4 个值。颜色支持颜色名、#RRGGBBrgb()/rgba() 与 linear-gradient

    需要提前知道的边界

    模板循环指令(如 for/each)、rowSpan/colSpan 合并单元格、直接渲染网络 URL 图片、表单提交动作与提交 URL、全局分页背景或全局水印、keepTogether 绝对禁止分页,这些能力在本文基线下均未证实,不应写进方案假设。

    实战说明

    Maven 依赖

    使用 JDK 8+、Maven 3.6+,pom.xml 只需加入核心依赖:

    <dependency>    <groupId>io.github.paohaijiao</groupId>    <artifactId>jquick-pdfx</artifactId>    <version>4.0.0</version></dependency>

    运行时由 Maven 传递引入 Apache PDFBox 3.0.x、ANTLR4 runtime 与 SLF4J API;模板由 ANTLR4 解析、PDFBox 直接绘制,无浏览器、无 headless Chrome、无本地动态库。首次接入先执行 mvn dependency:tree 排除版本冲突,再运行静态模板验证链路。

    QuickStartPdf 完整示例

    以下类可作为普通 Java 程序直接运行,输出当前目录的 quick-start.pdf

    import com.github.paohaijiao.executor.JQuickPdfFactory;import java.nio.file.Files;import java.nio.file.Paths;public class QuickStartPdf {    public static void main(String[] args) throws Exception {        String template = ""                + "<pdf><body>"                + "<h1style=\"fontSize:24;textAlignment:center;fontColor:#1f4e79\">'订单确认单'</h1>"                + "<p>'客户:'{orderNo}</p>"                + "<tablestyle=\"width:520px;border:solid1px #999\">"                + "<tr><th>'商品'</th><th>'数量'</th><th>'金额'</th></tr>"                + "<tr><td>'Java 技术书'</td><td>'2'</td><td>'98.00'</td></tr>"                + "</table></body></pdf>";        // 为本次文档绑定业务变量并执行模板        byte[] pdf = new JQuickPdfFactory()                .bind("customer", "张三")                .bind("orderNo", "NO-2026001")                .executeContent(template);        Files.write(Paths.get("quick-start.pdf"), pdf);    }}

    效果如下

    结果预期与验证

    执行后应得到可正常打开的 quick-start.pdf:标题居中呈蓝色,变量替换为实际值,表格带 1px 灰色边框。验证顺序固定为“文件生成 → 可打开 → 中文正常 → 数据一致 → 分页符合预期”;失败时先查标签闭合与单引号,再查绑定键名与样式。

    数据准备与选型边界

    报表通常在服务层把金额、日期与状态格式化为展示值,再通过 bind 注入模板,从而不被 ORM 字段名、空值与业务枚举牵着走;列表用 <list><li>,明细用 <table>,图片用 <image src="..." alt="...">,分页可用样例验证过的 <htmlPageBreak> 或 <areaBreak> 指定。选型上:相比 iText 与 PdfBox 的底层 API,它更适合结构化文档与快速迭代;相比浏览器截图,它无需 Chrome,部署更轻;但完整网页兼容与浏览器专属 CSS 仍需评估其他方案。

    总结

    • 五个节点决定成败:读入、解析、绑定、布局分页、渲染输出,排查应逐层验证。
    • 语法固定:文本用单引号,变量用 ${name},资源用 &{name},样式以分号分隔且支持驼峰/连字符别名。
    • 工程固定:先跑通静态模板,再依次加入绑定、样式、分页与真实数据。

    适用边界与常见误区:它面向规则明确的结构化业务文档,不是完整 HTML/CSS 实现,也不能替代底层绘图库;最常见的错误是遗漏文本单引号、跨请求复用携带变量的工厂、把用户输入拼进模板,以及在服务器上忽略中文字体。

    版本基线:jquick-pdfx 4.0.0、JDK 8+;许可证与版本强相关,上线前请核对 README 版本对照表;更多示例见 GitHub 仓库。

相关学习资料