在做後臺管理系統的時候,很多場景都會遇到Execl的導入和導出,如果在以前的話,我們基本都是用POI這個組件,不得不說,這個組件的功能確實強大,但是也有有一些弊端,比如內存佔用高、文件過大會導致OOM。後來,阿里開源的EasyExecl就能很好解決這些問題。
在開始之前,我們需要對EasyEexcl有個初步的了解,這裡,我只有去Github或者是語雀查看相關的資料。
這裡,我們先引入EasyExecl所以的組件
com.alibabagroupId> easyexcelartifactId> 2.2.7version>dependency>
EasyExecl常用註解
EasyExecl提供了很多註解,使得我們在導出Execl的時候更加的方便
ExcelProperty
指定當前欄位對應excel中的哪一列。可以根據名字或者Index去匹配。當然也可以不寫,默認第一個欄位就是index=0,以此類推。千萬注意,要麼全部不寫,要麼全部用index,要麼全部用名字去匹配。千萬別三個混著用,除非你非常了解原始碼中三個混著用怎麼去排序的。
@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)@Inheritedpublic @interface ExcelProperty { String[] value() default {""}; int index() default -1; #指定當前欄位對應excel中的那一列 int order() default Integer.MAX_VALUE; #用於排序 Class converter() default AutoConverter.class; @Deprecated String format() default "";}
ExcelIgnore
默認所有欄位都會和excel去匹配,加了這個註解會忽略該欄位
DateTimeFormat
日期轉換,用String去接收excel日期格式的數據會調用這個註解。裡面的value參照java.text.SimpleDateFormat
@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)@Inheritedpublic @interface DateTimeFormat { String value() default ""; boolean use1904windowing() default false;}
NumberFormat
數字轉換,用String去接收excel數字格式的數據會調用這個註解。裡面的value參照java.text.DecimalFormat
@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)@Inheritedpublic @interface NumberFormat { String value() default ""; RoundingMode roundingMode() default RoundingMode.HALF_UP;}
@ExcelIgnore
這個註解的作用就是我們導出 Excel 的時候有些屬性可以忽略,那麼我們就在屬性上面加上此註解即可。
@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)@Inheritedpublic @interface ExcelIgnore {}
ExcelIgnoreUnannotated
這個註解的作用是忽略未註解的,我們如果一個實體類有太多想忽略的欄位的話可以在實體類上加上該註解,這樣就不用每個屬性上去每個添加 @ExcelIgnore 註解了。
@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Inheritedpublic @interface ExcelIgnoreUnannotated {}
ColumnWidth
表格列寬度
@Target({ElementType.FIELD, ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Inheritedpublic @interface ColumnWidth { int value() default -1; # 表格寬度,默認-1}
ContentRowHeight
表格行高
@Target({ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Inheritedpublic @interface ContentRowHeight { short value() default -1;}
HeadRowHeight
表頭行高
@Target({ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Inheritedpublic @interface HeadRowHeight { short value() default -1;}
ContentLoopMerge
合併單元格。
@Target({ElementType.FIELD})@Retention(RetentionPolicy.RUNTIME)@Inheritedpublic @interface ContentLoopMerge { int eachRow() default -1; int columnExtend() default 1;}
除了上面這些註解,還有一些關於表格樣式的註解,如HeadStyle、HeadFontStyle、ContentFontStyle等。下面,我就用註解來實現我們的Execl導出,首先需要一個類
@Getter@Setter@ContentRowHeight(15)public class PercentageExeclExportVo { @ColumnWidth(20) @ExcelProperty(value = "工號",index = 0) private String jobCode; @ExcelProperty(value = "姓名",index = 1) private String name; @ExcelProperty(value = "月份",index = 2) private String month; @ExcelProperty(value = "收入",index = 3) @NumberFormat(value ="#.##" ,roundingMode= RoundingMode.HALF_UP) private BigDecimal income;}
然後取出對應的數據,直接調用EasyExecl提供的API接口下載
@ApiOperation(value = "導出數據") @PostMapping(value = "/execl-export") public void execlExport(@RequestBody PercentageCalcResultInVo inVo, HttpServletResponse response) throws DefaultException { try { response.setContentType("application/vnd.ms-excel"); response.setCharacterEncoding("utf-8"); // 這裡URLEncoder.encode可以防止中文亂碼 當然和easyexcel沒有關係 String fileName = URLEncoder.encode("人員提成收入", "UTF-8").replaceAll("\\+", "%20"); response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx"); // 這裡需要設置不關閉流 EasyExcel.write(response.getOutputStream(), PercentageExeclExportVo.class).sheet("提成") .doWrite(percentageService.queryPercentageData(inVo)); } catch (Exception e) { throw new DefaultException(e.getMessage()); } }
這裡只是做一個簡單的示例,在語雀也有更多示例,朋友們就自己去借鑑一番。這裡我只提一點,由於我們基於kubesphere將應用部署到Docker中會報錯
Error: java.lang.reflect.InvocationTargetException com.alibaba.excel.exception.ExcelGenerateException: java.lang.InternalError: java.lang.reflect.InvocationTargetExceptionjava.lang.NullPointerException: null at java.desktop/sun.awt.FontConfiguration.getVersion(FontConfiguration.java:1262)
我們最開始是Dockerfile是這樣的
FROM java:openjdk-8-jre-alpineWORKDIR /homeCOPY *.jar /homeENV JAVA_OPTS="-server -Xmx2g -Xms2g"ENTRYPOINT java -jar *.jar ${JAVA_OPTS}
其實主要是因為openjdk的鏡像中缺少字體包。所以,要解決這個問題,要麼就是在docker加入字體,要麼就更換鏡像。我這邊是用的後者,將Dockerfile改為
FROM java:8WORKDIR /homeCOPY *.jar /homeENV JAVA_OPTS="-server -Xmx2g -Xms2g"ENTRYPOINT java -jar *.jar ${JAVA_OPTS}
特別聲明:以上內容(如有圖片或視頻亦包括在內)為自媒體平臺「網易號」用戶上傳並發布,本平臺僅提供信息存儲服務。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.