← dompdf.js Studio

电商订单确认单PDF生成完整指南

电商交易完成后,系统通常需要生成订单确认单,供用户核对商品、收货信息和支付金额,也用于仓库拣货和售后对账。传统订单确认单多由后端模板生成,模板更新慢、中文字体易出错;直接打印网页又会带上导航栏和推荐位等无关内容。dompdf.js让订单确认单在前端一键生成:订单数据组装成HTML,渲染成矢量PDF后下载或打印,版式干净统一。本文将完整讲解电商订单确认单PDF的生成方案,包括订单模板设计、金额结算区、多商品分页、批量导出和常见问题,适合电商系统、ERP和独立站快速集成。除了基础模板,本文还会讨论跨境店铺的国际化需求、商家自定义模板、以及让订单文档保持准确的数据规范。无论你运营的是平台、ERP还是独立站,前端方案都能帮你拿掉一整类服务端问题,让订单一旦产生就能立刻得到可打印的文档。

订单确认单的业务场景

订单确认单在电商流程中承担多重角色:对用户是交易凭证,确认下单的商品、价格和收货信息;对仓库是拣货依据,按商品明细备货发货;对财务和客服是对账凭证,处理退款、换货和投诉时快速定位订单。

一份完整的订单确认单应包含:订单编号和下单时间、收货人姓名电话地址、商品明细(名称、规格、单价、数量、小计)、金额汇总(商品总额、运费、优惠、实付金额)、支付方式和配送信息,要素缺一不可。

电商订单量通常很大,高峰期一天数万单,后端生成PDF会给服务器带来额外压力,影响核心交易接口的稳定性;前端生成方案把渲染负载分摊到每个用户的浏览器,服务器零负担,并发再高也不怕。

订单确认单还有国际化的需求:跨境店铺需要输出英文或双语订单信息,商品名称、规格、地址都要翻译。前端模板可以把文案抽成多语言字典,按店铺语言设置渲染;地址格式也要适配不同国家习惯,比如英文地址从小到大的书写顺序,避免客户收不到货。

为什么用dompdf.js生成订单确认单

订单确认单结构固定但字段繁多,HTML表格是描述它的最佳方式。dompdf.js直接渲染DOM为矢量PDF,订单模板与网页模板同源,开发和调试效率高,商品明细、金额格式、收货信息都能精确呈现。

电商场景对中文支持要求极高:商品名、收货地址、备注都可能包含生僻字和特殊字符,dompdf.js内置思源黑体,中文渲染无乱码;同时支持表格边框和自动分页,几十件商品的订单也能清晰排布。

批量导出是电商的刚需场景,比如导出当日订单确认单供仓库打印。前端方案循环读取订单列表,逐单addPage后一次save,一个PDF包含全部订单,每单从新页开始,打印分拣都方便,效率远超逐单操作。

对于独立站和SaaS电商工具来说,前端生成还有一个隐性好处:不依赖服务端渲染环境,模板即页面,运营人员可以通过可视化编辑器调整确认单样式,保存后前端直接生效。平台方还可以把确认单模板做成可配置项开放给商家,形成差异化卖点。

订单确认单模板设计

模板建议从上到下依次排列:订单头部(订单号、下单时间、订单状态)、收货信息区、商品明细表格、金额结算区、支付与配送信息、备注区。使用清晰的边框和留白分隔各区域,避免信息堆叠难以阅读。

商品明细表格的列建议为:序号、商品名称、规格、单价、数量、小计,商品名称列设置较宽;表格底部显示商品总额、运费、优惠金额和实付金额,实付金额用加粗突出,让用户一眼看到最终付款额。

收货信息可以用两栏布局展示收件人、电话、地址,地址较长时允许换行;金额区右对齐并保留两位小数;如有订单备注或发票信息,放在最下方独立区域,与正文保持间距,避免打印时粘连。

金额结算区的排版值得单独打磨:商品总额、运费、优惠、实付金额四行对齐,实付金额加大加粗;如果订单使用了优惠券或满减,建议在优惠行旁边注明规则摘要,比如满300减20,让用户明白优惠来源,减少对金额的疑问。

代码示例:导出订单确认单PDF

下面演示订单确认单的完整生成代码,从订单数据到PDF文件一气呵成,商品明细通过map批量生成表格行,金额区单独排版突出实付金额。

注意金额计算方式:商品小计由单价乘数量得到,实付金额应直接使用后端返回的金额,不要在前端重新计算应付总额,因为可能存在优惠券分摊、满减等复杂规则,前端重算容易产生分位差异。

示例中把订单对象单独定义,实际项目中订单数据来自下单接口,字段名可能不同,建议在模板函数入口做一次字段映射,把接口字段规范化为模板需要的结构,接口升级时只需修改映射层,模板保持稳定。

商品规格字段可能为空,比如部分商品没有颜色尺寸选项,渲染前要判断空值并显示为横线或留空,避免出现undefined字样;数量字段使用整数,金额统一两位小数,这些都是订单场景的常见数据规范,建议在数据层统一清洗。

如果订单包含赠品,可以在明细表格下方单独列出一行赠品信息并注明价值为0,既保证信息完整,又不影响金额合计;赠品较多时单独成区展示,避免和付费商品混在一起造成对账困扰。

import { DomPDF } from 'dompdf.js';

const order = {
  id: 'SO202608180001',
  time: '2026-08-18 14:30:22',
  receiver: '张小明',
  phone: '138****1234',
  address: '上海市浦东新区张江高科技园区某某路88号',
  items: [
    { name: '无线蓝牙耳机 Pro', spec: '白色', price: '399.00', qty: 1 },
    { name: '快充充电器 65W', spec: '黑色', price: '89.00', qty: 2 },
    { name: '手机支架', spec: '铝合金', price: '29.90', qty: 1 },
  ],
  freight: '0.00',
  discount: '-20.00',
  total: '497.90',
  payMethod: '支付宝',
  carrier: '顺丰速运',
};

const itemRows = order.items.map((item, i) => `
  <tr>
    <td style='border:1px solid #333;padding:6px;text-align:center'>${i + 1}</td>
    <td style='border:1px solid #333;padding:6px'>${item.name}</td>
    <td style='border:1px solid #333;padding:6px'>${item.spec}</td>
    <td style='border:1px solid #333;padding:6px;text-align:right'>¥${item.price}</td>
    <td style='border:1px solid #333;padding:6px;text-align:center'>${item.qty}</td>
    <td style='border:1px solid #333;padding:6px;text-align:right'>¥${(item.price * item.qty).toFixed(2)}</td>
  </tr>
`).join('');

const orderHtml = `
  <h1 style='text-align:center;font-size:16pt'>订单确认单</h1>
  <p style='text-align:center;font-size:10pt'>订单号:${order.id}  下单时间:${order.time}</p>
  <div style='border:1px solid #333;padding:8px;margin:10px 0'>
    <p style='margin:2px 0'>收货人:${order.receiver} ${order.phone}</p>
    <p style='margin:2px 0'>收货地址:${order.address}</p>
  </div>
  <table style='width:100%;border-collapse:collapse'>
    <tr style='background:#f5f5f5'>
      <th style='border:1px solid #333;padding:6px'>序号</th>
      <th style='border:1px solid #333;padding:6px'>商品名称</th>
      <th style='border:1px solid #333;padding:6px'>规格</th>
      <th style='border:1px solid #333;padding:6px'>单价</th>
      <th style='border:1px solid #333;padding:6px'>数量</th>
      <th style='border:1px solid #333;padding:6px'>小计</th>
    </tr>
    ${itemRows}
  </table>
  <div style='text-align:right;margin-top:8px'>
    <p style='margin:2px 0'>商品总额:¥${order.items.reduce((s, it) => s + it.price * it.qty, 0).toFixed(2)}</p>
    <p style='margin:2px 0'>运费:¥${order.freight}  优惠:¥${order.discount}</p>
    <p style='margin:2px 0;font-weight:bold;font-size:12pt'>实付金额:¥${order.total}</p>
  </div>
  <p style='font-size:10pt;margin-top:8px'>支付方式:${order.payMethod}  配送:${order.carrier}</p>
`;

const pdf = new DomPDF();
pdf.addPage(orderHtml, { format: 'A4', margin: '20mm' });
pdf.save(`订单确认单-${order.id}.pdf`);

多商品分页与批量导出

大额订单或批发订单可能包含几十上百件商品,一页放不下时dompdf.js自动分页,表头会在后续页面重复,拣货人员翻页也能看清列名;同时可以控制行高和字体大小,让单页容纳更多明细。

批量导出订单确认单时,建议按批次循环:先获取订单列表,每单构建HTML后addPage,所有订单添加完成后一次save;每单从新页开始渲染,方便打印后按订单撕开分拣,配合页眉页脚显示订单号更易归档。

批量场景要注意内存占用:订单数量极大时可以分批处理,例如每100单生成一个PDF文件;同时给用户显示生成进度,避免页面长时间无响应,生成完成后提供下载链接,用户体验更友好。

批量导出时建议把订单按仓库或发货批次分组,同组订单连续生成,页眉标注批次号;打印时配合浏览器的一键打印功能,整个批次一次输出,仓库人员按页分拣即可,减少重复操作,发货效率明显提升。

常见问题与注意事项

常见问题一:商品名称过长导致表格错位。建议商品名称列设置固定宽度并允许换行,不要使用nowrap强制不换行,否则长名称会撑破表格布局,影响整页排版。

常见问题二:金额分位误差。单价和数量相乘可能出现浮点误差,建议将金额转换为分(整数)运算后再格式化,或直接使用后端返回的小计金额,确保订单确认单金额与订单系统完全一致。

常见问题三:收货地址中的特殊字符乱码。地址可能包含全角字符、括号和生僻字,dompdf.js内置中文字体可正常渲染;若出现异常,检查HTML转义是否正确,避免特殊符号被浏览器解析破坏结构。

最后,确认单上应标注客服联系方式与售后说明,比如退换货政策摘要或客服热线;模板底部可以附上订单查询链接的二维码,顾客扫码即可查看物流进度,减少客服咨询量,也提升了确认单的实用价值。

⚡ 现场演示(点击生成 PDF)

下面的按钮用 dompdf.js 在浏览器端实时生成 PDF,无需后端:

Hello from dompdf.js!

这是由 dompdf.js 渲染的示例 PDF 内容。