Completion settlement — generate this PDF with Java (Template)
Template2 页 A4 · 71 KB
Multi-page settlement book: perforated seal strip, project name in page headers and paginated detail tables.

Output specs
- PDF pages
- 2
- Chart type
- Template
- Template lines
- 273
- Source lines
- 239
Java source · JQuickBiz81CompletionSettlement.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.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
public class JQuickBiz81CompletionSettlement {
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 + "81_completion_settlement.pdf";
private static final String TEMPLATE = "report/biz/81_completion_settlement.txt";
public static void main(String[] args) throws IOException {
new File(PDF_DIR).mkdirs();
new File(IMG_DIR).mkdirs();
// ---------- 1. 生成图片(双方公章 + 骑缝章条),模板按字面量路径引用 ----------
String sealOwner = IMG_DIR + "81_seal_owner.png";
String sealBuilder = IMG_DIR + "81_seal_builder.png";
generateSeal(sealOwner, "建设单位", "公章");
generateSeal(sealBuilder, "施工单位", "公章");
splitSealForRidge(sealBuilder, 4, IMG_DIR + "81_ridge_");
// ---------- 2. 组织数据(普通 Map,无实体类)----------
// 明细行:名称 / 单位 / 工程量 / 综合单价(合价由程序计算)
String[][] subs = {
{"土方开挖及回填", "m³", "12860", "38.50"},
{"C30 钢筋混凝土基础", "m³", "2380", "860.00"},
{"框架柱、梁混凝土浇筑", "m³", "4120", "920.00"},
{"钢筋制安(HRB400)", "t", "1860", "5280.00"},
{"砌体工程(加气混凝土砌块)", "m³", "1560", "420.00"},
{"屋面防水(SBS 卷材)", "m²", "6800", "96.00"},
{"外墙保温及真石漆", "m²", "9200", "168.00"},
{"铝合金门窗安装", "m²", "3400", "520.00"},
{"给排水管道安装", "m", "5600", "78.00"},
{"电气桥架及配管", "m", "12800", "46.00"},
{"消防喷淋系统", "m²", "18600", "62.00"},
{"通风空调设备安装", "台", "86", "8600.00"},
{"室内精装修(办公区)", "m²", "7200", "680.00"},
{"室外道路及绿化", "m²", "5400", "158.00"},
{"电梯采购与安装", "台", "4", "386000.00"},
{"弱电智能化系统", "项", "1", "1260000.00"},
{"临时设施及安全文明施工", "项", "1", "480000.00"}
};
String[][] changes = {
{"QZ-001", "地下室增加抗浮锚杆 126 根", "386000.00"},
{"QZ-002", "首层大堂石材由国产改为进口", "428000.00"},
{"QZ-003", "因设计变更空调主机由 3 台增至 4 台", "268000.00"},
{"QZ-004", "取消原设计中庭采光顶", "-196000.00"}
};
Map<String, Object> data = new LinkedHashMap<String, Object>();
data.put("settlementNo", "JS-2026-0086");
data.put("projectName", "××市科创中心一期建设工程");
data.put("ownerUnit", "××市城市建设投资集团有限公司");
data.put("builderUnit", "××建工集团第三工程有限公司");
data.put("settlementDate", "2026年10月19日");
data.put("contractAmount", "¥ 46,800,000.00(肆仟陆佰捌拾万元整)");
BigDecimal subTotal = BigDecimal.ZERO;
for (int i = 0; i < subs.length; i++) {
BigDecimal qty = new BigDecimal(subs[i][2]);
BigDecimal price = new BigDecimal(subs[i][3]);
BigDecimal amount = qty.multiply(price).setScale(2, BigDecimal.ROUND_HALF_UP);
subTotal = subTotal.add(amount);
data.put("spName" + (i + 1), subs[i][0]);
data.put("spUnit" + (i + 1), subs[i][1]);
data.put("spQty" + (i + 1), qty.toPlainString());
data.put("spPrice" + (i + 1), price.toPlainString());
data.put("spAmount" + (i + 1), amount.toPlainString());
}
BigDecimal changeTotal = BigDecimal.ZERO;
for (int i = 0; i < changes.length; i++) {
BigDecimal amount = new BigDecimal(changes[i][2]);
changeTotal = changeTotal.add(amount);
data.put("chNo" + (i + 1), changes[i][0]);
data.put("chContent" + (i + 1), changes[i][1]);
data.put("chAmount" + (i + 1), amount.toPlainString());
}
data.put("chTotal", changeTotal.toPlainString());
BigDecimal total = subTotal.add(changeTotal).setScale(2, BigDecimal.ROUND_HALF_UP);
data.put("totalWords", amountInWords(total));
data.put("totalPlain", total.toPlainString());
data.put("compiler", "张国强");
data.put("reviewer", "李慧");
data.put("approver", "王建平");
// ---------- 3. 渲染 ----------
JPdfConfig config = new JPdfConfig();
config.getLayoutConfig().setFlexLayout(true);
// 右侧留 26pt 供骑缝章细条使用
config.getDoc().setMargins(Arrays.asList(58, 76, 55, 50));
config.getHeaderConfig().setEnabled(true);
config.getHeaderConfig().setText(data.get("projectName") + " 竣工结算书");
config.getHeaderConfig().setFontSize(8);
config.getHeaderConfig().setHeight(34);
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);
java.nio.file.Files.write(new File(OUT_FILE).toPath(), pdf);
System.out.println("已生成:" + OUT_FILE);
}
/**
* 人民币大写(到分),与发票场景保持同一套换算规则。
*/
public static String amountInWords(BigDecimal amount) {
String[] digits = {"零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"};
String[] units = {"", "拾", "佰", "仟"};
String[] groups = {"", "万", "亿"};
BigDecimal scaled = amount.setScale(2, BigDecimal.ROUND_HALF_UP);
long integer = scaled.longValue();
int fraction = scaled.subtract(new BigDecimal(integer)).movePointRight(2).intValue();
String number = String.valueOf(integer);
StringBuilder result = new StringBuilder();
int groupIndex = 0;
boolean pendingZero = false;
while (number.length() > 0) {
int end = Math.max(0, number.length() - 4);
String group = number.substring(end);
number = number.substring(0, end);
if (Integer.parseInt(group) == 0) {
pendingZero = result.length() > 0;
groupIndex++;
continue;
}
StringBuilder part = new StringBuilder();
for (int i = 0; i < group.length(); i++) {
int d = group.charAt(i) - '0';
int pos = group.length() - 1 - i;
if (d == 0) {
if (part.length() > 0 && !part.toString().endsWith("零")) {
part.append("零");
}
} else {
part.append(digits[d]).append(units[pos]);
}
}
String text = part.toString();
if (text.endsWith("零")) {
text = text.substring(0, text.length() - 1);
}
if (pendingZero) {
result.insert(0, "零");
pendingZero = false;
}
result.insert(0, text + groups[groupIndex]);
groupIndex++;
}
if (result.length() == 0) {
result.append("零");
}
StringBuilder words = new StringBuilder(result).append("元");
if (fraction == 0) {
words.append("整");
} else {
int jiao = fraction / 10;
int fen = fraction % 10;
if (jiao > 0) {
words.append(digits[jiao]).append("角");
} else if (fen > 0) {
words.append("零");
}
if (fen > 0) {
words.append(digits[fen]).append("分");
}
}
return words.toString();
}
/** 生成简化公章(圆环 + 上方角色名 + 下方「公章」字样)。 */
private static void generateSeal(String path, String top, String bottom) throws IOException {
int size = 200;
BufferedImage image = new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = image.createGraphics();
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
Color red = new Color(0xC6, 0x28, 0x28);
g.setColor(red);
g.setStroke(new BasicStroke(6f));
g.drawOval(8, 8, size - 16, size - 16);
g.setFont(new Font("Microsoft YaHei", Font.BOLD, 17));
g.drawString(top, size / 2 - 34, 66);
g.setFont(new Font("Microsoft YaHei", Font.BOLD, 16));
g.drawString(bottom, size / 2 - 16, 132);
g.dispose();
ImageIO.write(image, "png", new File(path));
}
/**
* 骑缝章:把公章图按纵向切成 strips 条,输出到固定前缀路径。
* 打印后沿装订线裁切,各页边缘的细条拼起来就是一枚完整的章。
*/
public static List<String> splitSealForRidge(String sealPath, int strips, String prefix) throws IOException {
BufferedImage source = ImageIO.read(new File(sealPath));
int stripWidth = Math.max(1, source.getWidth() / strips);
List<String> paths = new ArrayList<String>();
for (int i = 0; i < strips; i++) {
int x = i * stripWidth;
int w = Math.min(stripWidth, source.getWidth() - x);
BufferedImage part = source.getSubimage(x, 0, w, source.getHeight());
String path = prefix + i + ".png";
ImageIO.write(part, "png", new File(path));
paths.add(path);
}
return paths;
}
}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/81_completion_settlement.txt");Template file · 81_completion_settlement.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>
<h1 style="fontSize:20pt; bold:true; color:#1A2733; textAlignment:center; characterSpacing:6pt">'工程竣工结算书'</h1>
<p style="fontSize:9pt; color:#5A6B7C; textAlignment:center; marginBottom:10px">'结算书编号:'${settlementNo}</p>
<!-- 封面信息 -->
<table style="width:100%; fontSize:9.5pt">
<tr>
<td style="width:110px; padding:6px; backgroundColor:#E8EDF2; bold:true; border:1px solid #C3CDD8">'工程名称'</td>
<td style="padding:6px; border:1px solid #C3CDD8">${projectName}</td>
</tr>
<tr>
<td style="padding:6px; backgroundColor:#E8EDF2; bold:true; border:1px solid #C3CDD8">'建设单位'</td>
<td style="padding:6px; border:1px solid #C3CDD8">${ownerUnit}</td>
</tr>
<tr>
<td style="padding:6px; backgroundColor:#E8EDF2; bold:true; border:1px solid #C3CDD8">'施工单位'</td>
<td style="padding:6px; border:1px solid #C3CDD8">${builderUnit}</td>
</tr>
<tr>
<td style="padding:6px; backgroundColor:#E8EDF2; bold:true; border:1px solid #C3CDD8">'结算日期'</td>
<td style="padding:6px; border:1px solid #C3CDD8">${settlementDate}</td>
</tr>
<tr>
<td style="padding:6px; backgroundColor:#E8EDF2; bold:true; border:1px solid #C3CDD8">'合同金额'</td>
<td style="padding:6px; border:1px solid #C3CDD8">${contractAmount}</td>
</tr>
</table>
<!-- 一、分项工程结算明细 -->
<h2 style="fontSize:11pt; bold:true; color:#1F4E79; borderLeft:3px solid #1F4E79; paddingLeft:6px; marginTop:10px; marginBottom:5px">'一、分项工程结算明细'</h2>
<table style="width:100%; fontSize:8.5pt">
<tr>
<th style="padding:5px; backgroundColor:#1F4E79; color:white; textAlign:center; border:1px solid #1F4E79; width:36px">'序号'</th>
<th style="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; width:40px">'单位'</th>
<th style="padding:5px; backgroundColor:#1F4E79; color:white; textAlign:center; border:1px solid #1F4E79; width:64px">'工程量'</th>
<th style="padding:5px; backgroundColor:#1F4E79; color:white; textAlign:center; border:1px solid #1F4E79; width:76px">'综合单价'</th>
<th style="padding:5px; backgroundColor:#1F4E79; color:white; textAlign:center; border:1px solid #1F4E79; width:88px">'合价(元)'</th>
</tr>
<tr>
<td style="padding:5px; textAlign:center; border:1px solid #C3CDD8">'1'</td>
<td style="padding:5px; border:1px solid #C3CDD8">${spName1}</td>
<td style="padding:5px; textAlign:center; border:1px solid #C3CDD8">${spUnit1}</td>
<td style="padding:5px; textAlign:right; border:1px solid #C3CDD8">${spQty1}</td>
<td style="padding:5px; textAlign:right; border:1px solid #C3CDD8">${spPrice1}</td>
<td style="padding:5px; textAlign:right; border:1px solid #C3CDD8">${spAmount1}</td>
</tr>
<tr>
<td style="padding:5px; textAlign:center; border:1px solid #C3CDD8">'2'</td>
<td style="padding:5px; border:1px solid #C3CDD8">${spName2}</td>
<td style="padding:5px; textAlign:center; border:1px solid #C3CDD8">${spUnit2}</td>
<td style="padding:5px; textAlign:right; border:1px solid #C3CDD8">${spQty2}</td>
<td style="padding:5px; textAlign:right; border:1px solid #C3CDD8">${spPrice2}</td>
<td style="padding:5px; textAlign:right; border:1px solid #C3CDD8">${spAmount2}</td>
</tr>
<tr>
<td style="padding:5px; textAlign:center; border:1px solid #C3CDD8">'3'</td>
<td style="padding:5px; border:1px solid #C3CDD8">${spName3}</td>
<td style="padding:5px; textAlign:center; border:1px solid #C3CDD8">${spUnit3}</td>
<td style="padding:5px; textAlign:right; border:1px solid #C3CDD8">${spQty3}</td>
<td style="padding:5px; textAlign:right; border:1px solid #C3CDD8">${spPrice3}</td>
<td style="padding:5px; textAlign:right; border:1px solid #C3CDD8">${spAmount3}</td>
</tr>
<tr>
<td style="padding:5px; textAlign:center; border:1px solid #C3CDD8">'4'</td>
<td style="padding:5px; border:1px solid #C3CDD8">${spName4}</td>
<td style="padding:5px; textAlign:center; border:1px solid #C3CDD8">${spUnit4}</td>
<td style="padding:5px; textAlign:right; border:1px solid #C3CDD8">${spQty4}</td>
<td style="padding:5px; textAlign:right; border:1px solid #C3CDD8">${spPrice4}</td>
<td style="padding:5px; textAlign:right; border:1px solid #C3CDD8">${spAmount4}</td>
</tr>
<tr>
<td style="padding:5px; textAlign:center; border:1px solid #C3CDD8">'5'</td>
<td style="padding:5px; border:1px solid #C3CDD8">${spName5}</td>
<td style="padding:5px; textAlign:center; border:1px solid #C3CDD8">${spUnit5}</td>
<td style="padding:5px; textAlign:right; border:1px solid #C3CDD8">${spQty5}</td>
<td style="padding:5px; textAlign:right; border:1px solid #C3CDD8">${spPrice5}</td>
<td style="padding:5px; textAlign:right; border:1px solid #C3CDD8">${spAmount5}</td>
</tr>
<tr>
<td style="padding:5px; textAlign:center; border:1px solid #C3CDD8">'6'</td>
<td style="padding:5px; border:1px solid #C3CDD8">${spName6}</td>
<td style="padding:5px; textAlign:center; border:1px solid #C3CDD8">${spUnit6}</td>
<td style="padding:5px; textAlign:right; border:1px solid #C3CDD8">${spQty6}</td>
<td style="padding:5px; textAlign:right; border:1px solid #C3CDD8">${spPrice6}</td>
<td style="padding:5px; textAlign:right; border:1px solid #C3CDD8">${spAmount6}</td>
</tr>
<tr>
<td style="padding:5px; textAlign:center; border:1px solid #C3CDD8">'7'</td>
<td style="padding:5px; border:1px solid #C3CDD8">${spName7}</td>
<td style="padding:5px; textAlign:center; border:1px solid #C3CDD8">${spUnit7}</td>
<td style="padding:5px; textAlign:right; border:1px solid #C3CDD8">${spQty7}</td>
<td style="padding:5px; textAlign:right; border:1px solid #C3CDD8">${spPrice7}</td>
<td style="padding:5px; textAlign:right; border:1px solid #C3CDD8">${spAmount7}</td>
</tr>
<tr>
<td style="padding:5px; textAlign:center; border:1px solid #C3CDD8">'8'</td>
<td style="padding:5px; border:1px solid #C3CDD8">${spName8}</td>
<td style="padding:5px; textAlign:center; border:1px solid #C3CDD8">${spUnit8}</td>
<td style="padding:5px; textAlign:right; border:1px solid #C3CDD8">${spQty8}</td>
<td style="padding:5px; textAlign:right; border:1px solid #C3CDD8">${spPrice8}</td>
<td style="padding:5px; textAlign:right; border:1px solid #C3CDD8">${spAmount8}</td>
</tr>
<tr>
<td style="padding:5px; textAlign:center; border:1px solid #C3CDD8">'9'</td>
<td style="padding:5px; border:1px solid #C3CDD8">${spName9}</td>
<td style="padding:5px; textAlign:center; border:1px solid #C3CDD8">${spUnit9}</td>
<td style="padding:5px; textAlign:right; border:1px solid #C3CDD8">${spQty9}</td>
<td style="padding:5px; textAlign:right; border:1px solid #C3CDD8">${spPrice9}</td>
<td style="padding:5px; textAlign:right; border:1px solid #C3CDD8">${spAmount9}</td>
</tr>
<tr>
<td style="padding:5px; textAlign:center; border:1px solid #C3CDD8">'10'</td>
<td style="padding:5px; border:1px solid #C3CDD8">${spName10}</td>
<td style="padding:5px; textAlign:center; border:1px solid #C3CDD8">${spUnit10}</td>
<td style="padding:5px; textAlign:right; border:1px solid #C3CDD8">${spQty10}</td>
<td style="padding:5px; textAlign:right; border:1px solid #C3CDD8">${spPrice10}</td>
<td style="padding:5px; textAlign:right; border:1px solid #C3CDD8">${spAmount10}</td>
</tr>
<tr>
<td style="padding:5px; textAlign:center; border:1px solid #C3CDD8">'11'</td>
<td style="padding:5px; border:1px solid #C3CDD8">${spName11}</td>
<td style="padding:5px; textAlign:center; border:1px solid #C3CDD8">${spUnit11}</td>
<td style="padding:5px; textAlign:right; border:1px solid #C3CDD8">${spQty11}</td>
<td style="padding:5px; textAlign:right; border:1px solid #C3CDD8">${spPrice11}</td>
<td style="padding:5px; textAlign:right; border:1px solid #C3CDD8">${spAmount11}</td>
</tr>
<tr>
<td style="padding:5px; textAlign:center; border:1px solid #C3CDD8">'12'</td>
<td style="padding:5px; border:1px solid #C3CDD8">${spName12}</td>
<td style="padding:5px; textAlign:center; border:1px solid #C3CDD8">${spUnit12}</td>
<td style="padding:5px; textAlign:right; border:1px solid #C3CDD8">${spQty12}</td>
<td style="padding:5px; textAlign:right; border:1px solid #C3CDD8">${spPrice12}</td>
<td style="padding:5px; textAlign:right; border:1px solid #C3CDD8">${spAmount12}</td>
</tr>
<tr>
<td style="padding:5px; textAlign:center; border:1px solid #C3CDD8">'13'</td>
<td style="padding:5px; border:1px solid #C3CDD8">${spName13}</td>
<td style="padding:5px; textAlign:center; border:1px solid #C3CDD8">${spUnit13}</td>
<td style="padding:5px; textAlign:right; border:1px solid #C3CDD8">${spQty13}</td>
<td style="padding:5px; textAlign:right; border:1px solid #C3CDD8">${spPrice13}</td>
<td style="padding:5px; textAlign:right; border:1px solid #C3CDD8">${spAmount13}</td>
</tr>
<tr>
<td style="padding:5px; textAlign:center; border:1px solid #C3CDD8">'14'</td>
<td style="padding:5px; border:1px solid #C3CDD8">${spName14}</td>
<td style="padding:5px; textAlign:center; border:1px solid #C3CDD8">${spUnit14}</td>
<td style="padding:5px; textAlign:right; border:1px solid #C3CDD8">${spQty14}</td>
<td style="padding:5px; textAlign:right; border:1px solid #C3CDD8">${spPrice14}</td>
<td style="padding:5px; textAlign:right; border:1px solid #C3CDD8">${spAmount14}</td>
</tr>
<tr>
<td style="padding:5px; textAlign:center; border:1px solid #C3CDD8">'15'</td>
<td style="padding:5px; border:1px solid #C3CDD8">${spName15}</td>
<td style="padding:5px; textAlign:center; border:1px solid #C3CDD8">${spUnit15}</td>
<td style="padding:5px; textAlign:right; border:1px solid #C3CDD8">${spQty15}</td>
<td style="padding:5px; textAlign:right; border:1px solid #C3CDD8">${spPrice15}</td>
<td style="padding:5px; textAlign:right; border:1px solid #C3CDD8">${spAmount15}</td>
</tr>
<tr>
<td style="padding:5px; textAlign:center; border:1px solid #C3CDD8">'16'</td>
<td style="padding:5px; border:1px solid #C3CDD8">${spName16}</td>
<td style="padding:5px; textAlign:center; border:1px solid #C3CDD8">${spUnit16}</td>
<td style="padding:5px; textAlign:right; border:1px solid #C3CDD8">${spQty16}</td>
<td style="padding:5px; textAlign:right; border:1px solid #C3CDD8">${spPrice16}</td>
<td style="padding:5px; textAlign:right; border:1px solid #C3CDD8">${spAmount16}</td>
</tr>
<tr>
<td style="padding:5px; textAlign:center; border:1px solid #C3CDD8">'17'</td>
<td style="padding:5px; border:1px solid #C3CDD8">${spName17}</td>
<td style="padding:5px; textAlign:center; border:1px solid #C3CDD8">${spUnit17}</td>
<td style="padding:5px; textAlign:right; border:1px solid #C3CDD8">${spQty17}</td>
<td style="padding:5px; textAlign:right; border:1px solid #C3CDD8">${spPrice17}</td>
<td style="padding:5px; textAlign:right; border:1px solid #C3CDD8">${spAmount17}</td>
</tr>
</table>
<!-- 二、签证变更清单 -->
<h2 style="fontSize:11pt; bold:true; color:#1F4E79; borderLeft:3px solid #1F4E79; paddingLeft:6px; marginTop:10px; marginBottom:5px">'二、签证变更清单'</h2>
<table style="width:100%; fontSize:8.5pt">
<tr>
<th style="padding:5px; backgroundColor:#1F4E79; color:white; textAlign:center; border:1px solid #1F4E79; width:70px">'编号'</th>
<th style="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; width:110px">'金额(元)'</th>
</tr>
<tr>
<td style="padding:5px; textAlign:center; border:1px solid #C3CDD8">${chNo1}</td>
<td style="padding:5px; border:1px solid #C3CDD8">${chContent1}</td>
<td style="padding:5px; textAlign:right; border:1px solid #C3CDD8">${chAmount1}</td>
</tr>
<tr>
<td style="padding:5px; textAlign:center; border:1px solid #C3CDD8">${chNo2}</td>
<td style="padding:5px; border:1px solid #C3CDD8">${chContent2}</td>
<td style="padding:5px; textAlign:right; border:1px solid #C3CDD8">${chAmount2}</td>
</tr>
<tr>
<td style="padding:5px; textAlign:center; border:1px solid #C3CDD8">${chNo3}</td>
<td style="padding:5px; border:1px solid #C3CDD8">${chContent3}</td>
<td style="padding:5px; textAlign:right; border:1px solid #C3CDD8">${chAmount3}</td>
</tr>
<tr>
<td style="padding:5px; textAlign:center; border:1px solid #C3CDD8">${chNo4}</td>
<td style="padding:5px; border:1px solid #C3CDD8">${chContent4}</td>
<td style="padding:5px; textAlign:right; border:1px solid #C3CDD8">${chAmount4}</td>
</tr>
<tr>
<td style="padding:5px; border:1px solid #C3CDD8; bold:true">'签证变更合计'</td>
<td style="padding:5px; border:1px solid #C3CDD8">'—'</td>
<td style="padding:5px; textAlign:right; border:1px solid #C3CDD8; bold:true">${chTotal}</td>
</tr>
</table>
<!-- 三、结算总金额 -->
<h2 style="fontSize:11pt; bold:true; color:#1F4E79; borderLeft:3px solid #1F4E79; paddingLeft:6px; marginTop:10px; marginBottom:5px">'三、结算总金额'</h2>
<table style="width:100%; fontSize:9.5pt">
<tr>
<td style="width:100px; padding:6px; backgroundColor:#E8EDF2; bold:true; border:1px solid #C3CDD8">'大写金额'</td>
<td style="padding:6px; border:1px solid #C3CDD8; bold:true; color:#B71C1C">${totalWords}</td>
</tr>
<tr>
<td style="padding:6px; backgroundColor:#E8EDF2; bold:true; border:1px solid #C3CDD8">'小写金额'</td>
<td style="padding:6px; border:1px solid #C3CDD8; bold:true; color:#B71C1C">'¥'${totalPlain}</td>
</tr>
</table>
<p style="fontSize:8.5pt; color:#5A6B7C; marginTop:6px">'说明:本结算书依据施工合同、竣工图纸、现场签证及变更指令编制,经建设、施工双方核对确认后作为竣工结算与工程款支付的依据。'</p>
<!-- 四、编制与审核 -->
<h2 style="fontSize:11pt; bold:true; color:#1F4E79; borderLeft:3px solid #1F4E79; paddingLeft:6px; marginTop:10px; marginBottom:5px">'四、编制与审核'</h2>
<div style="display:flex; justifyContent:space-between; marginTop:4px">
<div style="width:32%; borderTop:1px solid #5A6B7C; paddingTop:4px">
<p style="fontSize:9pt; color:#5A6B7C; textAlignment:center">'编制人:'${compiler}</p>
<p style="fontSize:8pt; color:#8a939b; textAlignment:center; marginTop:16px">'(签字)'</p>
</div>
<div style="width:32%; borderTop:1px solid #5A6B7C; paddingTop:4px">
<p style="fontSize:9pt; color:#5A6B7C; textAlignment:center">'审核人:'${reviewer}</p>
<p style="fontSize:8pt; color:#8a939b; textAlignment:center; marginTop:16px">'(签字)'</p>
</div>
<div style="width:32%; borderTop:1px solid #5A6B7C; paddingTop:4px">
<p style="fontSize:9pt; color:#5A6B7C; textAlignment:center">'审批人:'${approver}</p>
<p style="fontSize:8pt; color:#8a939b; textAlignment:center; marginTop:16px">'(签字)'</p>
</div>
</div>
<!-- 双方公章 -->
<div style="display:flex; justifyContent:space-between; marginTop:18px">
<div style="width:49%">
<p style="fontSize:9pt; color:#5A6B7C">'建设单位(盖章)'</p>
<p style="fontSize:9pt; bold:true; color:#1A2733">${ownerUnit}</p>
<image src='D:/test/image/81_seal_owner.png' style="width:92px; height:92px"></image>
</div>
<div style="width:49%">
<p style="fontSize:9pt; color:#5A6B7C">'施工单位(盖章)'</p>
<p style="fontSize:9pt; bold:true; color:#1A2733">${builderUnit}</p>
<image src='D:/test/image/81_seal_builder.png' style="width:92px; height:92px"></image>
</div>
</div>
<!-- 骑缝章细条 -->
<div style="marginTop:10px">
<p style="fontSize:7.5pt; color:#8a939b">'骑缝章条(打印后沿右侧装订线裁切,与各页边缘切口拼合形成骑缝章):'</p>
<div style="display:flex; justifyContent:space-between; marginTop:3px">
<image src='D:/test/image/81_ridge_0.png' style="width:14px; height:92px"></image>
<image src='D:/test/image/81_ridge_1.png' style="width:14px; height:92px"></image>
<image src='D:/test/image/81_ridge_2.png' style="width:14px; height:92px"></image>
<image src='D:/test/image/81_ridge_3.png' style="width:14px; height:92px"></image>
</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.