栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

EasyExcel——Excel读写工具

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

EasyExcel——Excel读写工具

EasyExcel——Excel读写工具
  • 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,填充数据

Excel 读写 1.1 EasyExcel

搬运参考地址:庄家钜(语雀)

1.1.1 依赖

	com.alibaba
	easyexcel
	3.0.5

1.1.2 实体对象
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 ReadListener {
    //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);
    }
}
1.1.4 测试类(读)
@SpringBootTest
public class EasyExcelTest {

    
    @Test
    void readExcelTet(){
        String fileName = "E:\Desktop\tempFile" + File.separator + "员工信息表.xls";
        
        EasyExcel.read(fileName, Employee.class, new ExcelReadListener()).sheet().doRead();
    }

}

读取结果测试:

1.1.5 测试类(写)

单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();
    }


1.1.6 EasyExcel 工具类(读)
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 Converter {

    //日期的格式化字符串
    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.1.7.1 自定义转换器的使用

方法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 依赖

EasyExcel 的依赖依赖于POI的依赖。使用上面EasyExcel的依赖即可。

2.2.2 导出Excel,填充数据
@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> hotmeals = (List>) map.get("hotSetmeal");
        int rowIndex = 12;
        for (Map hotmeal : hotmeals) {
            row = sheet.getRow(rowIndex);
            row.getCell(4).setCellValue(String.valueOf(hotmeal.get("name")));
            row.getCell(5).setCellValue(Integer.valueOf(hotmeal.get("setmeal_count").toString()));
            row.getCell(6).setCellValue(Double.valueOf(hotmeal.get("proportion").toString()));
            rowIndex++;//注意填充数据的开始行
        }
        //获取到输出流
        ServletOutputStream outputStream = response.getOutputStream();
        //设置浏览器能解析的内容类型
        response.setContentType("application/vnd.ms-excel");
        //设置响应头
        response.setHeader("content-Disposition", "attachment;filename=" + URLEncoder.encode("运营数据报表.xlsx", "UTF-8"));
        //向输出流中写入Excel文件
        xssfWorkbook.write(outputStream);
        //清理资源
        outputStream.flush();
        outputStream.close();
        xssfWorkbook.close();
        return null; //response提交过后不能在返回消息,否则会报错
    } catch (Exception e) {
        e.printStackTrace();
        return new Result(false, "导出运营数据失败");
    }
}

导出的效果图

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/684492.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号