param.setColumns(Arrays.asList("征集稿详情", "意见单位", "修改建议", "修改理由", "是否采纳", "意见小结"));
File file = new File(path);
// 获取模板文件流
InputStream resourceAsStream = new FileInputStream(file);
//poi-tl 配置
ConfigureBuilder builder = Configure.builder();
builder.useSpringEL(false);
Map<String, Object> map = new HashMap<>();
//创建表格并动态写入表头
RowRenderData row0 = new RowRenderData();
for (int g = 0; g < param.getColumns().size(); g++) {
CellRenderData cell_1 = Cells.of(new TextRenderData(param.getColumns().get(g))).create();
row0.addCell(cell_1);
}
Tables.TableBuilder tableBuilder = Tables.of(row0);
//给表格装载数据
ServerTableData serverTableData = getServerTableData(param);
List<RowRenderData> serverDataList = serverTableData.getServerDataList();
List<Map<String, Object>> groupDataList = serverTableData.getGroupDataList();
Integer mergeColumn = serverTableData.getMergeColumn(); //合并第几列,一般是0列
for (RowRenderData qiankuan : serverTableData.getServerDataList()) {
RowRenderData row = qiankuan;
tableBuilder.addRow(row);
}
MergeCellRule.MergeCellRuleBuilder rule = MergeCellRule.builder();
//待需要合并的行的集合
Map<MergeCellRule.Grid, MergeCellRule.Grid> mergeMap = new HashMap<>();
// 处理合并---开始
for (int i = 0; i < serverDataList.size(); i++) {
// 获取要合并的名称那一列数据 mergeColumn代表要合并的列,从0开始
String typeNameData = serverDataList.get(i).getCells().get(0).getParagraphs().get(0).getContents().get(0).toString();
for (int j = 0; j < groupDataList.size(); j++) {
String typeNameTemplate = String.valueOf(groupDataList.get(j).get("typeName"));
int listSize = Integer.parseInt(String.valueOf(groupDataList.get(j).get("listSize")));
//合并征集稿对象合并
if (typeNameTemplate.equals(typeNameData) && listSize > 1) {
mergeMap.put(MergeCellRule.Grid.of(i + 1, 0), MergeCellRule.Grid.of(i + listSize, 0));
groupDataList.remove(j);
break;
}
}
}
//将需要的合并行集合放到map中
for (Map.Entry<MergeCellRule.Grid, MergeCellRule.Grid> entry : mergeMap.entrySet()) {
MergeCellRule.Grid mapKey = entry.getKey();
MergeCellRule.Grid mapValue = entry.getValue();
rule.map(mapKey, mapValue);
}
// 处理合并---结束
tableBuilder.mergeRule(rule.build());//开始合并
map.put("oneTable", tableBuilder.create());
XWPFTemplate template = XWPFTemplate.compile(Objects.requireNonNull(resourceAsStream), builder.build()).render(map);
//输出网络流
response.setCharacterEncoding("utf-8");
response.setContentType("application/octet-stream");
response.setHeader("Content-disposition", "attachment;fileName=" + URLEncoder.encode(param.getDraftTitle() +"."+ param.getType(), "utf-8"));
// HttpServletResponse response
OutputStream out = response.getOutputStream();
BufferedOutputStream bos = new BufferedOutputStream(out);
template.write(bos);
bos.flush();
out.flush();
PoitlIOUtils.closeQuietlyMulti(template, bos, out);
private ServerTableData getServerTableData(ExportParam param) {
ServerTableData serverTableData = new ServerTableData();
List<RowRenderData> serverDataList = new ArrayList<>();
for (int a = 0; a < param.getResult().size(); a++) {
List<OpinionResultVo> listVos = param.getResult().get(a).getData();
listVos.stream().forEach(x -> {
RowRenderData serverData = new RowRenderData();
param.getColumns().stream().forEach(e -> {
CellRenderData cell_1 = Cells.of(new TextRenderData(columnName(e, x))).center().create();
serverData.addCell(cell_1);
});
serverDataList.add(serverData);
});
}
serverTableData.setServerDataList(serverDataList);
List<Map<String, Object>> groupDataList = new ArrayList<>();
for (int b = 0; b < param.getResult().size(); b++) {
ExportExcelVo exportExcelVo = param.getResult().get(b);
Map<String, Object> groupData1 = new HashMap<>();
groupData1.put("typeName", exportExcelVo.getRule());
groupData1.put("listSize", exportExcelVo.getData().size());
groupDataList.add(groupData1);
}
serverTableData.setGroupDataList(groupDataList);
serverTableData.setMergeColumn(0);
serverTableData.setColumns(param.getColumns());
return serverTableData;
}
word模板例子:

