跳转到内容

Java 生成「物资入库单」PDF 示例(Template)

JQuick-Pdf场景 Demo

Template2 页 A4 · 50 KB

物资入库单表格版式,仓储入库留档。

下载 PDF 文件查看模板原始文件返回全部示例

物资入库单 — Template
渲染效果

输出规格

PDF 页数
2
图表类型
Template
模板行数
306
源码行数
217

Java 源码 · JQuickBiz94MaterialInbound.java

以下代码即生成上方 PDF 的完整测试类,可直接复制运行;Maven 依赖见快速开始章节。

/*
 * 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.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.Map;

public class JQuickBiz94MaterialInbound {

    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 + "94_material_inbound.pdf";
    private static final String TEMPLATE = "report/biz/94_material_inbound.txt";

    /** 明细行原始数据:编码 / 名称 / 规格 / 单位 / 数量 / 单价。 */
    private static final String[][] ITEMS = {
            {"WL-1001", "热轧钢板", "Q235B 6mm×1500×6000", "张", "120", "386.00"},
            {"WL-1002", "镀锌钢管", "DN50 × 3.5mm", "m", "860", "28.60"},
            {"WL-1003", "角钢", "L50×50×5", "m", "1200", "18.40"},
            {"WL-1004", "六角螺栓", "M12×60 8.8 级", "套", "8000", "1.35"},
            {"WL-1005", "平垫圈", "M12 镀锌", "个", "16000", "0.18"},
            {"WL-1006", "电焊条", "J422 Φ3.2", "kg", "500", "9.80"},
            {"WL-1007", "二氧化碳气体", "40L / 瓶", "瓶", "60", "85.00"},
            {"WL-1008", "砂纸", "240 目", "张", "2000", "0.65"},
            {"WL-1009", "防锈底漆", "环氧富锌 20kg/桶", "桶", "40", "268.00"},
            {"WL-1010", "面漆", "丙烯酸聚氨酯 18kg/桶", "桶", "36", "312.00"},
            {"WL-1011", "稀释剂", "X-7 15kg/桶", "桶", "20", "146.00"},
            {"WL-1012", "安全帽", "ABS 透气型 白色", "顶", "80", "32.00"},
            {"WL-1013", "反光背心", "涤纶 荧光黄", "件", "100", "24.50"},
            {"WL-1014", "劳保手套", "丁腈涂层", "副", "400", "6.80"},
            {"WL-1015", "防护面罩", "焊接专用", "个", "40", "58.00"},
            {"WL-1016", "电缆", "YJV22 4×25", "m", "620", "96.50"},
            {"WL-1017", "配电箱", "XL-21 户外型", "台", "6", "1860.00"},
            {"WL-1018", "LED 投光灯", "200W IP66", "套", "48", "268.00"},
            {"WL-1019", "镀锌桥架", "200×100 含盖板", "m", "380", "62.00"},
            {"WL-1020", "接线端子", "UK-2.5", "个", "3000", "0.95"}};

    public static void main(String[] args) throws IOException {
        mkdirs();
        generateSeal(IMG_DIR + "94_seal.png", "中央仓库");

        Map<String, Object> data = new LinkedHashMap<String, Object>();
        data.put("orderNo", "RK-2026-03-0215");
        data.put("supplier", "××钢铁物资有限公司");
        data.put("warehouse", "××建工集团 中央仓库(A 区)");
        data.put("inboundDate", "2026年3月18日");
        data.put("purchaseNo", "CG-2026-0087");
        data.put("operator", "刘承");
        data.put("keeper", "孙慧");

        BigDecimal totalAmount = BigDecimal.ZERO;
        int totalQty = 0;
        for (int i = 0; i < ITEMS.length; i++) {
            String[] row = ITEMS[i];
            int qty = Integer.parseInt(row[4]);
            BigDecimal amount = new BigDecimal(row[5]).multiply(new BigDecimal(qty))
                    .setScale(2, RoundingMode.HALF_UP);
            totalQty += qty;
            totalAmount = totalAmount.add(amount);
            data.put("iCode" + (i + 1), row[0]);
            data.put("iName" + (i + 1), row[1]);
            data.put("iSpec" + (i + 1), row[2]);
            data.put("iUnit" + (i + 1), row[3]);
            data.put("iQty" + (i + 1), row[4]);
            data.put("iPrice" + (i + 1), row[5]);
            data.put("iAmount" + (i + 1), amount.toPlainString());
        }
        data.put("totalQty", totalQty);
        data.put("totalAmount", totalAmount.toPlainString());
        data.put("amountWords", amountInWords(totalAmount));
        data.put("acceptResult", "经清点数量、核对规格型号与质保资料,全部符合采购订单要求,其中钢材已抽样送检,"
                + "质保书、合格证、材质单齐全,验收合格,准予入库。");

        JPdfConfig config = new JPdfConfig();
        config.getLayoutConfig().setFlexLayout(true);
        config.getDoc().setMargins(Arrays.asList(52, 58, 52, 58));
        config.getHeaderConfig().setEnabled(true);
        config.getHeaderConfig().setText("物资入库单 RK-2026-03-0215");
        config.getHeaderConfig().setFontSize(8);
        config.getHeaderConfig().setHeight(32);
        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);
    }

    private static void mkdirs() {
        new File(PDF_DIR).mkdirs();
        new File(IMG_DIR).mkdirs();
    }

    /**
     * 人民币金额大写(到分)。示例:1234.50 → 壹仟贰佰叁拾肆元伍角整。
     */
    public static String amountInWords(BigDecimal amount) {
        String[] digits = {"零", "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖"};
        String[] units = {"", "拾", "佰", "仟"};
        String[] groups = {"", "万", "亿"};
        BigDecimal scaled = amount.setScale(2, RoundingMode.HALF_UP);
        long integer = scaled.longValue();
        int fraction = scaled.subtract(new BigDecimal(integer)).movePointRight(2).intValue();

        StringBuilder result = new StringBuilder();
        if (integer == 0) {
            result.append("零");
        } else {
            String number = String.valueOf(integer);
            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);
                int groupValue = Integer.parseInt(group);
                if (groupValue == 0) {
                    pendingZero = result.length() > 0;
                    groupIndex++;
                    continue;
                }
                if (pendingZero) {
                    result.insert(0, "零");
                    pendingZero = false;
                }
                StringBuilder groupText = new StringBuilder();
                char[] cs = group.toCharArray();
                boolean zeroFlag = false;
                for (int i = 0; i < cs.length; i++) {
                    int digit = cs[i] - '0';
                    int power = cs.length - 1 - i;
                    if (digit == 0) {
                        zeroFlag = true;
                    } else {
                        if (zeroFlag && groupText.length() > 0) {
                            groupText.append("零");
                        }
                        zeroFlag = false;
                        groupText.append(digits[digit]).append(units[power]);
                    }
                }
                result.insert(0, groupText.append(groups[groupIndex]).toString());
                groupIndex++;
            }
        }
        result.append("元");
        int jiao = fraction / 10;
        int fen = fraction % 10;
        if (jiao == 0 && fen == 0) {
            result.append("整");
        } else {
            if (jiao > 0) {
                result.append(digits[jiao]).append("角");
            } else {
                result.append("零");
            }
            if (fen > 0) {
                result.append(digits[fen]).append("分");
            } else {
                result.append("整");
            }
        }
        return result.toString();
    }

    /** 生成入库专用章(圆章 + 外圈文字)。 */
    private static void generateSeal(String path, String warehouse) 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, 15));
        g.drawString(warehouse, 14, 56);
        g.setFont(new Font("Microsoft YaHei", Font.BOLD, 14));
        g.drawString("入库专用", 24, size / 2 + 16);
        g.setFont(new Font("Microsoft YaHei", Font.PLAIN, 11));
        g.drawString("2026-03-18", 44, size / 2 + 34);
        g.dispose();
        ImageIO.write(image, "png", new File(path));
    }
}

最小调用(3 行)

不想读完整测试类?核心就是这三行:绑定图表 SVG,执行模板,拿到 PDF 字节流。可直接复制到你的项目里。

// config 可省略;svg 来自 JChartRendererFactory.renderChart(...),见下方完整源码
byte[] pdf = new JQuickPdfFactory(config).executeResource("report/biz/94_material_inbound.txt");

模板文件 · 94_material_inbound.txt

类 HTML + 内联 CSS 的模板语法,绑定数据后渲染为 PDF。下方为完整模板,可直接复制,也可下载原始文件。

<pdf>
<body>

  <h1 style="fontSize:19pt; bold:true; color:#1A2733; textAlignment:center; characterSpacing:6pt">'物 资 入 库 单'</h1>
  <p style="fontSize:9pt; color:#5A6B7C; textAlignment:center; marginBottom:8px">'INBOUND RECEIPT '${orderNo}</p>

  <table style="width:100%; fontSize:9pt; marginBottom:8px">
    <tr>
      <td style="width:72px; padding:5px; backgroundColor:#E8EDF2; bold:true; border:1px solid #C3CDD8">'入库单号'</td>
      <td style="padding:5px; border:1px solid #C3CDD8">${orderNo}</td>
      <td style="width:72px; padding:5px; backgroundColor:#E8EDF2; bold:true; border:1px solid #C3CDD8">'入库日期'</td>
      <td style="padding:5px; border:1px solid #C3CDD8">${inboundDate}</td>
    </tr>
    <tr>
      <td style="padding:5px; backgroundColor:#E8EDF2; bold:true; border:1px solid #C3CDD8">'供应商'</td>
      <td style="padding:5px; border:1px solid #C3CDD8">${supplier}</td>
      <td style="padding:5px; backgroundColor:#E8EDF2; bold:true; border:1px solid #C3CDD8">'入库仓库'</td>
      <td style="padding:5px; border:1px solid #C3CDD8">${warehouse}</td>
    </tr>
    <tr>
      <td style="padding:5px; backgroundColor:#E8EDF2; bold:true; border:1px solid #C3CDD8">'采购单号'</td>
      <td style="padding:5px; border:1px solid #C3CDD8">${purchaseNo}</td>
      <td style="padding:5px; backgroundColor:#E8EDF2; bold:true; border:1px solid #C3CDD8">'经办人'</td>
      <td style="padding:5px; border:1px solid #C3CDD8">${operator}'  '${keeper}</td>
    </tr>
  </table>

  <!-- 明细表:第 1 页(1~18 项) -->
  <table style="width:100%; fontSize:8pt">
    <tr>
      <th style="padding:5px; backgroundColor:#1F4E79; color:white; textAlign:center; border:1px solid #1F4E79; width:5%">'序'</th>
      <th style="padding:5px; backgroundColor:#1F4E79; color:white; textAlign:center; border:1px solid #1F4E79; width:13%">'物资编码'</th>
      <th style="padding:5px; backgroundColor:#1F4E79; color:white; textAlign:center; border:1px solid #1F4E79; width:22%">'物资名称'</th>
      <th style="padding:5px; backgroundColor:#1F4E79; color:white; textAlign:center; border:1px solid #1F4E79; width:19%">'规格型号'</th>
      <th style="padding:5px; backgroundColor:#1F4E79; color:white; textAlign:center; border:1px solid #1F4E79; width:7%">'单位'</th>
      <th style="padding:5px; backgroundColor:#1F4E79; color:white; textAlign:center; border:1px solid #1F4E79; width:9%">'数量'</th>
      <th style="padding:5px; backgroundColor:#1F4E79; color:white; textAlign:center; border:1px solid #1F4E79; width:12%">'单价'</th>
      <th style="padding:5px; backgroundColor:#1F4E79; color:white; textAlign:center; border:1px solid #1F4E79">'金额'</th>
    </tr>
    <tr>
      <td style="padding:4px; textAlign:center; border:1px solid #C3CDD8">'1'</td>
      <td style="padding:4px; textAlign:center; border:1px solid #C3CDD8">${iCode1}</td>
      <td style="padding:4px; border:1px solid #C3CDD8">${iName1}</td>
      <td style="padding:4px; border:1px solid #C3CDD8">${iSpec1}</td>
      <td style="padding:4px; textAlign:center; border:1px solid #C3CDD8">${iUnit1}</td>
      <td style="padding:4px; textAlign:right; border:1px solid #C3CDD8">${iQty1}</td>
      <td style="padding:4px; textAlign:right; border:1px solid #C3CDD8">${iPrice1}</td>
      <td style="padding:4px; textAlign:right; border:1px solid #C3CDD8">${iAmount1}</td>
    </tr>
    <tr>
      <td style="padding:4px; textAlign:center; border:1px solid #C3CDD8">'2'</td>
      <td style="padding:4px; textAlign:center; border:1px solid #C3CDD8">${iCode2}</td>
      <td style="padding:4px; border:1px solid #C3CDD8">${iName2}</td>
      <td style="padding:4px; border:1px solid #C3CDD8">${iSpec2}</td>
      <td style="padding:4px; textAlign:center; border:1px solid #C3CDD8">${iUnit2}</td>
      <td style="padding:4px; textAlign:right; border:1px solid #C3CDD8">${iQty2}</td>
      <td style="padding:4px; textAlign:right; border:1px solid #C3CDD8">${iPrice2}</td>
      <td style="padding:4px; textAlign:right; border:1px solid #C3CDD8">${iAmount2}</td>
    </tr>
    <tr>
      <td style="padding:4px; textAlign:center; border:1px solid #C3CDD8">'3'</td>
      <td style="padding:4px; textAlign:center; border:1px solid #C3CDD8">${iCode3}</td>
      <td style="padding:4px; border:1px solid #C3CDD8">${iName3}</td>
      <td style="padding:4px; border:1px solid #C3CDD8">${iSpec3}</td>
      <td style="padding:4px; textAlign:center; border:1px solid #C3CDD8">${iUnit3}</td>
      <td style="padding:4px; textAlign:right; border:1px solid #C3CDD8">${iQty3}</td>
      <td style="padding:4px; textAlign:right; border:1px solid #C3CDD8">${iPrice3}</td>
      <td style="padding:4px; textAlign:right; border:1px solid #C3CDD8">${iAmount3}</td>
    </tr>
    <tr>
      <td style="padding:4px; textAlign:center; border:1px solid #C3CDD8">'4'</td>
      <td style="padding:4px; textAlign:center; border:1px solid #C3CDD8">${iCode4}</td>
      <td style="padding:4px; border:1px solid #C3CDD8">${iName4}</td>
      <td style="padding:4px; border:1px solid #C3CDD8">${iSpec4}</td>
      <td style="padding:4px; textAlign:center; border:1px solid #C3CDD8">${iUnit4}</td>
      <td style="padding:4px; textAlign:right; border:1px solid #C3CDD8">${iQty4}</td>
      <td style="padding:4px; textAlign:right; border:1px solid #C3CDD8">${iPrice4}</td>
      <td style="padding:4px; textAlign:right; border:1px solid #C3CDD8">${iAmount4}</td>
    </tr>
    <tr>
      <td style="padding:4px; textAlign:center; border:1px solid #C3CDD8">'5'</td>
      <td style="padding:4px; textAlign:center; border:1px solid #C3CDD8">${iCode5}</td>
      <td style="padding:4px; border:1px solid #C3CDD8">${iName5}</td>
      <td style="padding:4px; border:1px solid #C3CDD8">${iSpec5}</td>
      <td style="padding:4px; textAlign:center; border:1px solid #C3CDD8">${iUnit5}</td>
      <td style="padding:4px; textAlign:right; border:1px solid #C3CDD8">${iQty5}</td>
      <td style="padding:4px; textAlign:right; border:1px solid #C3CDD8">${iPrice5}</td>
      <td style="padding:4px; textAlign:right; border:1px solid #C3CDD8">${iAmount5}</td>
    </tr>
    <tr>
      <td style="padding:4px; textAlign:center; border:1px solid #C3CDD8">'6'</td>
      <td style="padding:4px; textAlign:center; border:1px solid #C3CDD8">${iCode6}</td>
      <td style="padding:4px; border:1px solid #C3CDD8">${iName6}</td>
      <td style="padding:4px; border:1px solid #C3CDD8">${iSpec6}</td>
      <td style="padding:4px; textAlign:center; border:1px solid #C3CDD8">${iUnit6}</td>
      <td style="padding:4px; textAlign:right; border:1px solid #C3CDD8">${iQty6}</td>
      <td style="padding:4px; textAlign:right; border:1px solid #C3CDD8">${iPrice6}</td>
      <td style="padding:4px; textAlign:right; border:1px solid #C3CDD8">${iAmount6}</td>
    </tr>
    <tr>
      <td style="padding:4px; textAlign:center; border:1px solid #C3CDD8">'7'</td>
      <td style="padding:4px; textAlign:center; border:1px solid #C3CDD8">${iCode7}</td>
      <td style="padding:4px; border:1px solid #C3CDD8">${iName7}</td>
      <td style="padding:4px; border:1px solid #C3CDD8">${iSpec7}</td>
      <td style="padding:4px; textAlign:center; border:1px solid #C3CDD8">${iUnit7}</td>
      <td style="padding:4px; textAlign:right; border:1px solid #C3CDD8">${iQty7}</td>
      <td style="padding:4px; textAlign:right; border:1px solid #C3CDD8">${iPrice7}</td>
      <td style="padding:4px; textAlign:right; border:1px solid #C3CDD8">${iAmount7}</td>
    </tr>
    <tr>
      <td style="padding:4px; textAlign:center; border:1px solid #C3CDD8">'8'</td>
      <td style="padding:4px; textAlign:center; border:1px solid #C3CDD8">${iCode8}</td>
      <td style="padding:4px; border:1px solid #C3CDD8">${iName8}</td>
      <td style="padding:4px; border:1px solid #C3CDD8">${iSpec8}</td>
      <td style="padding:4px; textAlign:center; border:1px solid #C3CDD8">${iUnit8}</td>
      <td style="padding:4px; textAlign:right; border:1px solid #C3CDD8">${iQty8}</td>
      <td style="padding:4px; textAlign:right; border:1px solid #C3CDD8">${iPrice8}</td>
      <td style="padding:4px; textAlign:right; border:1px solid #C3CDD8">${iAmount8}</td>
    </tr>
    <tr>
      <td style="padding:4px; textAlign:center; border:1px solid #C3CDD8">'9'</td>
      <td style="padding:4px; textAlign:center; border:1px solid #C3CDD8">${iCode9}</td>
      <td style="padding:4px; border:1px solid #C3CDD8">${iName9}</td>
      <td style="padding:4px; border:1px solid #C3CDD8">${iSpec9}</td>
      <td style="padding:4px; textAlign:center; border:1px solid #C3CDD8">${iUnit9}</td>
      <td style="padding:4px; textAlign:right; border:1px solid #C3CDD8">${iQty9}</td>
      <td style="padding:4px; textAlign:right; border:1px solid #C3CDD8">${iPrice9}</td>
      <td style="padding:4px; textAlign:right; border:1px solid #C3CDD8">${iAmount9}</td>
    </tr>
    <tr>
      <td style="padding:4px; textAlign:center; border:1px solid #C3CDD8">'10'</td>
      <td style="padding:4px; textAlign:center; border:1px solid #C3CDD8">${iCode10}</td>
      <td style="padding:4px; border:1px solid #C3CDD8">${iName10}</td>
      <td style="padding:4px; border:1px solid #C3CDD8">${iSpec10}</td>
      <td style="padding:4px; textAlign:center; border:1px solid #C3CDD8">${iUnit10}</td>
      <td style="padding:4px; textAlign:right; border:1px solid #C3CDD8">${iQty10}</td>
      <td style="padding:4px; textAlign:right; border:1px solid #C3CDD8">${iPrice10}</td>
      <td style="padding:4px; textAlign:right; border:1px solid #C3CDD8">${iAmount10}</td>
    </tr>
    <tr>
      <td style="padding:4px; textAlign:center; border:1px solid #C3CDD8">'11'</td>
      <td style="padding:4px; textAlign:center; border:1px solid #C3CDD8">${iCode11}</td>
      <td style="padding:4px; border:1px solid #C3CDD8">${iName11}</td>
      <td style="padding:4px; border:1px solid #C3CDD8">${iSpec11}</td>
      <td style="padding:4px; textAlign:center; border:1px solid #C3CDD8">${iUnit11}</td>
      <td style="padding:4px; textAlign:right; border:1px solid #C3CDD8">${iQty11}</td>
      <td style="padding:4px; textAlign:right; border:1px solid #C3CDD8">${iPrice11}</td>
      <td style="padding:4px; textAlign:right; border:1px solid #C3CDD8">${iAmount11}</td>
    </tr>
    <tr>
      <td style="padding:4px; textAlign:center; border:1px solid #C3CDD8">'12'</td>
      <td style="padding:4px; textAlign:center; border:1px solid #C3CDD8">${iCode12}</td>
      <td style="padding:4px; border:1px solid #C3CDD8">${iName12}</td>
      <td style="padding:4px; border:1px solid #C3CDD8">${iSpec12}</td>
      <td style="padding:4px; textAlign:center; border:1px solid #C3CDD8">${iUnit12}</td>
      <td style="padding:4px; textAlign:right; border:1px solid #C3CDD8">${iQty12}</td>
      <td style="padding:4px; textAlign:right; border:1px solid #C3CDD8">${iPrice12}</td>
      <td style="padding:4px; textAlign:right; border:1px solid #C3CDD8">${iAmount12}</td>
    </tr>
    <tr>
      <td style="padding:4px; textAlign:center; border:1px solid #C3CDD8">'13'</td>
      <td style="padding:4px; textAlign:center; border:1px solid #C3CDD8">${iCode13}</td>
      <td style="padding:4px; border:1px solid #C3CDD8">${iName13}</td>
      <td style="padding:4px; border:1px solid #C3CDD8">${iSpec13}</td>
      <td style="padding:4px; textAlign:center; border:1px solid #C3CDD8">${iUnit13}</td>
      <td style="padding:4px; textAlign:right; border:1px solid #C3CDD8">${iQty13}</td>
      <td style="padding:4px; textAlign:right; border:1px solid #C3CDD8">${iPrice13}</td>
      <td style="padding:4px; textAlign:right; border:1px solid #C3CDD8">${iAmount13}</td>
    </tr>
    <tr>
      <td style="padding:4px; textAlign:center; border:1px solid #C3CDD8">'14'</td>
      <td style="padding:4px; textAlign:center; border:1px solid #C3CDD8">${iCode14}</td>
      <td style="padding:4px; border:1px solid #C3CDD8">${iName14}</td>
      <td style="padding:4px; border:1px solid #C3CDD8">${iSpec14}</td>
      <td style="padding:4px; textAlign:center; border:1px solid #C3CDD8">${iUnit14}</td>
      <td style="padding:4px; textAlign:right; border:1px solid #C3CDD8">${iQty14}</td>
      <td style="padding:4px; textAlign:right; border:1px solid #C3CDD8">${iPrice14}</td>
      <td style="padding:4px; textAlign:right; border:1px solid #C3CDD8">${iAmount14}</td>
    </tr>
    <tr>
      <td style="padding:4px; textAlign:center; border:1px solid #C3CDD8">'15'</td>
      <td style="padding:4px; textAlign:center; border:1px solid #C3CDD8">${iCode15}</td>
      <td style="padding:4px; border:1px solid #C3CDD8">${iName15}</td>
      <td style="padding:4px; border:1px solid #C3CDD8">${iSpec15}</td>
      <td style="padding:4px; textAlign:center; border:1px solid #C3CDD8">${iUnit15}</td>
      <td style="padding:4px; textAlign:right; border:1px solid #C3CDD8">${iQty15}</td>
      <td style="padding:4px; textAlign:right; border:1px solid #C3CDD8">${iPrice15}</td>
      <td style="padding:4px; textAlign:right; border:1px solid #C3CDD8">${iAmount15}</td>
    </tr>
    <tr>
      <td style="padding:4px; textAlign:center; border:1px solid #C3CDD8">'16'</td>
      <td style="padding:4px; textAlign:center; border:1px solid #C3CDD8">${iCode16}</td>
      <td style="padding:4px; border:1px solid #C3CDD8">${iName16}</td>
      <td style="padding:4px; border:1px solid #C3CDD8">${iSpec16}</td>
      <td style="padding:4px; textAlign:center; border:1px solid #C3CDD8">${iUnit16}</td>
      <td style="padding:4px; textAlign:right; border:1px solid #C3CDD8">${iQty16}</td>
      <td style="padding:4px; textAlign:right; border:1px solid #C3CDD8">${iPrice16}</td>
      <td style="padding:4px; textAlign:right; border:1px solid #C3CDD8">${iAmount16}</td>
    </tr>
    <tr>
      <td style="padding:4px; textAlign:center; border:1px solid #C3CDD8">'17'</td>
      <td style="padding:4px; textAlign:center; border:1px solid #C3CDD8">${iCode17}</td>
      <td style="padding:4px; border:1px solid #C3CDD8">${iName17}</td>
      <td style="padding:4px; border:1px solid #C3CDD8">${iSpec17}</td>
      <td style="padding:4px; textAlign:center; border:1px solid #C3CDD8">${iUnit17}</td>
      <td style="padding:4px; textAlign:right; border:1px solid #C3CDD8">${iQty17}</td>
      <td style="padding:4px; textAlign:right; border:1px solid #C3CDD8">${iPrice17}</td>
      <td style="padding:4px; textAlign:right; border:1px solid #C3CDD8">${iAmount17}</td>
    </tr>
    <tr>
      <td style="padding:4px; textAlign:center; border:1px solid #C3CDD8">'18'</td>
      <td style="padding:4px; textAlign:center; border:1px solid #C3CDD8">${iCode18}</td>
      <td style="padding:4px; border:1px solid #C3CDD8">${iName18}</td>
      <td style="padding:4px; border:1px solid #C3CDD8">${iSpec18}</td>
      <td style="padding:4px; textAlign:center; border:1px solid #C3CDD8">${iUnit18}</td>
      <td style="padding:4px; textAlign:right; border:1px solid #C3CDD8">${iQty18}</td>
      <td style="padding:4px; textAlign:right; border:1px solid #C3CDD8">${iPrice18}</td>
      <td style="padding:4px; textAlign:right; border:1px solid #C3CDD8">${iAmount18}</td>
    </tr>
  </table>

  <areaBreak></areaBreak>

  <!-- 明细表:第 2 页(续表 19~20 + 合计行,逐列占位不用 colspan) -->
  <p style="fontSize:8.5pt; color:#5A6B7C; marginBottom:4px">${orderNo}' (续表)'</p>
  <table style="width:100%; fontSize:8pt">
    <tr>
      <th style="padding:5px; backgroundColor:#1F4E79; color:white; textAlign:center; border:1px solid #1F4E79; width:5%">'序'</th>
      <th style="padding:5px; backgroundColor:#1F4E79; color:white; textAlign:center; border:1px solid #1F4E79; width:13%">'物资编码'</th>
      <th style="padding:5px; backgroundColor:#1F4E79; color:white; textAlign:center; border:1px solid #1F4E79; width:22%">'物资名称'</th>
      <th style="padding:5px; backgroundColor:#1F4E79; color:white; textAlign:center; border:1px solid #1F4E79; width:19%">'规格型号'</th>
      <th style="padding:5px; backgroundColor:#1F4E79; color:white; textAlign:center; border:1px solid #1F4E79; width:7%">'单位'</th>
      <th style="padding:5px; backgroundColor:#1F4E79; color:white; textAlign:center; border:1px solid #1F4E79; width:9%">'数量'</th>
      <th style="padding:5px; backgroundColor:#1F4E79; color:white; textAlign:center; border:1px solid #1F4E79; width:12%">'单价'</th>
      <th style="padding:5px; backgroundColor:#1F4E79; color:white; textAlign:center; border:1px solid #1F4E79">'金额'</th>
    </tr>
    <tr>
      <td style="padding:4px; textAlign:center; border:1px solid #C3CDD8">'19'</td>
      <td style="padding:4px; textAlign:center; border:1px solid #C3CDD8">${iCode19}</td>
      <td style="padding:4px; border:1px solid #C3CDD8">${iName19}</td>
      <td style="padding:4px; border:1px solid #C3CDD8">${iSpec19}</td>
      <td style="padding:4px; textAlign:center; border:1px solid #C3CDD8">${iUnit19}</td>
      <td style="padding:4px; textAlign:right; border:1px solid #C3CDD8">${iQty19}</td>
      <td style="padding:4px; textAlign:right; border:1px solid #C3CDD8">${iPrice19}</td>
      <td style="padding:4px; textAlign:right; border:1px solid #C3CDD8">${iAmount19}</td>
    </tr>
    <tr>
      <td style="padding:4px; textAlign:center; border:1px solid #C3CDD8">'20'</td>
      <td style="padding:4px; textAlign:center; border:1px solid #C3CDD8">${iCode20}</td>
      <td style="padding:4px; border:1px solid #C3CDD8">${iName20}</td>
      <td style="padding:4px; border:1px solid #C3CDD8">${iSpec20}</td>
      <td style="padding:4px; textAlign:center; border:1px solid #C3CDD8">${iUnit20}</td>
      <td style="padding:4px; textAlign:right; border:1px solid #C3CDD8">${iQty20}</td>
      <td style="padding:4px; textAlign:right; border:1px solid #C3CDD8">${iPrice20}</td>
      <td style="padding:4px; textAlign:right; border:1px solid #C3CDD8">${iAmount20}</td>
    </tr>
    <tr>
      <td style="padding:5px; border:1px solid #C3CDD8">'—'</td>
      <td style="padding:5px; border:1px solid #C3CDD8">'—'</td>
      <td style="padding:5px; border:1px solid #C3CDD8; bold:true">'合计'</td>
      <td style="padding:5px; border:1px solid #C3CDD8">'—'</td>
      <td style="padding:5px; border:1px solid #C3CDD8">'—'</td>
      <td style="padding:5px; textAlign:right; border:1px solid #C3CDD8; bold:true">${totalQty}</td>
      <td style="padding:5px; border:1px solid #C3CDD8">'—'</td>
      <td style="padding:5px; textAlign:right; border:1px solid #C3CDD8; bold:true; color:#B71C1C">${totalAmount}</td>
    </tr>
  </table>

  <table style="width:100%; fontSize:9pt; marginTop:6px">
    <tr>
      <td style="width:76px; padding:5px; backgroundColor:#E8EDF2; bold:true; border:1px solid #C3CDD8">'金额大写'</td>
      <td style="padding:5px; border:1px solid #C3CDD8; bold:true; color:#B71C1C">${amountWords}</td>
    </tr>
    <tr>
      <td style="padding:5px; backgroundColor:#E8EDF2; bold:true; border:1px solid #C3CDD8">'验收结论'</td>
      <td style="padding:5px; border:1px solid #C3CDD8">${acceptResult}</td>
    </tr>
  </table>

  <div style="display:flex; justifyContent:space-between; marginTop:12px">
    <div style="width:150px; borderTop:1px solid #5A6B7C; paddingTop:4px">
      <p style="fontSize:9pt; color:#5A6B7C; textAlignment:center">'送货人:'${supplier}</p>
      <p style="fontSize:8pt; color:#8a939b; textAlignment:center; marginTop:14px">'(签字)'</p>
    </div>
    <div style="width:150px; borderTop:1px solid #5A6B7C; paddingTop:4px">
      <p style="fontSize:9pt; color:#5A6B7C; textAlignment:center">'验收人:'${operator}</p>
      <p style="fontSize:8pt; color:#8a939b; textAlignment:center; marginTop:14px">'(签字)'</p>
    </div>
    <div style="width:150px; borderTop:1px solid #5A6B7C; paddingTop:4px">
      <p style="fontSize:9pt; color:#5A6B7C; textAlignment:center">'保管员:'${keeper}</p>
      <p style="fontSize:8pt; color:#8a939b; textAlignment:center; marginTop:14px">'(签字)'</p>
    </div>
  </div>

  <div style="display:flex; justifyContent:flex-end; marginTop:6px">
    <div style="width:170px; textAlignment:center">
      <image src='D:/test/image/94_seal.png' style="width:92px; height:92px"></image>
      <p style="fontSize:8pt; color:#5A6B7C">${warehouse}' 入库专用章'</p>
    </div>
  </div>

  <p style="fontSize:7.5pt; color:#8a939b; marginTop:4px">'说明:本单一式三联,第一联仓库留存,第二联财务记账,第三联供应商回执。'</p>

</body>
</pdf>

同分组示例

本页 PDF、预览图、模板与源码均由 JQuick-Pdf 真实运行产出,可自由复制到你的项目中使用。