欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java中EasyExcel使用自定義Converter處理方法詳解

 更新時(shí)間:2024年08月23日 10:25:16   作者:transitory_truth  
EasyExcel自定義Converter是指在使用EasyExcel進(jìn)行Excel讀寫操作時(shí),可以自定義轉(zhuǎn)換器來處理一些不支持的數(shù)據(jù)類型,這篇文章主要給大家介紹了關(guān)于Java中EasyExcel使用自定義Converter處理的相關(guān)資料,需要的朋友可以參考下

需求背景

類型處理報(bào)錯(cuò)

系統(tǒng)使用EasyExcel作為導(dǎo)入導(dǎo)出,有些類型操作會(huì)報(bào)轉(zhuǎn)換異常:

com.alibaba.excel.exception.ExcelWriteDataConvertException: Can not find 'Converter' support class XXX.

這個(gè)問題的原因是因?yàn)檎也坏街付ǖ腸onverter去處理當(dāng)前類型,默認(rèn)的各種Converter去com.alibaba.excel.converters包下查看,或者直接查看Converter的各個(gè)實(shí)現(xiàn)類。作者主要是需要實(shí)現(xiàn)LocalDate的導(dǎo)出,其他類型同理。

枚舉字段轉(zhuǎn)換

還有一個(gè)場(chǎng)景是,如果這個(gè)字段的值本身是固定的枚舉code,但是導(dǎo)出時(shí)要導(dǎo)出成文字。也可以使用。

其他說明

作者當(dāng)前使用的easyExcel的版本為3.0.5。某些版本內(nèi)置類名稱不太一致,Api有些調(diào)整,不過都大同小異。

查看官方文檔時(shí)發(fā)現(xiàn)其對(duì)自定義Converter的描述不太完整,特此記錄

代碼編寫

重寫converter

  • 首先要重寫converter來完成數(shù)據(jù)的數(shù)據(jù)準(zhǔn)換
public class SpecClassConverter implements Converter<SpecClass> {}
// 以下為實(shí)現(xiàn)方法
Class<?> supportJavaTypeKey();
// 支持?jǐn)?shù)據(jù)轉(zhuǎn)換的java類型, 例如: return LocalDate.class/Integer.class/Boolean.class/customClass.class;
CellDataTypeEnum supportExcelTypeKey();
// 支持?jǐn)?shù)據(jù)轉(zhuǎn)換的單元格類型, 例如: return CellDataTypeEnum.STRING;
T convertToJavaData(ReadCellData<?> cellData, ExcelContentProperty contentProperty,GlobalConfiguration globalConfiguration);
// 將單元格內(nèi)容轉(zhuǎn)換成java對(duì)象;導(dǎo)入時(shí)使用 例如: return LocalDate.parse(cellData.getStringValue(), DateTimeFormatter.ofPattern("yyyy-MM-dd"));/return cellData.getStringValue().equals("是") ? 1 : 0; 注意自己處理空指針/空數(shù)據(jù)問題
T convertToJavaData(ReadConverterContext<?> context);
//  return convertToJavaData(context.getReadCellData(), context.getContentProperty(),context.getAnalysisContext().currentReadHolder().globalConfiguration());
// 估計(jì)是舊版本Api,默認(rèn)實(shí)現(xiàn)調(diào)用上面方法,所以只重寫上面方法就可以了 
WriteCellData<?> convertToExcelData(T value, ExcelContentProperty contentProperty,GlobalConfiguration globalConfiguration);
// 將java對(duì)象導(dǎo)出為指定單元格內(nèi)容 例如: return new WriteCellData<>((LocalDate)value.format(DateUtil.formatter1));/return new WriteCellData<>((Integer)value == 1 ? "是" : "否"); 更多單元格樣式設(shè)置請(qǐng)參照官方文檔
WriteCellData<?> convertToExcelData(WriteConverterContext<T> context);
//  return convertToExcelData(context.getValue(), context.getContentProperty(),context.getWriteContext().currentWriteHolder().globalConfiguration());
// 估計(jì)是舊版本Api,默認(rèn)實(shí)現(xiàn)調(diào)用上面方法,所以只重寫上面方法就可以了 

