目录
Why haiwei-poi-word
基本思想
开发方法论
术语
版本要求
快速入门
模板编写
组件能力
文本替换
最简单文本匹配
标签前后格式不同
文本中有标签
标签中不可有空格
文本框
表格支持
Loop单表
Loop单表多行
Loop并联
Loop并联多行
Loop嵌套
图片打印
代码架构
Q&A
Word版本支持03吗
图片打印宽度单位和关系
扩展能力
代码
haiwei-poi-word 基于poi,自己编码实现比较负责,且需要兼容各种版本,可以做但很繁杂。word不同于excel行列分明,并且跟实际客户端的排版设置有关系,单纯代码实现工作量大,可扩展性差,并且效果不确定。
同类比较:Poi-tl,也是个不错的组件,功能强大。有poi-tl为啥要封装Haiwei-poi呢?poi-tl就像是成品柜,Haiwei-poi-word更像是针对Saas化的定制。
侧重点不同:
poi-tl: 数据和模板没有完全分离,是用代码操作word的比较好的封装。
haiwei-poi-word则完全分离,所有样式全部由模板word决定。
文档 = 模板 + 模型(Model)
模板: 提供所有布局和样式
Model:只提供模板中需要填充的数据
模板只在逻辑上预留位置,并设定展示的参数
组件会根据数据类型 + 展示参数 来进行展示
问题1: 如果位置是方框,参数是图片,数据是字符串 >> 字符串
问题2: 位置是文本,参数是图片,数据是字符串 >> 字符串
问题3:位置是文本,参数是图片,数据是图片 >> 根据参数展示图片
问题4:位置是文本,参数没有,数据是图片 >> 展示原图
如果模板和模型不匹配时展示原则:牺牲样式,尽可能展示数据
- 好处:把问题展示出来,有助于问题的暴露和及早进行模板或者数据调整。
模型决定数据类型
- 字符串,图片
TDD 测试驱动设计
这么复杂的系统,靠前期的设计很难设计完整,所以就按照case走。
标签:占位符,place_holder label sign 都指的是 ##{customer.name}
POI 4.1.2+
JDK 1.8+
Office Word 2007(咱不支持03)
Start
<dependency>
<groupId>com.haiweigroupId>
<artifactId>haiwei-poi-wordartifactId>
<version>1.0.1version>
dependency>
模板文件:
示例代码:
// 加载模板文件
final XWPFDocument document = HaiweiDocumentGenerator.build(new File("template.docx"));
// 数据构建
List items1 = new ArrayList<>();
items1.add(new Item1("键盘11","电子类11","2020/8/11",new HaiweiImages()));
items1.add(new Item1("键盘12","电子类12","2020/8/12",new HaiweiImages()));
items1.get(0).getImages().addFiles("img1.jpg","img2.jpg");
items1.get(1).getImages().addFiles("img2.jpg","img2.jpg");
List items2 = new ArrayList<>();
items2.add(new Item1("键盘21","电子类21","2018/8/21",new HaiweiImages()));
items2.add(new Item1("键盘22","电子类22","2018/8/22",new HaiweiImages()));
items2.get(0).getImages().addFiles("img1.jpg","img2.jpg");
items2.get(1).getImages().addFiles("img2.jpg","img2.jpg");
Order1 order1 = new Order1("梅长苏1","N0001",items1);
Order1 order2 = new Order1("梅长苏2","N0002",items2);
List orders = new ArrayList<>();
orders.add(order1);
orders.add(order2);
// 添加bean
HaiweiBeanCacheManager.setBean(orders,"orders");
// 根据路径设置 单个变量
HaiweiBeanCacheManager.setString("文档编号0011","文档编号00011");
// 打印数据树
HaiweiBeanCacheManager.print();
// 设置回调函数,解决解析过程中的数据获取场景
HaiweiBeanCacheManager.setCallBackCache(new HaiweiBeanCallback() {
@Override
public Object getBean(String path) {
return null;
}
});
//解析文档
HaiweiXWPFDocumentUtil.parse(document);
// 生成文件
final File file = new File("结果文件.docx");
HaiweiDocumentGenerator.toFile(document,file);
数据类型
文本(字符串,数字等可用字符串展示的),图片,图标
标签位置:
文本,文本框,表格
文档位置:
正文,页眉,页脚,备注
表格:
并联(不限制长度),嵌套(不限制深度),并联嵌套
风格:
背景,水印
说明:已支持的为黑体展示。
标签格式:##{ 标签名称.子对象.Name1:key=value&key1=value1 }
注意:
##{aa}
按照最前面字符格式展示
##{aa}
@$&*1我 AAA#######{aa}}}}}BBB@$&*1我
有空格不会替换
##{a a}
文本框处理只是位置不同,处理方式一致。
1###{aa}}} |
订单编号:##{order.no}
订单名称:##{order.name}
行项1 |
产品名称1 |
产品金额1 |
##={begin:order.items_item}##={order:time_降序} |
||
##{ item.name} |
##{ item.type} |
##{ item.time1} |
##={end} |
订单编号:##{order.no}
订单名称:##{order.name}
行项1 |
产品名称1 |
产品金额1 |
##={begin:order.items_item}##={order:time_降序} |
||
##{ item.name} |
##{ item.type} |
##{ item.time1} |
##{ item.time} |
||
##={end} |
订单编号:##={编号}
订单名称:##={名称}
订单类型:##={业务类型}
订单时间:##={创建时间}
行项1 |
产品名称 |
产品金额 |
##={begin:Items_item}##={order: item.时间_升序/降序} |
||
##{item.名称} |
##{item.业务类型} |
##={item.创建时间} |
##={end} |
||
行项1 |
产品名称 |
产品金额 |
##={begin:Items_item}##={order: item.时间_升序/降序} |
||
##={ item.名称} |
##={ item.业务类型} |
##={ item.创建时间} |
##={end} |
##={begin:orders_order} |
||
订单编号: |
##={ order.no} |
|
订单名称: |
##={ order.name} |
|
产品名称 |
产品类型 |
时间 |
##={begin:order.items_item} |
||
##={item.name } |
##={item.type} |
##={item.time} |
##={end} |
||
##={end} |
订单编号:##={order.no}
订单名称:##={order.name}
行项1 |
产品名称1 |
产品金额1 |
##={begin:order.items_item}##={order:time_降序} |
||
##={ item.name} |
##={ item.type} |
##={ item.time1} |
##={ item.time} |
||
##={end} |
||
行项2 |
产品名称2 |
产品金额2 |
##={begin:order.items_item}##={order:item.时间_降序} |
||
##={ item.name} |
##={ item.type} |
##={ item.time} |
##={ item.time1} |
||
##={end} |
##={begin:orderList_order}##={order:order.account_升序} |
||
订单编号: |
##={ order.no} |
|
订单名称: |
##={ order.name} |
|
订单详细: |
||
行项1 |
产品名称 |
产品金额 |
##={begin:order.Items_item}##={order:item.time_升序} |
||
##={item.名称} |
##={item.业务类型} |
##={item.创建时间} |
##={end} |
||
##={end} |
自动跳转尺寸适应内容别选了。选择后格式会通过内容多少来自动调整,可能不是用户想要的。所以需要判断字段内容的长度。
暂不支持
English Metric Units (EMUs) 英制公制单位(EMU),有时称为A单位
转换类:org.apache.poi.util.Units.toEMU
PIXEL像素 = 9525 * 1EMU
CENTIMETER厘米 = 360000 EMUs = 28.34 * Point点
Inch 英寸 = 2.54厘米
1英尺 = 12英寸
1POINT点 = 12700 * EMU = 13.3 * PIXEL像素
Point 点数 打印和印刷单位
DXA 是1/20 * 点
Dxa/20/28.34 = 厘米
haiwei-poi: poi的常用操作的封装