Java实现导出数据为Excel(多个sheet合成一张Excel)
前言:
本功能是springboot+mybatis为大的框架,整合hutool工具中的Excel工具,实现导出数据为Excel(多张Excel为sheet合成一张Excel)功能。
一、引入Excel专属依赖:
<!--解析excel-->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.1.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.poi/poi -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>4.1.2</version>
</dependency>
<!--处理2007 excel-->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-schemas</artifactId>
<version>4.1.2</version>
</dependency>
二、Excel工具类
ExcelUtils工具类
public class ExcelUtils {
/**
* 导出多个 Sheet 页
* @param response
* @param sheetList 页数据
* @param fileName 文件名
*/
public static void exportExcel(HttpServletResponse response, List<SheetDTO> sheetList, String fileName) {
ExcelWriter bigWriter = ExcelUtil.getBigWriter();
// 重命名第一个Sheet的名称,不然会默认多出一个Sheet1的页
bigWriter.renameSheet(0, sheetList.get(0).getSheetName());
for (SheetDTO sheet : sheetList) {
// 指定要写出的 Sheet 页
bigWriter.setSheet(sheet.getSheetName());
//Integer[] columnWidth = sheet.getColumnWidth();
List<Integer> columnWidth = sheet.getColumnWidth();
if (columnWidth == null || columnWidth.size() != sheet.getFieldAndAlias().size()) {
// 设置默认宽度
for (int i = 0; i < sheet.getFieldAndAlias().size(); i++) {
bigWriter.setColumnWidth(i, 25);
}
} else {
// 设置自定义宽度
for (int i = 0; i < columnWidth.size(); i++) {
bigWriter.setColumnWidth(i, columnWidth.get(i));
}
}
// 设置字段和别名
bigWriter.setHeaderAlias(sheet.getFieldAndAlias());
// 设置只导出有别名的字段
bigWriter.setOnlyAlias(true);
// 设置默认行高
bigWriter.setDefaultRowHeight(18);
// 设置冻结行
bigWriter.setFreezePane(1);
// 一次性写出内容,使用默认样式,强制输出标题
bigWriter.write(sheet.getCollection(), true);
// 设置所有列为自动宽度,不考虑合并单元格
//bigWriter.autoSizeColumnAll();
}
ServletOutputStream out = null;
try {
//response为HttpServletResponse对象
response.setContentType("application/vnd.ms-excel;charset=utf-8");
response.setHeader("Content-Disposition",
"attachment;filename=" +
URLEncoder.encode(fileName + DateUtil.today() + ".xlsx", "UTF-8"));
out = response.getOutputStream();
bigWriter.flush(out, true);
} catch (IOException e) {
e.printStackTrace();
} finally {
// 关闭writer,释放内存
bigWriter.close();
}
//此处记得关闭输出Servlet流
IoUtil.close(out);
}
}
SheetDTO工具类对象类
/**
* Excel - Sheet页
*/
public class SheetDTO implements Serializable {
private static final long serialVersionUID = 1L;
/**
* sheet页名称
*/
private String sheetName;
/**
* 字段和别名,如果使用这个,properties 和 titles可以不用处理
* Map<字段, 别名> 如:Map<"name", "姓名">
*/
private Map<String, String> fieldAndAlias;
/**
* 列宽<br/>
* 设置列宽时必须每个字段都设置才生效(columnWidth.size = fieldAndAlias.size)
*/
private List<Integer> columnWidth;
/**
* 数据集
*/
private Collection<?> collection;
public SheetDTO() {
}
/**
* @param sheetName sheet页名称
* @param fieldAndAlias 字段和别名
* @param collection 数据集
*/
public SheetDTO(String sheetName, Map<String, String> fieldAndAlias, Collection<?> collection) {
super();
this.sheetName = sheetName;
this.fieldAndAlias = fieldAndAlias;
this.collection = collection;
}
public String getSheetName() {
return sheetName;
}
public void setSheetName(String sheetName) {
this.sheetName = sheetName;
}
public Map<String, String> getFieldAndAlias() {
return fieldAndAlias;
}
public void setFieldAndAlias(Map<String, String> fieldAndAlias) {
this.fieldAndAlias = fieldAndAlias;
}
public List<Integer> getColumnWidth() {
return this.columnWidth;
}
public void setColumnWidth(List<Integer> columnWidth) {
this.columnWidth = columnWidth;
}
public Collection<?> getCollection() {
return collection;
}
public void setCollection(Collection<?> collection) {
this.collection = collection;
}
}
三、Controller层
我这里实现的是前端传过来一个ids数组,后端获取数组,通过单个id获取数据库数据,然后将每个id获取的数据整理到一个sheet里面,然后将多个sheet整合到一个Excel里面。
/* *
* 导出(单个或者批量导出)
*
* @param ids
* @return*/
@GetMapping("/correction/export/{ids}")
@ResponseBody
@ApiOperation(value = "单个或者批量导出")
@ApiImplicitParam(name = "ids", value = "单个或者多个id值数组", required = true, paramType = "[]String")
public void correctionExport(@PathVariable(value = "ids") String ids, HttpServletResponse response) throws UnsupportedEncodingException {
int index = 0;//Excel sheet计数
List<SheetDTO> sheetList = new ArrayList<SheetDTO>();// 创建sheet集合,用来存储sheet
//根据传过来的批次id查询日志详情,将日志信息导入sheet表中
for (String id :
Convert.toStrArray(ids)) {
index++;
//获取批次详情,方便下面获取批次中的信息对sheet命名
TaskInstanceBatch taskInstanceBatch = taskInstanceBatchService.selectByPrimaryKey(id);
//声明一个空的taskResultDetail,方面下面调用selectTaskResultDetailList方法
TaskResultDetail taskResultDetail = new TaskResultDetail();
//用来存储所有查询的数据,这些数据存储的是查询selectTaskResultDetailList后进行筛选后的详细信息
List<TaskResultDetail> listResult = new ArrayList<TaskResultDetail>();
//设置请求分页数据
startPage();
List<TaskResultDetail> list = taskResultDetailService.selectTaskResultDetailList(taskResultDetail, id);
for (TaskResultDetail tDetail : list
) {
if (tDetail.getDisposeType() == 2) {
listResult.add(tDetail);
}
}
HashMap<String, String> map = new HashMap<>();
// 设置只导出有别名的字段
map.put("uuid", "序号");
map.put("bizDate", "业务日期");
map.put("batchId", "任务每次跑的批次");
map.put("createTime", "批次创建时间");
map.put("startTime", "批次运行时间");
map.put("endTime", "批次结束时间");
map.put("tiigerFlagLog", "触发方式");
map.put("ruleId", "规则id");
map.put("ruleName", "规则名称");
map.put("inputDatabase", "输入主库id");
map.put("databaseName", "数据库名");
map.put("inputTableName", "输入主表名");
map.put("outDatabase", "输出主库");
map.put("outTableName", "输出主表");
map.put("dateMainCode", "数据主键");
map.put("runStateLog", "运行状态");
map.put("errorInfo", "失败时的错误信息");
map.put("warnValue", "警告值");
map.put("realValue", "输出实际值");
map.put("compareResulet", "比较结果");
map.put("reviseField", "纠错补全字段");
String name = index + "补全";
if (taskInstanceBatch.getOrgCode() != null && !taskInstanceBatch.getOrgCode().equals("")) {
name = name + taskInstanceBatch.getOrgCode();
}
if (taskInstanceBatch.getStartTime() != null) {
name = name + DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, taskInstanceBatch.getStartTime());
}
SheetDTO sheet = new SheetDTO();
sheet.setFieldAndAlias(map);
sheet.setSheetName(name);
sheet.setCollection(listResult);
sheetList.add(sheet);
}
ExcelUtils.exportExcel(response, sheetList, "纠错");
}
下面截屏对这段代码进行说明,和标注处有用的,和具体使用方式。