使用poi,通过重写render对表格进行处理
导入POI依赖
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.14</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.14</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-schemas</artifactId>
<version>3.14</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-scratchpad</artifactId>
<version>3.14</version>
</dependency>
初始word
废话不说,代码走起
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
import com.deepoove.poi.data.RowRenderData;
import com.deepoove.poi.policy.DynamicTableRenderPolicy;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.apache.poi.xwpf.usermodel.XWPFTableRow;
import java.io.*;
import java.util.*;
import java.util.stream.Collectors;
@Slf4j
@SuppressWarnings("unused")
public class POITest {
public static void main(String[] args) throws IOException {
//填写数据
List<Person> pList = new ArrayList<>();
for (int i = 0; i < 5; i++) {
String anInt = String.valueOf(new Random().nextInt(10));
String name = "阿恺" + i;
String sex = i % 2 == 0 ? "男" : "女";
String phone = anInt + anInt + anInt + anInt + anInt + anInt + anInt + i;
String mail = anInt + anInt + anInt + anInt + anInt + anInt + anInt + i + "@qq.com";
Person person = new Person(String.valueOf(i), name, sex, phone, mail);
pList.add(person);
}
//通过性别分组
Map<String, List<Person>> collect = pList.stream().collect(Collectors.groupingBy(Person::getSex));
//通过RowRenderData去构建每行数据
List<RowRenderData> rList = new ArrayList<>();
//建好准备分类的RowRenderData数据
Map<String, List<RowRenderData>> rm = new HashMap<>();
collect.forEach((x, y) -> {
List<RowRenderData> rl = new ArrayList<>();
y.stream().forEach(e -> {
RowRenderData rrd = RowRenderData.build(e.id, e.name, e.sex, e.phone, e.mail);
rl.add(rrd);
});
rm.put(x, rl);
});
Map<String, Object> map = new HashMap<>();
//放入解析模板的数据
map.put("sex", rm);
//通过Configure.ConfigureBuilder调用DynamicTableRenderPolicy接口重写render方法
Configure.ConfigureBuilder config = Configure.newBuilder();
config.bind("sex", new DynamicTableRenderPolicy() {
@Override
public void render(XWPFTable table, Object o) {
//格式转化
Map<String, List<RowRenderData>> rm = (Map<String, List<RowRenderData>>) o;
List<RowRenderData> girl = rm.get("女");
for (int i = 0; i < girl.size(); i++) {
//表格中有一行就,第一行就不需要新建了
if (i != 0) {
//没有行就新增一行数据
XWPFTableRow insertNewTableRow = table.insertNewTableRow(i + 2);
for (int j = 0; j < 5; j++) {
//根据需求自己选择几列:i就是列
insertNewTableRow.createCell();
}
for (int j = 0; j < 5; j++) {
//插入数据到每个单元格
//可以自行debug,查看RenderData中数据
table.getRow(i + 2).getCell(j).setText(girl.get(i).getCellDatas().get(j).getRenderData().getText());
}
/**
* 合并单元格
* mergeCellsHorizonal(XWPFTable table, int row, int fromCol, int toCol)
* row:哪一行
* fromCol:从哪开始
* toCol:到哪结束
* 注意:fromCol到toCol区间是左闭右闭
*/
// TableTools.mergeCellsHorizonal(table, i+2, 2, 3);
}
}
List<RowRenderData> man = rm.get("男");
for (int i = 0; i < girl.size(); i++) {
//表格中没有一行数据
//没有行就新增一行数据
XWPFTableRow insertNewTableRow = table.insertNewTableRow(i + 5);
for (int j = 0; j < 5; j++) {
//根据需求自己选择几列:i就是列
insertNewTableRow.createCell();
//插入数据到每个单元格
//可以自行debug,查看RenderData中数据
table.getRow(i + 2).getCell(j).setText(girl.get(i).getCellDatas().get(j).getRenderData().getText());
}
}
}
});
//获取resources下的docx资源包的输入流
InputStream resourceAsStream = new FileInputStream(new File("C:/Users/11142/Desktop/test.docx"));
XWPFTemplate render = XWPFTemplate.compile(resourceAsStream, config.build()).render(map);
FileOutputStream outputStream = new FileOutputStream(new File("C:/Users/11142/Desktop/out_template.docx"));
render.write(outputStream);
outputStream.flush();
outputStream.close();
render.close();
}
}
class Person {
public String id;
public String name;
public String sex;
public String phone;
public String mail;
public Person(String id, String name, String sex, String phone, String mail) {
this.id = id;
this.name = name;
this.sex = sex;
this.phone = phone;
this.mail = mail;
}
public String getSex() {
return this.sex;
}
}
可能会有一丢丢多,如果有大佬可以指正,欢迎评论区留言
出问题啦,不过项目中亲测可以
报错:Exception in thread "main" java.lang.IncompatibleClassChangeError: Found interface org.apache.poi.util.POILogger, but class was expected
这个错误说是POI的jar包版本问题,具体可以查看
结果(按照项目中走法)
踩过的坑
1.千万要注意下{{sex}}所放位置,那里相对于来说是0
2.最好使用.doxc做模板,不然可能会报错,这个还有待研究
总结一下
1.使用steam流去进行分组,第一次用,用起来还不错的样子
通过函数式表达式根据性别分组
2.对表格单元格的行合并以及增加一行、多列和赋值