打印格式
打印格式是 ERPNext 中用于控制文档打印输出外观的重要功能。它允许企业自定义各类业务文档(如发票、订单、报价单等)的打印布局和内容,以满足企业品牌标识和业务需求。本文将详细介绍 ERPNext 中的打印格式配置方法和最佳实践。
打印格式基础
什么是打印格式
打印格式定义了文档打印或 PDF 导出时的外观和内容布局:
- 布局:文档各元素的位置和大小
- 样式:文字、表格、边框等的视觉样式
- 内容:显示哪些字段和数据
- 计算:可以包含计算字段和条件显示
打印格式的应用场景
ERPNext 中的打印格式可以应用于多种业务文档:
- 销售文档:报价单、销售订单、送货单、销售发票
- 采购文档:采购订单、采购收货单、采购发票
- 财务文档:付款凭证、收款凭证、会计凭证
- 库存文档:物料出入库单、库存盘点单
- 人力资源文档:工资单、雇佣合同、绩效评估
标准打印格式
系统默认格式
ERPNext 为各种文档类型提供了标准打印格式:
- 标准格式:系统默认的基本格式
- 精简格式:简化版本,仅显示核心信息
- 现代格式:采用现代设计元素的增强版本
- 经典格式:传统样式的格式
设置默认打印格式
为特定文档类型设置默认打印格式:
- 导航至 设置 > 打印设置
- 设置 默认打印格式
- 或者针对特定文档类型:
- 导航至 自定义 > 自定义表单
- 选择文档类型
- 在 打印 部分设置默认打印格式
创建自定义打印格式
使用打印格式生成器
打印格式生成器是创建自定义格式的可视化工具:
- 导航至 设置 > 打印格式生成器
- 点击 新建
- 选择文档类型
- 设计打印格式:
- 添加和删除字段
- 调整字段位置和大小
- 设置样式和格式
- 添加自定义 HTML、CSS 和表格
- 保存格式
使用 HTML 和 Jinja 模板
创建高度自定义的打印格式:
- 导航至 自定义 > 打印格式
- 点击 新建
- 选择文档类型
- 使用 HTML 和 Jinja 模板语法编写格式代码
- 保存格式
打印格式设计元素
页面布局
控制页面整体布局:
- 页眉:包含公司标志、文档标题等
- 正文:主要内容区域
- 页脚:包含页码、总计和条款等
- 边距:设置页面四周的空白区域
- 页面大小:如 A4、信纸等
文本格式化
设置文本的外观:
- 字体:选择字体系列
- 大小:设置字体大小
- 样式:如粗体、斜体、下划线
- 颜色:设置文本颜色
- 对齐:左对齐、居中、右对齐或两端对齐
表格设计
自定义表格的外观:
- 表头:设置表头样式
- 行:设置表格行的样式
- 列宽:调整列的宽度
- 边框:设置表格边框样式
- 合计行:设置合计行的样式
条件格式
基于条件显示不同内容:
- 条件显示:基于条件显示或隐藏元素
- 条件样式:基于条件应用不同样式
- 条件计算:基于条件执行不同计算
Jinja 模板语法
基本语法
Jinja 是用于打印格式的模板语言:
- 变量:
\{\{ doc.field_name \}\} - 条件:
{% if doc.status == "Paid" %} 已付款 {% else %} 未付款 {% endif %} - 循环:
{% for item in doc.items %} \{\{ item.item_name \}\} - \{\{ item.qty \}\} {% endfor %} - 注释:
{# 这是注释 #}
常用函数和过滤器
增强模板功能的函数和过滤器:
- 格式化:
\{\{ frappe.format_currency(value, "USD") \}\}\{\{ doc.date|format_date \}\}
- 字符串操作:
\{\{ "hello"|upper \}\}(输出 "HELLO")\{\{ doc.description|truncate(100) \}\}
- 数学运算:
\{\{ doc.qty * doc.rate \}\}\{\{ items|sum(attribute='amount') \}\}
- 条件判断:
\{\{ "Yes" if doc.enabled else "No" \}\}
访问文档数据
在模板中访问文档数据:
- 文档字段:
\{\{ doc.field_name \}\} - 子表数据:
\{\{ doc.items \}\} - 元数据:
\{\{ doc.meta.title \}\} - 用户信息:
\{\{ frappe.session.user \}\} - 公司信息:
\{\{ frappe.db.get_value("Company", doc.company, "field") \}\}
打印格式高级功能
自定义 CSS 样式
添加自定义 CSS 样式:
html
<style>
.print-heading {
color: #4d4d4d;
font-size: 18px;
margin-bottom: 10px;
}
.print-table {
width: 100%;
border-collapse: collapse;
}
.print-table td, .print-table th {
border: 1px solid #ddd;
padding: 8px;
}
</style>自定义 JavaScript
添加自定义 JavaScript 功能:
html
<script>
// 在打印前执行
$(document).ready(function() {
// 自定义逻辑
});
</script>水印和背景
添加水印或背景:
html
<style>
@media print {
body::before {
content: "机密文件";
position: fixed;
top: 50%;
left: 0;
width: 100%;
text-align: center;
font-size: 100px;
color: rgba(0, 0, 0, 0.1);
transform: rotate(-45deg);
}
}
</style>多语言支持
支持多语言打印格式:
- 使用翻译函数:
\{\{ _("Invoice") \}\} - 根据用户语言切换内容:
{% if frappe.lang == "zh" %} 中文内容 {% else %} English Content {% endif %} - 格式化本地化的日期和数字
常见打印格式示例
销售发票格式
销售发票打印格式示例:
html
<div class="print-heading">
<h2>销售发票 <small>\{\{ doc.name \}\}</small></h2>
</div>
<div class="row">
<div class="col-xs-6">
<div><strong>客户:</strong> \{\{ doc.customer_name \}\}</div>
<div><strong>联系人:</strong> \{\{ doc.contact_display \}\}</div>
<div><strong>地址:</strong> \{\{ doc.address_display \}\}</div>
</div>
<div class="col-xs-6 text-right">
<div><strong>日期:</strong> \{\{ doc.posting_date \}\}</div>
<div><strong>付款条款:</strong> \{\{ doc.payment_terms_template \}\}</div>
<div><strong>到期日:</strong> \{\{ doc.due_date \}\}</div>
</div>
</div>
<table class="table table-bordered">
<thead>
<tr>
<th>物料</th>
<th>描述</th>
<th class="text-right">数量</th>
<th class="text-right">单价</th>
<th class="text-right">金额</th>
</tr>
</thead>
<tbody>
{% for item in doc.items %}
<tr>
<td>\{\{ item.item_code \}\}</td>
<td>\{\{ item.description \}\}</td>
<td class="text-right">\{\{ item.qty \}\} \{\{ item.uom \}\}</td>
<td class="text-right">\{\{ frappe.format_currency(item.rate, doc.currency) \}\}</td>
<td class="text-right">\{\{ frappe.format_currency(item.amount, doc.currency) \}\}</td>
</tr>
{% endfor %}
</tbody>
<tfoot>
<tr>
<td colspan="4" class="text-right"><strong>小计</strong></td>
<td class="text-right">\{\{ frappe.format_currency(doc.total, doc.currency) \}\}</td>
</tr>
{% for tax in doc.taxes %}
<tr>
<td colspan="4" class="text-right">\{\{ tax.description \}\}</td>
<td class="text-right">\{\{ frappe.format_currency(tax.tax_amount, doc.currency) \}\}</td>
</tr>
{% endfor %}
<tr>
<td colspan="4" class="text-right"><strong>总计</strong></td>
<td class="text-right">\{\{ frappe.format_currency(doc.grand_total, doc.currency) \}\}</td>
</tr>
</tfoot>
</table>
<div class="row">
<div class="col-xs-12">
<div><strong>总计(大写):</strong> \{\{ frappe.utils.money_in_words(doc.grand_total, doc.currency) \}\}</div>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<div><strong>备注:</strong> \{\{ doc.terms or "" \}\}</div>
</div>
</div>采购订单格式
采购订单打印格式示例:
html
<div class="print-heading">
<h2>采购订单 <small>\{\{ doc.name \}\}</small></h2>
</div>
<div class="row">
<div class="col-xs-6">
<div><strong>供应商:</strong> \{\{ doc.supplier_name \}\}</div>
<div><strong>联系人:</strong> \{\{ doc.contact_display \}\}</div>
<div><strong>地址:</strong> \{\{ doc.address_display \}\}</div>
</div>
<div class="col-xs-6 text-right">
<div><strong>日期:</strong> \{\{ doc.transaction_date \}\}</div>
<div><strong>预计交货日期:</strong> \{\{ doc.schedule_date \}\}</div>
<div><strong>付款条款:</strong> \{\{ doc.payment_terms_template \}\}</div>
</div>
</div>
<table class="table table-bordered">
<thead>
<tr>
<th>物料</th>
<th>描述</th>
<th class="text-right">数量</th>
<th class="text-right">单价</th>
<th class="text-right">金额</th>
</tr>
</thead>
<tbody>
{% for item in doc.items %}
<tr>
<td>\{\{ item.item_code \}\}</td>
<td>\{\{ item.description \}\}</td>
<td class="text-right">\{\{ item.qty \}\} \{\{ item.uom \}\}</td>
<td class="text-right">\{\{ frappe.format_currency(item.rate, doc.currency) \}\}</td>
<td class="text-right">\{\{ frappe.format_currency(item.amount, doc.currency) \}\}</td>
</tr>
{% endfor %}
</tbody>
<tfoot>
<tr>
<td colspan="4" class="text-right"><strong>小计</strong></td>
<td class="text-right">\{\{ frappe.format_currency(doc.total, doc.currency) \}\}</td>
</tr>
{% for tax in doc.taxes %}
<tr>
<td colspan="4" class="text-right">\{\{ tax.description \}\}</td>
<td class="text-right">\{\{ frappe.format_currency(tax.tax_amount, doc.currency) \}\}</td>
</tr>
{% endfor %}
<tr>
<td colspan="4" class="text-right"><strong>总计</strong></td>
<td class="text-right">\{\{ frappe.format_currency(doc.grand_total, doc.currency) \}\}</td>
</tr>
</tfoot>
</table>
<div class="row">
<div class="col-xs-12">
<div><strong>条款与条件:</strong> \{\{ doc.terms or "" \}\}</div>
</div>
</div>打印设置
全局打印设置
配置系统级打印设置:
- 导航至 设置 > 打印设置
- 配置以下选项:
- 打印样式:选择默认 CSS 样式
- 页面大小:设置默认页面尺寸(如 A4、Letter)
- 页面边距:设置页面四周的边距
- 默认打印语言:设置默认语言
- 是否显示页眉和页脚:控制页眉页脚的显示
- 显示草稿水印:对草稿文档显示水印
字母抬头和页脚
创建可重用的字母抬头和页脚:
- 导航至 设置 > 字母抬头
- 点击 新建
- 设计公司抬头或页脚,包含:
- 公司名称和标志
- 地址和联系信息
- 注册信息和税号
- 银行账户信息
- 在打印格式中引用:
\{\{ frappe.db.get_value("Letter Head", doc.letter_head, "content") \}\}
条款模板
创建可重用的条款和条件模板:
- 导航至 销售/采购 > 条款和条件
- 点击 新建
- 编写条款内容
- 在文档中选择条款模板
- 在打印格式中显示:
\{\{ doc.terms \}\}
打印格式最佳实践
设计原则
设计有效打印格式的关键原则:
- 简洁清晰:避免过度装饰,保持内容易读
- 一致性:在所有文档中保持统一的样式
- 品牌一致:符合公司品牌标识规范
- 信息层次:明确显示信息的重要性层次
- 合规要求:确保满足法律和行业要求
优化打印性能
提高打印格式性能的方法:
- 简化 HTML:减少不必要的标签和嵌套
- 优化图片:使用适当大小和分辨率的图片
- 减少计算:尽量减少复杂的模板计算
- 缓存数据:缓存频繁使用的数据查询
- 避免大型脚本:精简 JavaScript 代码
打印格式测试
测试打印格式的方法:
- 预览测试:使用不同的测试数据预览
- 多浏览器测试:在不同浏览器中测试
- 打印测试:实际打印出文档进行检查
- PDF 测试:生成 PDF 并检查格式
- 响应式测试:测试不同页面大小的适应性
常见问题与解决方案
布局问题
解决常见布局问题:
- 内容溢出:
- 使用
overflow: hidden或word-break: break-word - 调整容器大小或内边距
- 使用
- 表格宽度:
- 设置表格为
width: 100% - 使用
table-layout: fixed控制列宽
- 设置表格为
- 页面分页:
- 使用
page-break-inside: avoid防止元素跨页 - 使用
page-break-before: always强制分页
- 使用
格式化问题
解决格式化问题:
- 数字格式:
- 使用
frappe.format_number()函数 - 设置适当的小数位数和千位分隔符
- 使用
- 日期格式:
- 使用
frappe.format_date()函数 - 根据地区设置适当的日期格式
- 使用
- 文本截断:
- 使用
truncate过滤器 - 设置适当的容器高度和
overflow属性
- 使用
多语言问题
解决多语言支持问题:
- 字符集:确保使用 UTF-8 编码
- 翻译:使用翻译函数和条件语句
- 文字方向:支持从右到左的语言
- 字体:确保选择支持多语言的字体
总结
打印格式是 ERPNext 中展示企业专业形象和满足业务需求的关键工具。通过掌握打印格式的创建和自定义,企业可以确保业务文档符合品牌标识,清晰传达信息,并满足各种业务和法规要求。
无论是使用可视化的打印格式生成器,还是编写自定义 HTML 和 Jinja 模板,ERPNext 都提供了灵活的工具来创建各种复杂程度的打印格式。通过遵循最佳实践并持续优化,企业可以创建既美观又实用的业务文档打印格式。