使用converter

  • 上述代碼只是創(chuàng)建了一個(gè)自定義的Converter,如果要使用這個(gè)Converter需要指定使用,有兩種使用方法:
    • 加在指定字段上,指定該字段使用該Converter,注意類型不要搞錯(cuò),如果該實(shí)體內(nèi)有該類型字段需要指定多次
        @JsonFormat(pattern = "yyyy-MM-dd")
    	@ExcelProperty(value = "開始時(shí)間",converter = SpecClassConverter .class)
    	private LocalDate startTime;
    	
        @JsonFormat(pattern = "yyyy-MM-dd")
    	@ExcelProperty(value = "結(jié)束時(shí)間",converter = SpecClassConverter .class)
    	private LocalDate endTime;
    
    • 也可以在寫入Excel時(shí)將該Converter注冊(cè)到ExcelWriterBuilder中,該實(shí)體內(nèi)所有支持類型都會(huì)被SpecConverter轉(zhuǎn)換。
    EasyExcel.write(out, SpecClass.class).registerConverter(new SpecClassConverter());
    // 只是簡(jiǎn)單的完成數(shù)據(jù)轉(zhuǎn)換,如果需要記錄日志等功能,可以將converter托管給spring成為一個(gè)bean再引入使用,converter作為默認(rèn)bean時(shí)注意單例的多線程問題
    
  • 注意:如果字段上指定了converter,ExcelWriterBuilder中也注冊(cè)了Converter且類型支持,字段上的converter優(yōu)先級(jí)最高,ExcelWriterBuilder中的converter在該字段不執(zhí)行

進(jìn)階使用

在數(shù)據(jù)轉(zhuǎn)換時(shí)可以對(duì)單元格格式做操作,比如設(shè)置不同的單元格顏色、設(shè)置不同的字體、設(shè)置不同的字號(hào)

對(duì)于舊實(shí)體的處理 (例如: 數(shù)字脫敏)

實(shí)體類內(nèi)字段指定使用Converter

// 代碼很簡(jiǎn)單,重寫converter的時(shí)候指定處理規(guī)則,然后將要脫敏的字段指定使用該Converter
@Override
    public WriteCellData<String> convertToExcelData(String value, ExcelContentProperty contentProperty,
                                               GlobalConfiguration globalConfiguration) throws IOException {
                String s = value.replaceAll("[0123456789]", "*");
        WriteCellData<String> res = new WriteCellData<>(s);
        return res;
    }

舊有實(shí)體類改造,實(shí)體類太多,原字段沒有指定converter,固定了要處理的字段名或者指定了 @ExcelProperty 內(nèi)的value

// 代碼思路是在類上注冊(cè)這個(gè)轉(zhuǎn)換器,因?yàn)槲覀冇袀€(gè)系統(tǒng)是提數(shù)系統(tǒng),所有的導(dǎo)出最后統(tǒng)一由一個(gè)ExcelWriterBuilder處理,所以這個(gè)方式很省力
@Override
    public WriteCellData<String> convertToExcelData(String value, ExcelContentProperty contentProperty,
                                               GlobalConfiguration globalConfiguration) throws IOException {
        WriteCellData<String> res;
        Field field = contentProperty.getField();
        // 固定字段值 為了判斷當(dāng)前字段是否處理,獲取當(dāng)前字段的名稱,進(jìn)行判斷
      	if(field.getName().equals("handler")){
            String s = value.replaceAll("[0123456789]", "*");
            res = new WriteCellData<>(s);
        }else{
            res = new WriteCellData<>(value);
        }
		// 字段值不固定,指定了 @ExcelProperty 注解中的value,固定導(dǎo)出列頭,利用反射拿到注解
		ExcelProperty annotation = contentProperty.getField().getAnnotation(ExcelProperty.class);
        String resValue = value;
        if (annotation != null) {
            String[] value1 = annotation.value();
            String name = value1[value1.length-1];
            if(name.contains("handler")){
                resValue = value.replaceAll("[0123456789]", "*");
            }
        }
        WriteCellData<String> res = new WriteCellData<>(resValue);
		
        
        return res;
    }

舊有實(shí)體類改造,沒使用 @ExcelProperty 注解,header是List<List<String>>格式,不確定字段名稱,只確定導(dǎo)出header

