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;
    }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM