poi-tl 是基于 Apache POI ,使用时请注意poi的版本依赖冲突问题
添加依赖
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>4.1.2</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.1.2</version>
</dependency>
<dependency>
<groupId>com.deepoove</groupId>
<artifactId>poi-tl</artifactId>
<version>1.10.3</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.11.0</version>
</dependency>
模板文件内容(我这里用的是下面那个模板内容)
代码
import com.deepoove.poi.data.RowRenderData;
import java.util.List;
import java.util.Map;
public class ServerTableData {
/**
* 携带表格中真实数据
*/
private List<RowRenderData> serverDataList;
/**
* 携带要分组的信息
*/
private List<Map<String, Object>> groupDataList;
/**
* 需要合并的列,从0开始
*/
private Integer mergeColumn;
public List<RowRenderData> getServerDataList() {
return serverDataList;
}
public void setServerDataList(List<RowRenderData> serverDataList) {
this.serverDataList = serverDataList;
}
public List<Map<String, Object>> getGroupDataList() {
return groupDataList;
}
public void setGroupDataList(List<Map<String, Object>> groupDataList) {
this.groupDataList = groupDataList;
}
public Integer getMergeColumn() {
return mergeColumn;
}
public void setMergeColumn(Integer mergeColumn) {
this.mergeColumn = mergeColumn;
}
}
import com.deepoove.poi.data.RowRenderData;
import com.deepoove.poi.policy.DynamicTableRenderPolicy;
import com.deepoove.poi.policy.TableRenderPolicy;
import com.deepoove.poi.util.TableTools;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.apache.poi.xwpf.usermodel.XWPFTableRow;
import java.util.List;
import java.util.Map;
public class ServerTablePolicy extends DynamicTableRenderPolicy {
@Override
public void render(XWPFTable xwpfTable, Object tableData) throws Exception {
if (null == tableData) {
return;
}
// 参数数据声明
ServerTableData serverTableData = (ServerTableData) tableData;
List<RowRenderData> serverDataList = serverTableData.getServerDataList();
List<Map<String, Object>> groupDataList = serverTableData.getGroupDataList();
Integer mergeColumn = serverTableData.getMergeColumn();
if (CollectionUtils.isNotEmpty(serverDataList)) {
// 先删除一行, demo中第一行是为了调整 三线表 样式
// xwpfTable.removeRow(1);//如果表单里面只有一行表头信息的话,这里设置成1
xwpfTable.removeRow(2);//如果表单里面有两行数据,则设置成2
// 行从中间插入, 因此采用倒序渲染数据
for (int i = serverDataList.size() - 1; i >= 0; i--) {
// XWPFTableRow newRow = xwpfTable.insertNewTableRow(1);//从表单的哪行开始插入数据,一般表单有一个标题,所以这里设置1;
XWPFTableRow newRow = xwpfTable.insertNewTableRow(2);//从表单的哪行开始插入数据,如果表单里面有两行,这是设置成2
// newRow.setHeight(400);
for (int j = 0; j < 3; j++) {//因为我的表单是3列,所以这里是3
newRow.createCell();
}
// 渲染一行数据
TableRenderPolicy.Helper.renderRow(newRow, serverDataList.get(i));
}
// 处理合并
for (int i = 0; i < serverDataList.size(); i++) {
// 获取要合并的名称那一列数据 mergeColumn代表要合并的列,从0开始
String typeNameData = serverDataList.get(i).getCells().get(mergeColumn).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(listSize == 1){
continue;
}
// 若匹配上 就直接合并
if (typeNameTemplate.equals(typeNameData)) {
// TableTools.mergeCellsVertically(xwpfTable, 0, i + 1, i + listSize);//如果表单里面只有一行表头信息的话,用这个语句
TableTools.mergeCellsVertically(xwpfTable, 0, i + 2, i + 1 + listSize);//如果表单里面有两行数据,则用这个语句
groupDataList.remove(j);
break;
}
}
}
}
}
}
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
import com.deepoove.poi.config.ConfigureBuilder;
import com.deepoove.poi.data.RowRenderData;
import com.deepoove.poi.data.Rows;
import com.deepoove.poi.util.PoitlIOUtils;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;
import java.io.*;
import java.util.*;
public class PreTestExport {
public static void main(String[] args) throws Exception{
// 获取模板文件流
// InputStream resourceAsStream = new FileInputStream(new File("E:/word/poi-tl-pre-old2.docx"));
InputStream resourceAsStream = new FileInputStream(new File("E:/word/poiaa.docx"));
//poi-tl 配置
ConfigureBuilder builder = Configure.builder();
builder.useSpringEL(false);
Map<String,Object> map = new HashMap<String,Object>();
// 伪造一个表格数据
//单个表格
ServerTableData oneTable = getServerTableData();
map.put("oneTable",oneTable);
map.put("title", "2023");
builder.bind("oneTable",new ServerTablePolicy());
XWPFTemplate template = XWPFTemplate.compile(Objects.requireNonNull(resourceAsStream), builder.build()).render(map);
// 获取表格对象
XWPFTable table = template.getXWPFDocument().getTableArray(0);
// 设置表格边框样式为黑色实线
CTTblPr tblPr = table.getCTTbl().getTblPr();
CTTblBorders tblBorders = tblPr.isSetTblBorders() ? tblPr.getTblBorders() : tblPr.addNewTblBorders();
CTBorder border = tblBorders.addNewTop();
border.setVal(STBorder.SINGLE);
border.setColor("000000");
// HttpServletResponse response
OutputStream out = new FileOutputStream(new File("E:/word/poi-tl-降水new.docx"));
BufferedOutputStream bos = new BufferedOutputStream(out);
template.write(bos);
bos.flush();
out.flush();
PoitlIOUtils.closeQuietlyMulti(template, bos, out);
}
private static ServerTableData getServerTableData() {
ServerTableData serverTableData = new ServerTableData();
List<RowRenderData> serverDataList = new ArrayList<RowRenderData>();
RowRenderData serverData1 = Rows.of("广州", "天河", "0.3").textFontSize(14).center().create();
RowRenderData serverData2 = Rows.of("广州", "白云", "0.2").textFontSize(14).center().create();
RowRenderData serverData3 = Rows.of("广州", "东山", "0.1").textFontSize(14).center().create();
serverDataList.add(serverData1);
serverDataList.add(serverData2);
serverDataList.add(serverData3);
RowRenderData fs = Rows.of("佛山", "禅城", "0.3").textFontSize(14).center().create();
serverDataList.add(fs);
RowRenderData sz1 = Rows.of("深圳", "南山", "0.3").textFontSize(14).center().create();
RowRenderData sz2 = Rows.of("深圳", "福田", "0.3").textFontSize(14).center().create();
serverDataList.add(sz1);
serverDataList.add(sz2);
List<Map<String, Object>> groupDataList = new ArrayList<Map<String, Object>>();
Map<String, Object> groupData1 = new HashMap<String, Object>();
groupData1.put("typeName", "广州");
groupData1.put("listSize", "3");
Map<String, Object> groupData2 = new HashMap<String, Object>();
groupData2.put("typeName", "深圳");
groupData2.put("listSize", "2");
Map<String, Object> groupData3 = new HashMap<String, Object>();
groupData3.put("typeName", "佛山");
groupData3.put("listSize", "1");
groupDataList.add(groupData1);
groupDataList.add(groupData2);
groupDataList.add(groupData3);
serverTableData.setServerDataList(serverDataList);
serverTableData.setGroupDataList(groupDataList);
serverTableData.setMergeColumn(0);
return serverTableData;
}
}
结果
参考文档