通過反射,實現修改easyExcel的@ExcelProperty注解的value值從而實現從配置文件讀取@ExcelProperty的value


自定義注解:

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"));

 

 
 
       


免責聲明!

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



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