Delivery receipt — generate this PDF with Java (Template)
Template1 页 A4 · 34 KB
Delivery receipt whose table spans pages, with a sign-off row at the bottom.

Output specs
- PDF pages
- 1
- Chart type
- Template
- Template lines
- 125
- Source lines
- 101
Java source · JQuickBiz79DeliveryReceipt.java
This is the complete test class that produced the PDF above — copy it and run as-is; see the quick-start section for the Maven dependency.
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Copyright (c) [2025-2099] Martin ([email protected])
*/
package com.github.paohaijiao.biz.scenario;
import com.github.paohaijiao.config.JPdfConfig;
import com.github.paohaijiao.executor.JQuickPdfFactory;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
public class JQuickBiz79DeliveryReceipt {
private static final String PDF_DIR = "D:/test/pdf/";
private static final String IMG_DIR = "D:/test/image/";
private static final String OUT_FILE = PDF_DIR + "79_delivery_receipt.pdf";
private static final String TEMPLATE = "report/biz/79_delivery_receipt.txt";
public static void main(String[] args) throws Exception {
new File(PDF_DIR).mkdirs();
new File(IMG_DIR).mkdirs();
// ---------- 1. 生成签名图片(模板 image src 按字面量引用固定路径) ----------
generateSignature(IMG_DIR + "79_sign.png", "赵一鸣");
// ---------- 2. 组织数据(普通 Map,无实体类)----------
Map<String, Object> data = new LinkedHashMap<String, Object>();
data.put("receiptNo", "HZ-2026-1019-0043");
data.put("receiverUnit", "××城市商业银行 信息科技部");
data.put("contact", "赵一鸣 021-6123-4567");
data.put("address", "××市浦东新区××路 88 号 JQ 大厦 12 层");
data.put("deliveryDate", "2026年10月19日");
List<String[]> items = new ArrayList<String[]>();
items.add(new String[]{"PDF 报表引擎安装介质(U 盘)", "V4.2.0", "个", "1", "含许可文件"});
items.add(new String[]{"企业版许可证书", "5 节点", "份", "1", "已激活"});
items.add(new String[]{"部署手册", "V4.2", "册", "2", ""});
items.add(new String[]{"运维手册", "V4.2", "册", "2", ""});
items.add(new String[]{"接口开发文档", "V4.2", "册", "2", "含示例代码"});
items.add(new String[]{"报表模板包(58 套)", "STD-2026", "套", "1", "压缩包"});
data.put("itemCount", items.size() + " 项");
String[] keys = {"name", "spec", "unit", "qty", "remark"};
for (int i = 0; i < items.size(); i++) {
for (int j = 0; j < keys.length; j++) {
data.put("it" + (i + 1) + "_" + keys[j], items.get(i)[j]);
}
}
// ---------- 3. 渲染 ----------
JPdfConfig config = new JPdfConfig();
config.getLayoutConfig().setFlexLayout(true);
config.getDoc().setMargins(Arrays.asList(48, 48, 55, 48));
config.getFooterConfig().setEnabled(true);
config.getFooterConfig().setFontSize(8);
config.getFooterConfig().setPageNumberFormat("第 %d 页");
JQuickPdfFactory factory = new JQuickPdfFactory(config);
factory.bindAll(data);
byte[] pdf = factory.executeResource(TEMPLATE);
FileOutputStream out = new FileOutputStream(OUT_FILE);
out.write(pdf);
out.close();
System.out.println("已生成:" + OUT_FILE);
}
/** 生成手写签名图片(楷体 + 轻微旋转),与 93 样板同一套绘图逻辑。 */
private static void generateSignature(String path, String name) throws IOException {
BufferedImage image = new BufferedImage(180, 88, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = image.createGraphics();
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.rotate(Math.toRadians(-3), 90, 44);
g.setColor(new Color(0x1B, 0x2A, 0x3A));
g.setFont(new Font("KaiTi", Font.PLAIN, 40));
g.drawString(name, 26, 60);
g.dispose();
ImageIO.write(image, "png", new File(path));
}
}Minimal invocation (3 lines)
Skip the full test class — the core is these three lines: bind the chart SVG, execute the template, get the PDF bytes. Copy them straight into your project.
// config 可省略;svg 来自 JChartRendererFactory.renderChart(...),见下方完整源码
byte[] pdf = new JQuickPdfFactory(config).executeResource("report/biz/79_delivery_receipt.txt");Template file · 79_delivery_receipt.txt
An HTML-like template with inline CSS that renders to PDF once bound to data. The full template is below — copy it or download the raw file.
<pdf>
<body>
// ---------- 页头 ----------
<div style="display:flex; justifyContent:space-between; borderBottom:2px solid #1F4E79; paddingBottom:6px; marginBottom:8px">
<div style="width:320px">
<h1 style="fontSize:18pt; bold:true; color:#1F4E79; characterSpacing:3pt">'交付收货回执'</h1>
</div>
<div style="width:180px; textAlignment:right">
<p style="fontSize:8.5pt; color:#5A6B7C">'回执单号'</p>
<p style="fontSize:10pt; bold:true; color:#1A2733">${receiptNo}</p>
</div>
</div>
// ---------- 收货信息 ----------
<table style="width:100%; fontSize:9pt">
<tr>
<td style="width:78px; padding:5px; backgroundColor:#E8EDF2; bold:true; border:1px solid #C3CDD8">'收货单位'</td>
<td style="width:170px; padding:5px; border:1px solid #C3CDD8">${receiverUnit}</td>
<td style="width:78px; padding:5px; backgroundColor:#E8EDF2; bold:true; border:1px solid #C3CDD8">'联系人'</td>
<td style="padding:5px; border:1px solid #C3CDD8">${contact}</td>
</tr>
<tr>
<td style="width:78px; padding:5px; backgroundColor:#E8EDF2; bold:true; border:1px solid #C3CDD8">'收货地址'</td>
<td style="padding:5px; border:1px solid #C3CDD8">${address}</td>
<td style="padding:5px; textAlign:center; border:1px solid #C3CDD8; color:#C3CDD8">'—'</td>
<td style="padding:5px; textAlign:center; border:1px solid #C3CDD8; color:#C3CDD8">'—'</td>
</tr>
<tr>
<td style="width:78px; padding:5px; backgroundColor:#E8EDF2; bold:true; border:1px solid #C3CDD8">'交付日期'</td>
<td style="width:170px; padding:5px; border:1px solid #C3CDD8">${deliveryDate}</td>
<td style="width:78px; padding:5px; backgroundColor:#E8EDF2; bold:true; border:1px solid #C3CDD8">'明细项数'</td>
<td style="padding:5px; border:1px solid #C3CDD8">${itemCount}</td>
</tr>
</table>
// ---------- 交付明细 ----------
<table style="width:100%; fontSize:8.5pt; marginTop:6px">
<tr>
<th style="width:34px; padding:5px; backgroundColor:#1F4E79; color:white; textAlign:center; border:1px solid #1F4E79">'序号'</th>
<th style="width:190px; padding:5px; backgroundColor:#1F4E79; color:white; textAlign:center; border:1px solid #1F4E79">'交付物名称'</th>
<th style="width:110px; padding:5px; backgroundColor:#1F4E79; color:white; textAlign:center; border:1px solid #1F4E79">'规格型号'</th>
<th style="width:40px; padding:5px; backgroundColor:#1F4E79; color:white; textAlign:center; border:1px solid #1F4E79">'单位'</th>
<th style="width:45px; padding:5px; backgroundColor:#1F4E79; color:white; textAlign:center; border:1px solid #1F4E79">'数量'</th>
<th style="padding:5px; backgroundColor:#1F4E79; color:white; textAlign:center; border:1px solid #1F4E79">'备注'</th>
</tr>
<tr>
<td style="padding:5px; textAlign:center; border:1px solid #C3CDD8">'1'</td>
<td style="padding:5px; border:1px solid #C3CDD8">${it1_name}</td>
<td style="padding:5px; border:1px solid #C3CDD8">${it1_spec}</td>
<td style="padding:5px; textAlign:center; border:1px solid #C3CDD8">${it1_unit}</td>
<td style="padding:5px; textAlign:right; border:1px solid #C3CDD8">${it1_qty}</td>
<td style="padding:5px; border:1px solid #C3CDD8">${it1_remark}</td>
</tr>
<tr>
<td style="padding:5px; textAlign:center; border:1px solid #C3CDD8">'2'</td>
<td style="padding:5px; border:1px solid #C3CDD8">${it2_name}</td>
<td style="padding:5px; border:1px solid #C3CDD8">${it2_spec}</td>
<td style="padding:5px; textAlign:center; border:1px solid #C3CDD8">${it2_unit}</td>
<td style="padding:5px; textAlign:right; border:1px solid #C3CDD8">${it2_qty}</td>
<td style="padding:5px; border:1px solid #C3CDD8">${it2_remark}</td>
</tr>
<tr>
<td style="padding:5px; textAlign:center; border:1px solid #C3CDD8">'3'</td>
<td style="padding:5px; border:1px solid #C3CDD8">${it3_name}</td>
<td style="padding:5px; border:1px solid #C3CDD8">${it3_spec}</td>
<td style="padding:5px; textAlign:center; border:1px solid #C3CDD8">${it3_unit}</td>
<td style="padding:5px; textAlign:right; border:1px solid #C3CDD8">${it3_qty}</td>
<td style="padding:5px; border:1px solid #C3CDD8">${it3_remark}</td>
</tr>
<tr>
<td style="padding:5px; textAlign:center; border:1px solid #C3CDD8">'4'</td>
<td style="padding:5px; border:1px solid #C3CDD8">${it4_name}</td>
<td style="padding:5px; border:1px solid #C3CDD8">${it4_spec}</td>
<td style="padding:5px; textAlign:center; border:1px solid #C3CDD8">${it4_unit}</td>
<td style="padding:5px; textAlign:right; border:1px solid #C3CDD8">${it4_qty}</td>
<td style="padding:5px; border:1px solid #C3CDD8">${it4_remark}</td>
</tr>
<tr>
<td style="padding:5px; textAlign:center; border:1px solid #C3CDD8">'5'</td>
<td style="padding:5px; border:1px solid #C3CDD8">${it5_name}</td>
<td style="padding:5px; border:1px solid #C3CDD8">${it5_spec}</td>
<td style="padding:5px; textAlign:center; border:1px solid #C3CDD8">${it5_unit}</td>
<td style="padding:5px; textAlign:right; border:1px solid #C3CDD8">${it5_qty}</td>
<td style="padding:5px; border:1px solid #C3CDD8">${it5_remark}</td>
</tr>
<tr>
<td style="padding:5px; textAlign:center; border:1px solid #C3CDD8">'6'</td>
<td style="padding:5px; border:1px solid #C3CDD8">${it6_name}</td>
<td style="padding:5px; border:1px solid #C3CDD8">${it6_spec}</td>
<td style="padding:5px; textAlign:center; border:1px solid #C3CDD8">${it6_unit}</td>
<td style="padding:5px; textAlign:right; border:1px solid #C3CDD8">${it6_qty}</td>
<td style="padding:5px; border:1px solid #C3CDD8">${it6_remark}</td>
</tr>
</table>
// ---------- 交付说明 ----------
<div style="borderLeft:4px solid #2F5597; background:#F7F9FC; padding:7px 9px; marginTop:8px">
<p style="fontSize:8.5pt; color:#333333">'1. 请收货人当面清点数量、检查外观与包装,确认无误后在下方签收栏签字。'</p>
<p style="fontSize:8.5pt; color:#333333">'2. 如发现短缺、破损或型号不符,请在备注栏注明,并于 24 小时内书面通知交付方。'</p>
<p style="fontSize:8.5pt; color:#333333">'3. 本回执一式两联,交付方与收货单位各执一联,签字盖章后生效。'</p>
</div>
// ---------- 签收栏(签名图片由 Java 生成到固定路径) ----------
<div style="display:flex; justifyContent:space-between; marginTop:16px">
<div style="width:155px; border:1px solid #C3CDD8; padding:7px">
<p style="fontSize:9pt; bold:true; color:#1F4E79">'交付人'</p>
<p style="fontSize:9pt; color:#5A6B7C; marginTop:16px">'签字:'</p>
<p style="fontSize:9pt; color:#5A6B7C; marginTop:8px">'日期:'</p>
</div>
<div style="width:155px; border:1px solid #C3CDD8; padding:7px">
<p style="fontSize:9pt; bold:true; color:#1F4E79">'收货人'</p>
<image src='D:/test/image/79_sign.png' style="width:90px; height:44px"></image>
<p style="fontSize:9pt; color:#5A6B7C; marginTop:4px">'日期:'</p>
</div>
<div style="width:155px; border:1px solid #C3CDD8; padding:7px">
<p style="fontSize:9pt; bold:true; color:#1F4E79">'收货单位(盖章)'</p>
<p style="fontSize:9pt; color:#5A6B7C; marginTop:16px">' '</p>
<p style="fontSize:9pt; color:#5A6B7C; marginTop:8px">'日期:'</p>
</div>
</div>
</body>
</pdf>More demos in this group
The PDF, preview image, template and source code on this page were all produced by a real JQuick-Pdf run and are free to copy into your own project.