你好!这是由一个刚毕业的学生,由于项目所需,需要通过Java后台的方式打印Word文档,因此在对大量能操作word的Java API中,选择了Apache POI。以下将简单分享一下这个在学习和开发这个基于POI的word文档打印工具时,一些心得:
接下来,我将会对Apache POI进行讲解。以及我这套工具的一些底层原理,目的是为了和各位大牛交流,以及有人有定制需求的话,可以基于我这个工具进行改写,来适应不同的项目。如果你不想学原理,则只需要跳过本段内容,到最后一小节,我会用最黑盒的方式,来快速教大家上手使用我这套工具。
(由于本人技术有限,而且公文写作能力一般,因此有口误的地方请大家指出,并且欢迎大家提出更好的解决建议)
(本工具现在是V1.0版本,代码方面也还没进行过多优化,性能暂时还OK,但还有很大优化空间 )
已实现的功能:
后期可能扩展的方向
本工具与网上其他POI打印工具类对比 特点:
简单例子
(1)word模板
<properties>
<java.poi.version>4.0.0</java.poi.version>
</properties>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>${java.poi.version}</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-schemas</artifactId>
<version>${java.poi.version}</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>${java.poi.version}</version>
</dependency>
他们之间的关系结构如图所示(为了更方便大家的理解,用一个图表示)
因此:
String text = paragraphs.get(0).getText();
4.设置段落的样式
//每一个XWPFParagraph可以设置对齐方式,边框,加粗等等,自己看里面的方法即可
String text = paragraphs.get(0).setXXX();
5.获取段落的Run,并修改这段Run的文字
//获取段落的所有Run
List<XWPFRun> runs = paragraph.getRuns();
//删除某一个Run
paragraph.removeRun(下标);
//增加一个没有文字的Run
paragraph.createRun();
//修改文字(覆盖原文本,追加的话则不使用第二个参数)
runs.get(0).setText("第二个参数表示从哪个下标开始修改字符串", 0);
//一个Run里面又有很多样式可以选择,如加粗,斜体等等
runs.get(0).setXXX();
//如果需要将一整个段落都替换成一个新的文本
while (paragraph.getRuns().isEmpty()){
paragraph.removeRun(0);
}
paragraph.createRun().setText("新文本");
//上面的代码会导致,原来的Run样式都没了,新的Run使用默认的样式。如果想保留原来Run的样式,可以删除的时候不要删掉全部Run,如
while (paragraph.getRuns().size() > 1){
paragraph.removeRun(1);
}
paragraph.getRuns().get(0).setText("新文本", 0);
由于要工作,暂没时间写完(后续更新)
其中:
建议使用WPS编辑word模板,因为目前Apache Poi对office不太友好,在我约束的规则下,我发现一个 占位符无法对应一个XWPFRun,在处理上非常不方便
( * 表示通配符,可以是任意字符)
(1) 文本替换,使用@${t_*}@的方式(其中两边的@,需要独占一种样式)
PS : 两边的@是必不可少的,并且需要使用一种与周围字符样式不同的样式。我的做法通常是,加粗+变为指数。在进行打印的过程中, ${xxx}的内容会被你指定的文本替换掉,两边的@也会被删掉。
(2) 静态表格(文本替换)
表格上方多增加一行,在第一行第一列中指定静态表格 ${at_static_*}
表格内需要进行文本替换的地方,与普通文本替换的规则一样
(3) 动态表格(行动态)
(4) 动态表格(整个表格动态)
(5) 动态表格(携带标题和跟随文本)
(2) Java对应word模板DEMO的示例
//word模板的路径
String inputUrl = "F:\\poidemo\\TESTPOI.docx";
//输出的位置(可以不存在文件)
String outputUrl = "F:\\poidemo\\OUTPUT.docx";
//文本替换Map
Map<String, String> textMap = new HashMap<>();
//动态表格Map
Map<String, List<IPoiWordTable>> tableMap = new HashMap<>();
//表格为空时,文本替换的Map(这个的用法是,如果某一个表格是不需要显示的,则把他规则的名字放进key里面,value如果设为null,则该表格不显示,如果是文本内容,则这个表格的位置,会被一段文字替换)
Map<String, String> noneTableMap = new HashMap<>();
//准备数据
//文本替换 and 静态表格文本替换 都是放在textMap里
textMap.put("t_author", "走在刀剑上的羊");
textMap.put("t_email", "[email protected]");
textMap.put("t_year", "2018");
textMap.put("t_month", "11");
textMap.put("t_day", "30");
textMap.put("t_poi_cool", "[我不会影响左右两边文字]";
//动态表格都放入tableMap中
//动态表格(行)
PoiWordAutoTable rowTable = new PoiWordAutoTable(2, 3); //指定2行3列的动态行table
rowTable.setCell(0, 0, "row1col1");
rowTable.setCell(0, 1, "row1col2");
rowTable.setCell(0, 2, "row1col3");
rowTable.setCell(1, 0, "row2col1");
rowTable.setCell(1, 1, "row2col2");
rowTable.setCell(1, 2, "row2col3");
tableMap.put("at_row_autoRow", Arrays.asList(rowTable));
//如果不需要显示这个表格。表格会隐藏,并在相应位置出现一段文字提示
//noneTableMap.put("at_row_autoRow", "暂无数据");
//动态表格01,使用PoiWordAutoTable,行列根据原表格固定
PoiWordAutoTable data1 = new PoiWordAutoTable(2,2);
data1.setCell(0, 0, "企业名称");
data1.setCell(0, 1, "xxx");
data1.setCell(1, 0, "注册号");
data1.setCell(1, 1, "XXX123");
PoiWordAutoTable data2 = new PoiWordAutoTable(2,2);
data2.setCell(0, 0, "企业名称");
data2.setCell(0, 1, "xxx");
data2.setCell(1, 0, "注册号");
data2.setCell(1, 1, "---x2---");
tableMap.put("at_max01_auto", Arrays.asList(data1, data2));
//动态表格02,使用PWATwithHeaderBottom
PWATwithHeaderBottom pwat1 = new PWATwithHeaderBottom(3,2);
//如果标题 或 跟随文本不需要显示内容,则用"" 或 null代替
pwat1.setTitle("1.实际控制人:xxx(身份证号:441900XXXXXXX)查询日期:1995年11月23日");
//pwat1.setTitle(null);
pwat1.setBottom("底部跟随文本");
pwat1.setCell(0, 1, "信用卡");
pwat1.setCell(1, 0, "账户数");
pwat1.setCell(1, 1, "2个");
pwat1.setCell(2, 0, "未结清/未注销账户数");
pwat1.setCell(2, 1, "2个");
PWATwithHeaderBottom pwat2 = new PWATwithHeaderBottom(3,2);
pwat2.setTitle("2.实际控制人:xxx(身份证号:xxx)查询日期:2018年11月22日");
pwat2.setBottom("底部跟随文本");
pwat2.setCell(0, 1, "信用卡");
pwat2.setCell(1, 0, "账户数");
pwat2.setCell(1, 1, "255个");
pwat2.setCell(2, 0, "未结清/未注销账户数");
pwat2.setCell(2, 1, "255个");
tableMap.put("at_max02_auto", Arrays.asList(pwat1, pwat2));
//最后使用工具
PoiWordUtil.changWord(inputUrl, outputUrl, textMap, tableMap, noneTableMap);
再次强调:建议使用WPS编辑word模板,因为我发现如果用office编辑模板,一个占位符无法对应一个XWPFRun,如果各位发现office也能正常编辑 占位符,请留言
https://github.com/YellowWinterSun/poiWordUtil
最近更新: