自定義注解:
package com.resuper.yhexcel.util; import java.lang.annotation.*; @Documented @Inherited @Target({ ElementType.FIELD, ElementType.METHOD }) @Retention(RetentionPolicy.RUNTIME) public @interface ExcelI18N { String i18nkey(); }
配置文件:excel.properties
#row即表頭行(起始值/最小值為1); excel.zgnyyh.row=3 excel.zgnyyh.jysj=會計日期 excel.zgnyyh.jffse=支出金額 excel.zgnyyh.dffse=收入金額 excel.zgnyyh.jyhye=賬戶余額 excel.zgnyyh.fkzh=對方賬號 excel.zgnyyh.fkzhm=對方戶名 excel.zgnyyh.zysm=交易用途
excel對應的實體:
package com.resuper.yhexcel.excelData; import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.excel.annotation.format.DateTimeFormat; import com.resuper.yhexcel.converter.ZggsyhConverter; import com.resuper.yhexcel.converter.ZgnyyhConverter; import com.resuper.yhexcel.util.ExcelI18N; import lombok.Data; import java.lang.reflect.Field; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; import java.math.BigDecimal; import java.util.Date; import java.util.Map; import java.util.PropertyResourceBundle; @Data public class Data { /* // 強制讀取第三個 這里不建議 index 和 name 同時用,要么一個對象只用index,要么一個對象只用name去匹配 @ExcelProperty(index = 2) private Double doubleData; // 用名字去匹配,這里需要注意,如果名字重復,會導致只有一個字段讀取到數據 @ExcelProperty("字符串標題") private String string; @ExcelProperty("日期標題") private Date date; */ /** * 交易時間 */ // @ExcelProperty(value = "交易時間" , converter = ZgnyyhConverter.class) // @DateTimeFormat("yyyyMMdd HH:mm:ss") // private Date jysj; @ExcelI18N(i18nkey = "會計日期") @ExcelProperty(value = "會計日期") private String jysj; /** * 收入支出標志(1 收入,2 支出) */ // private String srzcbz; /** * 金額 */ // @ExcelProperty("支出金額") // private BigDecimal je; @ExcelI18N(i18nkey = "支出金額") @ExcelProperty(value = "支出金額") // @ExcelProperty("借方發生額(支取)") private String jffse; // private BigDecimal jffse; @ExcelI18N(i18nkey = "收入金額") @ExcelProperty(value = "收入金額") // @ExcelProperty("貸方發生額(收入)") private String dffse; // private BigDecimal dffse; /** * 交易后余額 */ @ExcelI18N(i18nkey = "賬戶余額") @ExcelProperty(value = "賬戶余額") private String jyhye; // private BigDecimal jyhye; /** * 付款賬號 */ @ExcelI18N(i18nkey = "對方賬號") @ExcelProperty(value = "對方賬號") private String fkzh; /** * 付款賬號名 */ @ExcelI18N(i18nkey = "對方戶名") @ExcelProperty(value = "對方戶名") private String fkzhm; /** * 摘要說明 */ @ExcelI18N(i18nkey = "交易用途") @ExcelProperty(value = "交易用途") private String zysm; /** * 用途=摘要說明 */ // @ExcelProperty(value = "交易用途") // private String yt; public synchronized void changeExcelHead() throws NoSuchFieldException, IllegalAccessException { Field[] fields = ZgnyyhData.class.getDeclaredFields(); for (int j = 0; j < fields.length; j++) { Field field = fields[j]; if (field.isAnnotationPresent(ExcelI18N.class) && field.isAnnotationPresent(ExcelProperty.class)) { //獲取NcxysData字段上的ExcelProperty注解實例 ExcelI18N i18n = field.getAnnotation(ExcelI18N.class); ExcelProperty excel = field.getAnnotation(ExcelProperty.class); //獲取 ExcelProperty 這個代理實例所持有的 InvocationHandler InvocationHandler i18nH = Proxy.getInvocationHandler(i18n); InvocationHandler excelH = Proxy.getInvocationHandler(excel); // 獲取 AnnotationInvocationHandler 的 memberValues 字段 Field i18nF = i18nH.getClass().getDeclaredField("memberValues"); Field excelF = excelH.getClass().getDeclaredField("memberValues"); // 因為這個字段事 private final 修飾,所以要打開權限 i18nF.setAccessible(true); excelF.setAccessible(true); // 獲取 memberValues Map i18nValues = (Map) i18nF.get(i18nH); Map excelValues = (Map) excelF.get(excelH); // 修改 value 屬性值 Object i18nO = i18nValues.get("i18nkey"); Object excelOS = excelValues.get("value"); if (i18nO != null && excelOS != null) { String HEAD = (String) i18nO;//這里取到的就是@ExcelProperty的value值 PropertyResourceBundle res = (PropertyResourceBundle) PropertyResourceBundle.getBundle("excel"); // properties 文件名 switch (HEAD) { case "會計日期": excelValues.put("value", new String[]{res.getString("excel.zgnyyh.jysj")}); break; case "支出金額": excelValues.put("value", new String[]{res.getString("excel.zgnyyh.jffse")}); break; case "收入金額": excelValues.put("value", new String[]{res.getString("excel.zgnyyh.dffse")}); break; case "賬戶余額": excelValues.put("value", new String[]{res.getString("excel.zgnyyh.jyhye")}); break; case "對方賬號": excelValues.put("value", new String[]{res.getString("excel.zgnyyh.fkzh")}); break; case "對方戶名": excelValues.put("value", new String[]{res.getString("excel.zgnyyh.fkzhm")}); break; case "交易用途": excelValues.put("value", new String[]{res.getString("excel.zgnyyh.zysm")}); break; } } } } } }
只需要在EasyExcelFactory.read之前調用changeExcelHead()方法即可從配置文件讀取excel表頭:
private ResponseEntity readExcelData(MultipartFile file) { try { DataListener2<ZwWyjymx> listener = new DataListener2<ZwWyjymx>(); byte [] byteArr=file.getBytes(); PropertyResourceBundle res = (PropertyResourceBundle)PropertyResourceBundle.getBundle("excel"); Integer row = Integer.valueOf(res.getString("excel.zgnyyh.row")); new Data().changeExcelHead(); InputStream inputStream = new ByteArrayInputStream(byteArr);//MultipartFile轉為InputStream // ExcelReader excelReader = EasyExcelFactory.read(inputStream, null, listener).headRowNumber(5).build(); ExcelReader excelReader = EasyExcelFactory.read(inputStream, Data.class, listener).headRowNumber(row).build(); excelReader.readAll(); List<ZwWyjymx> listMap = listener.getDatas();//取excel解析后的數據 excelReader.finish(); return ResponseEntity.ok(new Result(ResponseConstant.SUCCESS_CODE, ResponseConstant.PARSE_SUCCESS_MSG, listMap)); } catch (IOException e) { e.printStackTrace(); return ResponseEntity.ok(new Result(ResponseConstant.ERROR_CODE, ResponseConstant.SERVER_ERROR_MSG, null)); //讀取文件出錯的處理邏輯 } catch (NoSuchFieldException e) { e.printStackTrace(); return ResponseEntity.ok(new Result(ResponseConstant.ERROR_CODE, "配置表頭讀取失敗", null)); } catch (IllegalAccessException e) { e.printStackTrace(); return ResponseEntity.ok(new Result(ResponseConstant.ERROR_CODE, "配置表頭讀取失敗", null)); } }
注意:上面的配置文件雖然在idea中設置了.properties的文件格式utf-8,但當鼠標點擊文件內容后在idea中其格式依然為ISO-8859-1,所以
(PropertyResourceBundle) PropertyResourceBundle.getBundle("excel").getString("excel.zgnyyh.jysj")就能取到配置文件的中文;
但當鼠標點擊文件內容后發現格式已經為utf-8了,就要做如下變動
(PropertyResourceBundle) PropertyResourceBundle.getBundle("excel").getString("exce.zggsyh.jysj").getBytes("ISO-8859-1"),"UTF-8")取到的中文才不會亂碼。
idea中設置文件編碼格式和查看具體文件編碼如下:

上面的方式讀取的配置文件是在打包是會打在jar包里
*************************************************************************************************************************************************************
下面的方式讀取的配置文件只需要(未打包時:放在項目根目錄下面;打jar包時:放在jar包同級目錄下)
放在jar包同級目錄下的配置文件讀取方式:
//2022年2月21日
Properties properties = new Properties();
//優先使用外部配置文件 路徑為 jar包所在目錄System.getProperty("user.dir")即讀取到jar包同級目錄或者未打包前的項目根目錄
String path = System.getProperty("user.dir")+"/"+"excel.properties";
File file = new File(path);
FileInputStream fis = null;
try {
fis = new FileInputStream(file);
properties.load(fis);
fis.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
//讀取配置文件中具體參數
Integer row = Integer.valueOf(new String(properties.getProperty("excel0506.zggsyh.row").getBytes("ISO-8859-1"),"UTF-8"));