思路是獲取到設(shè)置的head列表,根據(jù)當(dāng)前列的索引值獲取當(dāng)前header,判斷是否處理,在converter中無法獲取當(dāng)前columnIndex,所以放到了CellWriteHandler中。

// 查看registerWriteHandler方法,發(fā)現(xiàn)這個(gè)WriteHandler 的調(diào)用更像是一個(gè)鏈路,所以不用擔(dān)心覆蓋,可以注冊(cè)多個(gè)CustomWriteHandler 
   public T registerWriteHandler(WriteHandler writeHandler) {
        if (parameter().getCustomWriteHandlerList() == null) {
            parameter().setCustomWriteHandlerList(new ArrayList<WriteHandler>());
        }
        parameter().getCustomWriteHandlerList().add(writeHandler);
        return self();
    }


public class CustomWriterHandler implements CellWriteHandler {
// 重寫afterCellDataConverted方法,在數(shù)據(jù)轉(zhuǎn)換處理后對(duì)單元格做操作
    @Override
    public void afterCellDataConverted(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder,WriteCellData<?> cellData, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
    
        if(!isHead){
            int columnIndex = cell.getColumnIndex();
            List<String> strings = writeSheetHolder.getHead().get(columnIndex);
            String s = strings.get(strings.size() - 1);
            if(s.equals("handler")){
                    String stringValue = cellData.getStringValue();
                    String res = stringValue.replaceAll("[0123456789]", "*");
                    cellData.setStringValue(res);
            }
            
            // 下面這種寫法如果碰到自定義Head會(huì)空指針,而且這種對(duì)數(shù)據(jù)的處理可以的話盡量放到Converter更好
            
            // if(head.getFieldName().equals("handler")){
            //     String stringValue = cellData.getStringValue();
            //     String s = stringValue.replaceAll("[0123456789]", "*");
            //     cellData.setStringValue(s);
            // }
        }
    }
}

總結(jié) 

到此這篇關(guān)于Java中EasyExcel使用自定義Converter處理方法的文章就介紹到這了,更多相關(guān)EasyExcel自定義Converter內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Spring Boot應(yīng)用事件監(jiān)聽示例詳解

    Spring Boot應(yīng)用事件監(jiān)聽示例詳解

    這篇文章主要給大家介紹了關(guān)于Spring Boot應(yīng)用事件監(jiān)聽的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-12-12
  • 解決mybatis一對(duì)多查詢r(jià)esultMap只返回了一條記錄問題

    解決mybatis一對(duì)多查詢r(jià)esultMap只返回了一條記錄問題

    小編接到領(lǐng)導(dǎo)一個(gè)任務(wù)需求,需要用到使用resultMap相關(guān)知識(shí),在這小編記錄下這個(gè)問題的解決方法,對(duì)mybatis一對(duì)多查詢r(jià)esultMap項(xiàng)目知識(shí)感興趣的朋友一起看看吧
    2021-11-11
  • java如何利用poi解析doc和docx中的數(shù)據(jù)

    java如何利用poi解析doc和docx中的數(shù)據(jù)

    這篇文章主要給大家介紹了關(guān)于java如何利用poi解析doc和docx中數(shù)據(jù)的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04
  • SpringBoot項(xiàng)目改為SpringCloud項(xiàng)目使用nacos作為注冊(cè)中心的方法

    SpringBoot項(xiàng)目改為SpringCloud項(xiàng)目使用nacos作為注冊(cè)中心的方法

    本文主要介紹了SpringBoot項(xiàng)目改為SpringCloud項(xiàng)目使用nacos作為注冊(cè)中心,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-04-04
  • SpringBoot使用Apache?Tika檢測(cè)敏感信息

    SpringBoot使用Apache?Tika檢測(cè)敏感信息

    Apache?Tika?是一個(gè)功能強(qiáng)大的內(nèi)容分析工具,它能夠從多種文件格式中提取文本、元數(shù)據(jù)以及其他結(jié)構(gòu)化信息,下面我們來看看如何使用Apache?Tika檢測(cè)敏感信息從而實(shí)現(xiàn)數(shù)據(jù)泄露防護(hù)吧
    2025-01-01
  • 最新評(píng)論