zoukankan      html  css  js  c++  java
  • EasyExcel——写文件

    easyExcel是阿里巴巴开源的一个excel处理框架,以使用简单、节省内存著称。
    64M内存1分钟内读取75M(46W行25列)的Excel(当然还有急速模式能更快,但是内存占用会在100M多一点)
    可有效避免OOM。
    致敬阿里:

    ---参照官方文档进行编辑,主要记录了工作中用到的,用的少的就没有记录
    ---官方文档 : https://www.yuque.com/easyexcel
    ---官方github : https://github.com/alibaba/easyexcel

    写入数据实体类

    @Data
    public class DemoData {
        @ExcelProperty("字符串标题")
        private String stringData;
        @ExcelProperty("整型标题")
        private Integer  integerData;
        @ExcelProperty("日期标题")
        private Date  dateData;
        @NumberFormat("#.##%")
        private Double  dounleData;
    }
    
    • @ExcelProperty("***") 标题行名称

    构造数据的方法

        private List<DemoData> data() {
            List<DemoData> list = new ArrayList<DemoData>();
            for (int i = 0; i < 10; i++) {
                DemoData data = new DemoData();
                data.setStringData("字符串" + i);
                data.setIntegerData(i);
                data.setDateData(new Date());
                data.setDounleData(0.56);
                list.add(data);
            }
    
            return list;
        }
    

    创建对象的写

    简单写入

            //写法一
            String fileName = "c://Users//****";
            // 这里 需要指定写用哪个class去写,然后写到第一个sheet,名字为模板 然后文件流会自动关闭
            EasyExcel.write(fileName, DemoData.class).sheet("模板").doWrite(data());
            
            //写法二
            String fileName = "c://Users//****";
            // 这里 需要指定写用哪个class去写
            ExcelWriter excelWriter = EasyExcel.write(fileName, DemoData.class).build();
            WriteSheet writeSheet = EasyExcel.writerSheet("模板").build();
            excelWriter.write(data(), writeSheet);
            // 千万别忘记finish 会帮忙关闭流
            excelWriter.finish();
    

    根据参数只导出指定列

    
      String fileName = "c://Users//****";
      
      
      //排除掉不想输出的列 假设我们要忽略 stringData
      Set<String> excludeColumnFiledNames = new HashSet<String>();
      excludeColumnFiledNames.add("stringData");
      EasyExcel.write(fileName, DemoData.class).excludeColumnFiledNames(excludeColumnFiledNames).sheet("模板").doWrite(data());
      
      
      
      //只输出实体类我们想要的字段  假设我们只要导出 stringData
      Set<String> includeColumnFiledNames = new HashSet<String>();
      includeColumnFiledNames.add("stringData");
      EasyExcel.write(fileName, DemoData.class).includeColumnFiledNames(includeColumnFiledNames).sheet("模板").doWrite(data());
    

    指定写入的列

    修改实体类注解即可

        @ExcelProperty(value = "数字标题", index =5)
        private Integer  integerData;
    

    复杂头写入

    修改实体类注解即可

    @ExcelProperty({"主标题", "字符串标题"})
    @ExcelProperty({"主标题", "日期标题"})
    @ExcelProperty({"主标题", "数字标题"})
    

    重复多次写入(写到单个或者多个Sheet)

    同一个sheet多次写

    String fileName = "c://Users//****";
    ExcelWriter excelWriter = EasyExcel.write(fileName, DemoData.class).build();
    
    //同一个sheet只要创建一次
    WriteSheet writeSheet = EasyExcel.writerSheet("模板").build();
    
    // 调用写入,实际使用时根据数据库分页的总的页数来
    for (int i = 0; i < 5; i++) {
        // 分页去数据库查询数据 这里可以去数据库查询每一页的数据
        List<DemoData> data = data();
        excelWriter.write(data, writeSheet);
    }
    /// 千万别忘记finish 会帮忙关闭流
    excelWriter.finish();
    

    写到不同的sheet 同一个对象

    String fileName = "c://Users//****";
    ExcelWriter excelWriter = EasyExcel.write(fileName, DemoData.class).build();
    
    // 去调用写入,实际使用时根据数据库分页的总的页数来。最终会写到5个sheet里面
    for (int i = 0; i < 5; i++) {
        // 每次都要创建writeSheet 这里注意必须指定sheetNo 而且sheetName必须不一样
        WriteSheet writeSheet = EasyExcel.writerSheet(i, "模板" + i).build();
        // 分页去数据库查询数据 这里可以去数据库查询每一页的数据
        List<DemoData> data = data();
        excelWriter.write(data, writeSheet);
    }
    /// 千万别忘记finish 会帮忙关闭流
    excelWriter.finish();
    

    写到不同的sheet 不同的对象

    String fileName = "c://Users//****";
    //指定文件
    ExcelWriter excelWriter = EasyExcel.write(fileName).build();
    // 去调用写入,实际使用时根据数据库分页的总的页数来。这里最终会写到5个sheet里面
    for (int i = 0; i < 5; i++) {
        // 每次都要创建writeSheet 这里注意必须指定sheetNo 而且sheetName必须不一样。这里注意DemoData.class 可以每次都变,我这里为了方便 所以用的同一个class 实际上可以一直变
        writeSheet = EasyExcel.writerSheet(i, "模板" + i).head(DemoData.class).build();
        // 分页去数据库查询数据 这里可以去数据库查询每一页的数据
        List<DemoData> data = data();
        excelWriter.write(data, writeSheet);
    }
    /// 千万别忘记finish 会帮忙关闭流
    excelWriter.finish();
    

    日期、数字或者自定义格式转换

    修改实体类注解即可

    日期、数字

        @DateTimeFormat("yyyy年MM月dd日HH时mm分ss秒")
        @ExcelProperty("日期标题")
        private Date  dateData;
        @NumberFormat("#.##%")
        @ExcelProperty("浮点型标题")
        private Double   dounleData;
    

    自定义格式转换

    @ExcelProperty(converter = CustomStringStringConverter.class)
    private String stringData;
    
    public class CustomStringStringConverter  implements Converter<String> {
        @Override
        public Class supportJavaTypeKey() {
            return String.class;
        }
    
        @Override
        public CellDataTypeEnum supportExcelTypeKey() {
            return CellDataTypeEnum.STRING;
        }
        /**
         * 这里读的时候会调用
         */
        @Override
        public String convertToJavaData(CellData cellData, ExcelContentProperty excelContentProperty, GlobalConfiguration globalConfiguration) throws Exception {
            return "自定义:" + cellData.getStringValue();
        }
    
        /**
         * 这里是写的时候会调用
         */
        @Override
        public CellData convertToExcelData(String value, ExcelContentProperty excelContentProperty, GlobalConfiguration globalConfiguration) throws Exception {
            return new CellData(value);
        }
    }
    

    指定列宽、行高

    @Data
    @ContentRowHeight(10)
    @HeadRowHeight(20)
    @ColumnWidth(25)
    public class DemoData {
        @ColumnWidth(50)
        @ExcelProperty("字符串标题")
        //@ExcelProperty(converter = CustomStringStringConverter.class)
        private String stringData;
        @ExcelProperty(value = "数字标题")
        private Integer  integerData;
        @DateTimeFormat("yyyy年MM月dd日HH时mm分ss秒")
        @ExcelProperty("日期标题")
        private Date  dateData;
        @NumberFormat("#.##%")
        @ExcelProperty("浮点型标题")
        private Double   dounleData;
    }
    

    注解形式自定义样式

    @Data
    // 头背景设置成红色 IndexedColors.RED.getIndex()
    @HeadStyle(fillPatternType = FillPatternType.SOLID_FOREGROUND, fillForegroundColor = 10)
    // 头字体设置成20
    @HeadFontStyle(fontHeightInPoints = 20)
    // 内容的背景设置成绿色 IndexedColors.GREEN.getIndex()
    @ContentStyle(fillPatternType = FillPatternType.SOLID_FOREGROUND, fillForegroundColor = 17)
    // 内容字体设置成20
    @ContentFontStyle(fontHeightInPoints = 20)
    public class DemoData {
        @ColumnWidth(50)
        @ExcelProperty("字符串标题")
        // 字符串的头背景设置成粉红 IndexedColors.PINK.getIndex()
        @HeadStyle(fillPatternType = FillPatternType.SOLID_FOREGROUND, fillForegroundColor = 14)
        private String stringData;
        // 字符串的头字体设置成20
        @HeadFontStyle(fontHeightInPoints = 30)
        @ExcelProperty(value = "数字标题")
        private Integer  integerData;
        // 字符串的内容的背景设置成天蓝 IndexedColors.SKY_BLUE.getIndex()
        @ContentStyle(fillPatternType = FillPatternType.SOLID_FOREGROUND, fillForegroundColor = 40)
        @DateTimeFormat("yyyy年MM月dd日HH时mm分ss秒")
        @ExcelProperty("日期标题")
        private Date  dateData;
        // 字符串的内容字体设置成20
        @ContentFontStyle(fontHeightInPoints = 30)
        @NumberFormat("#.##%")
        @ExcelProperty("浮点型标题")
        private Double   dounleData;
    }
    

    自定义样式

            String fileName = "c://Users//****";
            // 这里 需要指定写用哪个class去写,然后写到第一个sheet,名字为模板 然后文件流会自动关闭
            // 头的策略
            WriteCellStyle headWriteCellStyle = new WriteCellStyle();
            // 背景设置为红色
            headWriteCellStyle.setFillForegroundColor(IndexedColors.RED.getIndex());
            WriteFont headWriteFont = new WriteFont();
            headWriteFont.setFontHeightInPoints((short)20);
            headWriteCellStyle.setWriteFont(headWriteFont);
            // 内容的策略
            WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
            // 这里需要指定 FillPatternType 为FillPatternType.SOLID_FOREGROUND 不然无法显示背景颜色.头默认了 FillPatternType所以可以不指定
            contentWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);
            // 背景绿色
            contentWriteCellStyle.setFillForegroundColor(IndexedColors.GREEN.getIndex());
            WriteFont contentWriteFont = new WriteFont();
            // 字体大小
            contentWriteFont.setFontHeightInPoints((short)20);
            contentWriteCellStyle.setWriteFont(contentWriteFont);
            // 这个策略是 头是头的样式 内容是内容的样式 其他的策略可以自己实现
            HorizontalCellStyleStrategy horizontalCellStyleStrategy =
                    new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);
    
            // 这里 需要指定写用哪个class去写,然后写到第一个sheet,名字为模板 然后文件流会自动关闭
            EasyExcel.write(fileName, DemoData.class).registerWriteHandler(horizontalCellStyleStrategy).sheet("模板")
                    .doWrite(data());
    

    合并单元格

    @Data
    // 将第6-7行的2-3列合并成一个单元格
    //@OnceAbsoluteMerge(firstRowIndex = 5, lastRowIndex = 6, firstColumnIndex = 1, lastColumnIndex = 2)
    public class DemoData {
        // 这一列 每隔2行 合并单元格
        @ContentLoopMerge(eachRow = 2)
        @ExcelProperty("字符串标题")
        private String stringData;
        @ExcelProperty(value = "数字标题")
        private Integer  integerData;
        @DateTimeFormat("yyyy年MM月dd日HH时mm分ss秒")
        @ExcelProperty("日期标题")
        private Date  dateData;
        @NumberFormat("#.##%")
        @ExcelProperty("浮点型标题")
        private Double   dounleData;
    }
    

    自动列宽(不太精确)

            EasyExcel.write(fileName, DemoData.class).registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()).sheet("模板")
                    .doWrite(data());
    

    不创建对象的写

    
    
        String fileName = "c://Users//****";
        EasyExcel.write(fileName).head(head()).sheet("模板").doWrite(dataList());
        
        -------------------------------------------------------------------------
        
        
        private List<List<String>> head() {
            List<List<String>> list = new ArrayList<List<String>>();
            List<String> head0 = new ArrayList<String>();
            head0.add("字符串" + System.currentTimeMillis());
            List<String> head1 = new ArrayList<String>();
            head1.add("数字" + System.currentTimeMillis());
            List<String> head2 = new ArrayList<String>();
            head2.add("日期" + System.currentTimeMillis());
            list.add(head0);
            list.add(head1);
            list.add(head2);
            return list;
        }
        
        
        private List<List<Object>> dataList() {
            List<List<Object>> list = new ArrayList<List<Object>>();
            for (int i = 0; i < 10; i++) {
                List<Object> data = new ArrayList<Object>();
                data.add("字符串" + i);
                data.add(new Date());
                data.add(0.56);
                list.add(data);
            }
            return list;
        }
        
    

    web的写(文件下载)

        /**
         * 文件下载(失败了会返回一个有部分数据的Excel)
         */
        @GetMapping("download")
        public void download(HttpServletResponse response) throws IOException {
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf-8");
            // 这里URLEncoder.encode可以防止中文乱码 easyexcel没有关系
            String fileName = URLEncoder.encode("测试", "UTF-8");
            response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
            EasyExcel.write(response.getOutputStream(), DownloadData.class).sheet("模板").doWrite(data());
        }
    

    web中的写并且失败的时候返回json

        @GetMapping("downloadFailedUsingJson")
        public void downloadFailedUsingJson(HttpServletResponse response) throws IOException {
            try {
                response.setContentType("application/vnd.ms-excel");
                response.setCharacterEncoding("utf-8");
                // 这里URLEncoder.encode可以防止中文乱码 和easyexcel没有关系
                String fileName = URLEncoder.encode("测试", "UTF-8");
                response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
                // 这里需要设置不关闭流
                EasyExcel.write(response.getOutputStream(), DownloadData.class).autoCloseStream(Boolean.FALSE).sheet("模板")
                    .doWrite(data());
            } catch (Exception e) {
                // 重置response
                response.reset();
                response.setContentType("application/json");
                response.setCharacterEncoding("utf-8");
                Map<String, String> map = new HashMap<String, String>();
                map.put("status", "failure");
                map.put("message", "下载文件失败" + e.getMessage());
                response.getWriter().println(JSON.toJSONString(map));
            }
        }
        
        
         private List<DownloadData> data() {
            List<DownloadData> list = new ArrayList<DownloadData>();
            for (int i = 0; i < 10; i++) {
                DownloadData data = new DownloadData();
                data.setStringData("字符串" + i);
                data.setIntegerData(i);
                data.setDateData(new Date());
                data.setDounleData(0.56);
                list.add(data);
            }
            return list;
        }
    
  • 相关阅读:
    架构漫谈读后感
    阅读笔记六
    阅读笔记五
    阅读笔记四
    阅读笔记三
    第二次冲刺周期第二天
    第二次冲刺周期第一天
    一轮项目冲刺——移山小分队(10)
    一轮项目冲刺——移山小分队(9)
    一轮项目冲刺——移山小分队(8)
  • 原文地址:https://www.cnblogs.com/luckyhui28/p/12693098.html
Copyright © 2011-2022 走看看