- Excel 读写
- 1.1 EasyExcel
- 1.1.1 依赖
- 1.1.2 实体对象
- 1.1.3 解析数据的监听器类(读)
- 1.1.4 测试类(读)
- 1.1.5 测试类(写)
- 1.1.6 EasyExcel 工具类(读)
- 1.1.7 自定义转换器(拓展)
- 1.1.7.1 自定义转换器的使用
- 2.2 POI
- 2.2.1 依赖
- 2.2.2 导出Excel,填充数据
搬运参考地址:庄家钜(语雀)
1.1.1 依赖1.1.2 实体对象com.alibaba easyexcel 3.0.5
public class Employee {
//不建议 index 和 name 同时用,要么一个对象只用index,要么一个对象只用name去匹配
//强制读取第1个
@ExcelProperty(index = 0)
private Integer eid;
//用名字去匹配,这里需要注意,如果名字重复,会导致只有一个字段读取到数据
@ExcelProperty("姓名")
private String ename;
@ExcelProperty("性别")
private String esex;
@ExcelProperty("年龄")
private Integer eage;
@ExcelProperty("工资")
private Double esalary;
//省略 get、set、构造 方法
}
1.1.3 解析数据的监听器类(读)
@Component public class ExcelReadListener implements ReadListener1.1.4 测试类(读){ //slf4j 日志 private Logger log = LoggerFactory.getLogger(ExcelReadListener.class); //解析的行数 private Integer analysisCount = 0; @Override public void invoke(Employee employee, AnalysisContext analysisContext) { log.info("解析到一条数据:{}", JSON.toJSONString(employee)); analysisCount++; } @Override public void doAfterAllAnalysed(AnalysisContext analysisContext) { log.info("共解析数据:{}",analysisCount); } }
@SpringBootTest
public class EasyExcelTest {
@Test
void readExcelTet(){
String fileName = "E:\Desktop\tempFile" + File.separator + "员工信息表.xls";
EasyExcel.read(fileName, Employee.class, new ExcelReadListener()).sheet().doRead();
}
}
读取结果测试:
单sheet写入:
//写入到Excel文件的一个Sheet中
@Test
public void writeToExcel() {
String filePath = "E:\Desktop\tempFile\员工信息表(写入测试).xls";
List list=new ArrayList<>();
list.add(new Employee(1,"Jack","男",26,8500.0));
list.add(new Employee(2,"Rose","女",24,8600.5));
EasyExcel.write(filePath,Employee.class).sheet().doWrite(list);
}
写入效果测试:
多sheet写入:
//写入到Excel文件多个Sheet中
@Test
public void writeToExcel2() {
String filePath = "E:\Desktop\tempFile\员工信息表(多个sheet写入测试).xls";
//将每个sheet的数据写入一个集合中,多个sheet对应多个集合
List list1 = new ArrayList<>();
list1.add(new Dept(1, "研发部"));
list1.add(new Dept(2, "销售部"));
List list2 = new ArrayList<>();
list2.add(new Employee(1, "Jack", "男", 26, 8500.0));
list2.add(new Employee(2, "Rose", "女", 24, 8600.5));
//Excel Writer 此工具用于通过 POI 将值写入 Excel
ExcelWriter excelWriter = EasyExcel.write(filePath).build();
//写单
WriteSheet sheet1 = EasyExcel.writerSheet(0, "部门表").head(Dept.class).build();
excelWriter.write(list1, sheet1); //将数据写入工作表
//写单
WriteSheet sheet2 = EasyExcel.writerSheet(1, "员工表").head(Employee.class).build();
excelWriter.write(list2, sheet2); //将数据写入工作表
//finish()调用,关闭 IO;保证文件不损坏
excelWriter.finish();
}
public class EasyExcelUtil{
public static List readFromExcel(InputStream stream, Class tClass, int sheetNo) {
//slf4j 日志
Logger log = LoggerFactory.getLogger(EasyExcelUtil.class);
//解析的行数
final Integer[] analysisCount = {0};
List list = new ArrayList<>();
EasyExcel.read(stream)
//反射获取类型
.head(tClass)
//读取的excel的sheet索引
.sheet(sheetNo)
//注册监听器
.registerReadListener(new AnalysisEventListener() {
@Override
public void invoke(T t, AnalysisContext analysisContext) {
log.info("解析到一条数据:{}", JSON.toJSONString(t));
list.add(t);
analysisCount[0]++;
}
@Override
public void doAfterAllAnalysed(AnalysisContext analysisContext) {
log.info("读取数据完毕,共解析数据:{}",analysisCount[0]);
}
}).doRead();
return list;
}
public static void writeToExcel(HttpServletResponse response,Class clazz,String fileName,String sheetName,List dataList){
ServletOutputStream outputStream = null;
//设置响应内容类型(内容类型可以和编码一起设置)
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8");
//设置响应头(inline :将文件内容直接显示在页面;attachment:弹出对话框让用户下载)
response.setHeader("Content-Disposition","attachment;fileName="+fileName+".xlsx");
try {
outputStream = response.getOutputStream();
EasyExcel.write(outputStream,clazz).registerConverter(new LocalDateConverter()).sheet(sheetName).doWrite(dataList);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (null != outputStream){
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
1.1.7 自定义转换器(拓展)
EasyExcel默认不支持LocalDate类型,即不能把该类型数据写入到Excel的Cell中,此时要定义一个转换器;
public class LocalDateConverter implements Converter1.1.7.1 自定义转换器的使用{ //日期的格式化字符串 private final String dateFormatStr="yyyy-MM-dd"; //回到 Java 中的对象类型 @Override public Class> supportJavaTypeKey() { return LocalDate.class; } //回到excel中的数据类型 @Override public CellDataTypeEnum supportExcelTypeKey() { return CellDataTypeEnum.STRING; } @Override public LocalDate convertToJavaData(ReadCellData> cellData, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception { LocalDate localDate = LocalDate.parse(cellData.getStringValue(), DateTimeFormatter.ofPattern(dateFormatStr)); return localDate; } @Override public WriteCellData> convertToExcelData(LocalDate localDate, ExcelContentProperty contentProperty, GlobalConfiguration globalConfiguration) throws Exception { WriteCellData> writeCellData = new WriteCellData<>(localDate.format(DateTimeFormatter.ofPattern(dateFormatStr))); return writeCellData; } }
方法1: 在导出数据的pojo类的LocalDate属性上多配置一个converter属性;
@ExcelProperty(value = "出生日期",converter = LocalDateConverter.class) private LocalDate birthday;
方法2:直接在EasyExcel写入数据方法上去注册转换器;
EasyExcel.write(pathName,Student.class).registerConverter(new LocalDateConverter()).sheet("学生信息表").doWrite(studetnList);
2.2 POI
2.2.1 依赖
2.2.2 导出Excel,填充数据EasyExcel 的依赖依赖于POI的依赖。使用上面EasyExcel的依赖即可。
@GetMapping("exportBusinessReport")
public Result exportBusinessReportExcel(HttpServletResponse response) throws Exception{
try {
//获取运营数据
Map map = reportService.getBusinessReport();
//获取到Excel模板文件的路径
ClassPathResource classPathResource = new ClassPathResource("templates/report_template.xlsx");
InputStream inputStream = classPathResource.getInputStream();
//创建一个代表Exel文件(WorkBook)的对象
XSSFWorkbook xssfWorkbook = new XSSFWorkbook(inputStream);
//获取到第1个表格
XSSFSheet sheet = xssfWorkbook.getSheetAt(0);
//获取表格里的行
XSSFRow row = sheet.getRow(2);
//设置行中第6列的值
row.getCell(5).setCellValue(map.get("reportDate").toString());
row = sheet.getRow(4);
row.getCell(5).setCellValue(Integer.valueOf(map.get("todayNewMember").toString()));//今日会员数
row.getCell(7).setCellValue(Integer.valueOf(map.get("totalMember").toString()));//总会员数
row = sheet.getRow(5);
row.getCell(5).setCellValue(Integer.valueOf(map.get("thisWeekNewMember").toString()));//本周新增会员数
row.getCell(7).setCellValue(Integer.valueOf(map.get("thisMonthNewMember").toString()));//本月新增会员数
row = sheet.getRow(7);
row.getCell(5).setCellValue(Integer.valueOf(map.get("todayOrderNumber").toString()));//今日预约数
row.getCell(7).setCellValue(Integer.valueOf(map.get("todayVisitsNumber").toString()));//今日到诊数
row = sheet.getRow(8);
row.getCell(5).setCellValue(Integer.valueOf(map.get("thisWeekOrderNumber").toString()));//本周预约数
row.getCell(7).setCellValue(Integer.valueOf(map.get("thisWeekVisitsNumber").toString()));//本周到诊数
row = sheet.getRow(9);
row.getCell(5).setCellValue(Integer.valueOf(map.get("thisMonthOrderNumber").toString()));//本月预约数
row.getCell(7).setCellValue(Integer.valueOf(map.get("thisMonthVisitsNumber").toString()));//本月到诊数
//热门套餐
List
导出的效果图



