后端处理Excel是比较常见的使用场景,主要有两方面:
- 解析Excel,然后插入数据库什么的
- 把数据库的内容,导出为Excel
无论是哪一种,发现使用EasyExcel都是比较方便的,这里简单介绍一下用法,这里阿里巴巴开源一个库,github地址是https://github.com/alibaba/easyexcel,其实github上面的例子已经非常简洁了,我甚至想拿过来,直接放在这里
EasyExcel解析Excel
//这里主要加载Excel文件,而解析主要在NoModelDataListener
@Test
public void loadExcel() {
String fileName = "C:\\Users\\admin\\Desktop\\data.xlsx";
// 这里 只要,然后读取第一个sheet 同步读取会自动finish
EasyExcel.read(fileName, new NoModelDataListener()).sheet().doRead();
}
public class NoModelDataListener extends AnalysisEventListener<Map<Integer, String>> {
//读取到的数据,会回调这里
@Override
public void invoke(Map<Integer, String> data, AnalysisContext context) {
//自定义处理数据
saveData(data);
}
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
}
}
生成Excel
我这里,主要介绍一下数据库生成,直接根据Entity生成的方法也比较简单
public class TicketHistory {
//表示忽略这个属性,不放在Excel
@ExcelIgnore
public static DecimalFormat decimalFormat = new DecimalFormat("0.00");
//设置该单元格的宽度
@ColumnWidth(20)
// 设置单元格式标题,序号(序号越小,越靠前),转换器
@ExcelProperty(value = "是否已經發送郵件", index = 17, converter = NotifyStatusConverter.class)
private Integer notifyStatus;
//设置该单元格的宽度
@ColumnWidth(20)
@ExcelProperty(value = "推薦人", index = 18)
private String recommender;
//设置该单元格的宽度
@ColumnWidth(30)
@ExcelProperty(value = " 會員登記", index = 19)
private String memberReg;
//设置该单元格的宽度
@ColumnWidth(20)
// 设置单元格式标题,序号(序号越小,越靠前),转换器
@ExcelProperty(value = "購買時間", index = 1, converter = TimeConverter.class)
private Long addTime;
//时间转换,把时间戳转格式化
public static class TimeConverter implements Converter<Long> {
@Override
public WriteCellData<?> convertToExcelData(WriteConverterContext<Long> context) {
return new WriteCellData<>(StaticUtil.secondMonthDayFormat.format(context.getValue()));
}
}
//状态,原本是用数字表示的,导出的时候,转换为文字描述
public static class PayStatusConverter implements Converter<Integer> {
@Override
public WriteCellData<?> convertToExcelData(WriteConverterContext<Integer> context) {
return new WriteCellData<>(context.getValue() == 1 ? "已經支付" : "未支付");
}
}
//状态,原本是用数字表示的,导出的时候,转换为文字描述
public static class NotifyStatusConverter implements Converter<Integer> {
@Override
public WriteCellData<?> convertToExcelData(WriteConverterContext<Integer> context) {
return new WriteCellData<>(context.getValue() == 1 ? "已經發送郵件" : "未通知");
}
}
//金额格式,这里进行转换
public static class PriceConverter implements Converter<Integer> {
@Override
public WriteCellData<?> convertToExcelData(WriteConverterContext<Integer> context) {
return new WriteCellData<>(decimalFormat.format((float) context.getValue() / 100));
}
}
}
上面是实体类,可以在Controller中直接返回给客户,如下:
response.setContentType("application/vnd.ms-excel");// 设置文本内省
response.setCharacterEncoding("utf-8");// 设置字符编码
response.setHeader("Content-disposition", "attachment;filename=TicketRecord.xlsx"); // 设置响应头,以及下载的文件名称
EasyExcel.write(response.getOutputStream(), TicketHistory.class).sheet("ticket").doWrite(ticketHistories); //用io流来写入数据
也可以直接保存在本地
EasyExcel.write(new File(fileName), TicketHistory.class)
.needHead(true)//是否显示表头
.sheet("test").doWrite(ticketHistories);