使用场景
支持页面的数据导出,基于springboot 2.3.5 使用 poi-ooxml 5.2.1
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.5.RELEASE</version>
<relativePath/>
</parent>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>5.2.1</version>
</dependency>
定制化
- 在每个需要导出的服务中硬编码,定义表头如:
public static ImmutableList<String> TITLE_NAMES = ImmutableList.of("任务id", "用途名称", "开关状态", "优先级", "开始时间");
- 获取需要导出的数据
- 通过excel api进行输出
public static void writeExcel(List<List> list, OutputStream outputStream) throws IOException {
//创建工作簿
XSSFWorkbook xssfWorkbook = new XSSFWorkbook();
XSSFSheet xssfSheet = xssfWorkbook.createSheet();
xssfSheet.setDefaultColumnWidth(15);
//把List里面的数据写到excel中
for (int i = 0; i < list.size(); i++) {
XSSFRow xssfRow = xssfSheet.createRow(i);
List subList = list.get(i);
for (int j = 0; j < subList.size(); j++) {
XSSFCell xssfCell = xssfRow.createCell(j);
xssfCell.setCellValue(subList.get(j) == null ? null : (String) subList.get(j));
}
}
//用输出流写到excel
try {
xssfWorkbook.write(outputStream);
outputStream.flush();
} finally {
if (outputStream != null) {
outputStream.close();
}
if (xssfWorkbook != null) {
xssfWorkbook.close();
}
}
}
如上的实现方式当多处需要导出时,构造对应的数据结构时存在大量的代码重复(不过这种定制化程度比较高),对于一些简单的单模型的数据导出可以考虑方式二
基于反射+元数据表
- 定义一张用于存储导出数据信息的表,如下是一种可能的存储结构
create table `export_info`(
`id` INT unsigned NOT NULL AUTO_INCREMENT COMMENT '唯一记录id',
`table_name` varchar(20) NOT NULL DEFAULT '' COMMENT '表名称',
`attr` varchar(20) NOT NULL DEFAULT '' COMMENT '字段名称',
`val` varchar(20) NOT NULL DEFAULT '' COMMENT '字段中文名称',
`ordered` tinyint NOT NULL DEFAULT '0' COMMENT '顺序',
`status` tinyint NOT NULL DEFAULT 1 COMMENT '0:启用1:关闭',
`creator` varchar(30) NOT NULL DEFAULT '0' COMMENT '创建者',
`updater` varchar(30) DEFAULT '0' COMMENT '修改者',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '记录创建时间',
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '记录最后更新时间',
PRIMARY KEY (`id`),
unique KEY `uk_table_attr` (`table_name`, `attr`),
KEY `idx_update`(`update_time`)
)ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='导出信息表';
- 这个表可以用于前端选择需要导出的字段,并过滤前端传入的字段
- 使用反射填充表格信息 data是需要导出的数据行
int rowSize = data.size();
Class clz = data.get(0).getClass();
Map<String,Field> columnFieldMap = fieldMap(columnNames,clz);
for (int i = 0; i < rowSize; i++) {
XSSFRow xssfRow = xssfSheet.createRow(i + 1);
T obj = data.get(i);
//反射获取数据
int j = 0;
for(String column: columnNames){
XSSFCell xssfCell = xssfRow.createCell(j++);
Field f = columnFieldMap.get(column);
f.setAccessible(true);
Object val = f.get(obj);
xssfCell.setCellValue(val == null ? null : String.valueOf(val));
}
}
- 得到完整的excel文件后通过输出流输出,可以输出到本地或者服务器
关于大数据量的导出,有思路的同学欢迎留言