最近项目上有excel导入、导出的需求,基于阿里巴巴开源的easyExcel做了一个简单的封装,希望能给大家带来一定的帮助,如果有问题请留言评论区。
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>easyexcel</artifactId>
<version>3.0.1</version>
</dependency>
工具类
博主是在springBoot项目中使用的此工具类,所以如果使用@Autowired导入此工具类的话,请注意在此工具类上加上@Compoent注解 将bean注入容器管理
/**
* @param <T>
* @param <K>
* @author yuanChen
* @Date 2022-10-10
* @Description 基于阿里巴巴easyExcel实现,实现基础常用功能,可根据需求参考文档进行优化
* 功能:1.excel生成至本地 2.返回流供前端下载 3.读取本地excel文件 4.读取前端上传
* excel文件
* 参考文档https://easyexcel.opensource.alibaba.com/
* 注意文件路径在windows下,“/”,“\”都可以识别,unix只识别“/”,所以路径的拼接,更推荐使用File.separator
* 如:/excel/sampleData.xlsx 推荐使用 String path = File.separator + "excel" + File.separator + "sampleData.xlsx";
*/
@Component
public class ExcelUtils<T, K> {
/**
* 导出excel文件至浏览器下载
*
* @param list list格式的数据源,模板中使用{.}
* @param map map格式的数据源,模板中使用{},与list相比少了.
* @param response 相应浏览器的请求
* @param formWorkPathName 模板文件的路径 相对于resource文件夹,/excel/sampleData.xlsx,resource文件下excel文件夹下的sampleData文件
* @param outPutFileName 输出的文件名
*/
public void exportExcelToBrowser(T list, K map, HttpServletResponse response, String formWorkPathName, String outPutFileName) {
//模板文件编译后的位置
InputStream path = this.getClass().getResourceAsStream(formWorkPathName);
String filename = null;
try {
// 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
filename = URLEncoder.encode(outPutFileName + System.currentTimeMillis(), "utf-8");
//ExcelWriter excelWriter = EasyExcel.write(filename).withTemplate(templateFileName).build();
WriteSheet writeSheet = EasyExcel.writerSheet()
.build();
//使用response.getOutputStream()下载,并使用项目下的模板填充
ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream())
.withTemplate(path)
.build();
//数据源,此处使用的方法为easyExcel的模板填充功能,与write不一样
if (map != null) {
excelWriter.fill(map, writeSheet);//存入map
}
if (list != null) {
excelWriter.fill(list, writeSheet);//存入list
}
//下载
response.setContentType("application/vnd.ms-excel");
response.setCharacterEncoding("utf-8");
response.setHeader("Content-disposition", "attachment;filename=" + filename + ".xlsx");
//必须要finish才会写入,不finish只会创建一个empty的文件。关闭外层流后,内层流也会关闭
excelWriter.finish();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 导出excel文件至本地
* @param list list格式数据源,模板中使用{.}
* @param map map格式数据源,模板中使用{},与list相比少了.
* @param formWorkPathName 模板文件的路径 相对于resource文件夹,/excel/sampleData.xlsx,resource文件下excel文件夹下的sampleData文件
* @param outPutPathName 保存至本地的文件路径 D://excel/,注意末尾的”/“不要省略
* @param outPutFileName 保存至本地的文件名
*/
public void exportExcelToDisk(T list, K map, String formWorkPathName, String outPutPathName, String outPutFileName) {
//模板文件编译后的位置
InputStream path = this.getClass().getResourceAsStream(formWorkPathName);
try {
//excel文件保存至本地的路径
FileOutputStream fileOutputStream = new FileOutputStream(outPutPathName + outPutFileName + System.currentTimeMillis() + ".xlsx");
//writeSheet可以指定excel的哪一个sheet
WriteSheet writeSheet = EasyExcel.writerSheet()
.build();
//使用本地路径下载,并使用模板填充
ExcelWriter excelWriter = EasyExcel.write(fileOutputStream)
.withTemplate(path)
.build();
//数据源,此处使用的方法为easyExcel的模板填充功能,与write不一样
if (map != null) {
excelWriter.fill(map, writeSheet);//存入map
}
if (list != null) {
excelWriter.fill(list, writeSheet);//存入list
}
//必须要finish才会写入,不finish只会创建一个empty的文件。关闭外层流后,内层流也会关闭
excelWriter.finish();
} catch (FileNotFoundException e) {
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 读取本地路径下的excel文件
* 路径示例:D://excel/demoData.xlsx
* @param filePathName 文件路径
*/
public void readExcelFromDisk(String filePathName) {
// 这里 需要指定读用哪个class去读,然后默认读取第一个sheet 文件流会自动关闭
// 直接new了监听器,lambda表达式进行数据后续处理
EasyExcel.read(filePathName, DemoDataEntity.class, new PageReadListener<DemoDataEntity>(dataList -> {
for (DemoDataEntity demoData : dataList) {
System.out.println(demoData);
}
})).sheet().doRead();//sheet()可指定读取哪一个sheet,支持名字和索引,索引起始为0
}
/**
* 读取前端传输的excel文件
*
*/
public void readExcelFromBrowser(MultipartFile file) {
try {
InputStream excelFileInputStream = file.getInputStream();
// 这里 需要指定读用哪个class去读,然后默认读取第一个sheet 文件流会自动关闭
// 直接new了监听器,lambda表达式进行数据后续处理
EasyExcel.read(excelFileInputStream, DemoDataEntity.class, new PageReadListener<DemoDataEntity>(dataList -> {
for (DemoDataEntity demoData : dataList) {
System.out.println(demoData);
}
})).sheet().doRead();//sheet()可指定读取哪一个sheet,支持名字和索引,索引起始为0
} catch (IOException e) {
e.printStackTrace();
}
}
}
实体类
在读取excel的时候需要,通过注解来映射excel的表头和实体类的字段
/**
* excel导入entity示例
* @ExcelProperty("") 注解说明: 对应的就是excel表头,支持字符串和索引
* 字符串使用举例:@ExcelProperty("日期") 对应的是excel表格里 名为日期的 列
* 索引使用举例:@ExcelProperty(index = 2) 对应的是excel表格的第三列,起始索引为0
*/
@Data
public class DemoDataEntity {
/**
* id
*/
@ExcelProperty("id")
private Integer id;
/**
* name
*/
@ExcelProperty("文件名称")
private String name;
/**
* url
*/
@ExcelProperty("下载地址")
private String url;
/**
* day
*/
@ExcelProperty("日期")
@JsonFormat(pattern="yyyy-MM-dd",timezone="GMT+8")
private Date day;
/**
* insert_time
*/
@ExcelProperty("插入时间")
@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
private Date insertTime;
}
控制层-读取excel的两个方法使用方式
@PostMapping ("/export/testRead")
@ResponseBody
public void testRead() {
String filePathName = "D:"+ File.separator + "excel/demoData.xlsx";
System.out.println(filePathName);
excelUtils.readExcelFromDisk(filePathName);
}
@PostMapping ("/export/testReadFromExcel")
@ResponseBody
public void testRead(@RequestParam("file") MultipartFile file) {
excelUtils.readExcelFromBrowser(file);
}
读取excel,postMan模拟前端发送文件
控制层-导出excel的两个方法使用方式
使用postMan模拟浏览器页面下载导出excel时,要使用发送并下载,以及params传参方式
/**
*
* 通过浏览器页面下载导出excel
* @param
* @param response
*/
@GetMapping("/export/excelToBrowser")
@ResponseBody
public void exportExcelToBrowser(HttpServletRequest request, HttpServletResponse response) {
//从前端获取查询参数
//姓名
String xm = ParamsUtils.getParamsStringValue(request.getParameter("xm"));
PersonTO personDTO = new PersonDTO();
personDTO.setXm(xm);
//查询出来的数据放入list,以上代码根据自己的业务需求进行改变
List<PersonVO> list = PersonNewMapper.getPersonList(personDTO);
//模板文件编译后的位置 是相对于resources文件而言的路径
String pathName = "/excel/noSampleToday.xlsx";
//下载的excel文件名
String outPutFileName = "人员信息";
excelUtils.exportExcelToBrowser(list, null, response, pathName, outPutFileName);
}
/**
*
* 下载导出excel到本地路径
* @param
* @param response
*/
@PostMapping("/export/ExcelToDisk")
@ResponseBody
public void exportExcelToDisk() {
//查询出来的数据放入list,以下代码根据自己的业务需求进行改变
List<PersonVO> list = PersonNewMapper.getPersonList();
//模板文件编译后的位置 是相对于resources文件而言的路径
String pathName = "/excel/noSampleToday.xlsx";
//输出的路径
String outPutFileName = "D://excel/";
//下载的excel文件名
String outPutFileName = "人员信息";
excelUtils.exportExcelToDisk(list, null, response, pathName, outPutPathName, outPutFileName);
}
导出excel时 所需要的模板文件
如果数据源为list则使用{.},map使用{}
注意,模板文件一定要放到resource目录下!!!!!!