最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

需求背景

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

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

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

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

枚舉字段轉(zhuǎn)換

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

其他說(shuō)明

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

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

代碼編寫(xiě)

重寫(xiě)converter

  • 首先要重寫(xiě)converter來(lái)完成數(shù)據(jù)的數(shù)據(jù)準(zhǔn)換
public class SpecClassConverter implements Converter<SpecClass> {}
// 以下為實(shí)現(xiàn)方法
Class<?> supportJavaTypeKey();
// 支持?jǐn)?shù)據(jù)轉(zhuǎn)換的java類(lèi)型, 例如: return LocalDate.class/Integer.class/Boolean.class/customClass.class;
CellDataTypeEnum supportExcelTypeKey();
// 支持?jǐn)?shù)據(jù)轉(zhuǎn)換的單元格類(lèi)型, 例如: 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ù)問(wèn)題
T convertToJavaData(ReadConverterContext<?> context);
//  return convertToJavaData(context.getReadCellData(), context.getContentProperty(),context.getAnalysisContext().currentReadHolder().globalConfiguration());
// 估計(jì)是舊版本Api,默認(rèn)實(shí)現(xiàn)調(diào)用上面方法,所以只重寫(xiě)上面方法就可以了 
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)用上面方法,所以只重寫(xiě)上面方法就可以了 

使用converter

  • 上述代碼只是創(chuàng)建了一個(gè)自定義的Converter,如果要使用這個(gè)Converter需要指定使用,有兩種使用方法:
    • 加在指定字段上,指定該字段使用該Converter,注意類(lèi)型不要搞錯(cuò),如果該實(shí)體內(nèi)有該類(lèi)型字段需要指定多次
        @JsonFormat(pattern = "yyyy-MM-dd")
    	@ExcelProperty(value = "開(kāi)始時(shí)間",converter = SpecClassConverter .class)
    	private LocalDate startTime;
    	
        @JsonFormat(pattern = "yyyy-MM-dd")
    	@ExcelProperty(value = "結(jié)束時(shí)間",converter = SpecClassConverter .class)
    	private LocalDate endTime;
    
    • 也可以在寫(xiě)入Excel時(shí)將該Converter注冊(cè)到ExcelWriterBuilder中,該實(shí)體內(nèi)所有支持類(lè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í)注意單例的多線(xiàn)程問(wèn)題
    
  • 注意:如果字段上指定了converter,ExcelWriterBuilder中也注冊(cè)了Converter且類(lèi)型支持,字段上的converter優(yōu)先級(jí)最高,ExcelWriterBuilder中的converter在該字段不執(zhí)行

進(jìn)階使用

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

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

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

// 代碼很簡(jiǎn)單,重寫(xiě)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í)體類(lèi)改造,實(shí)體類(lèi)太多,原字段沒(méi)有指定converter,固定了要處理的字段名或者指定了 @ExcelProperty 內(nèi)的value

// 代碼思路是在類(lèi)上注冊(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)前字段的名稱(chē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í)體類(lèi)改造,沒(méi)使用 @ExcelProperty 注解,header是List<List<String>>格式,不確定字段名稱(chēng),只確定導(dǎo)出header

思路是獲取到設(shè)置的head列表,根據(jù)當(dāng)前列的索引值獲取當(dāng)前header,判斷是否處理,在converter中無(wú)法獲取當(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 {
// 重寫(xiě)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);
            }
            
            // 下面這種寫(xiě)法如果碰到自定義Head會(huì)空指針,而且這種對(duì)數(shù)據(jù)的處理可以的話(huà)盡量放到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 Framework常用面試題及答案匯總

    Spring Framework常用面試題及答案匯總

    這篇文章主要介紹了Spring Framework常用面試題及答案匯總,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-06-06
  • Java實(shí)現(xiàn)單向鏈表的基本功能詳解

    Java實(shí)現(xiàn)單向鏈表的基本功能詳解

    這篇文章主要給大家介紹了關(guān)于Java實(shí)現(xiàn)單向鏈表基本功能的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。
    2018-03-03
  • C#使用MySQLConnectorNet和MySQLDriverCS操作MySQL的方法

    C#使用MySQLConnectorNet和MySQLDriverCS操作MySQL的方法

    這篇文章主要介紹了C#使用MySQLConnectorNet和MySQLDriverCS操作MySQL的方法,相比普通方法能夠在Windows下簡(jiǎn)化很多操作步驟,需要的朋友可以參考下
    2016-04-04
  • Java異?;A(chǔ)知識(shí)解析

    Java異?;A(chǔ)知識(shí)解析

    這篇文章主要介紹了Java異?;A(chǔ)知識(shí)解析,具有一定借鑒價(jià)值,需要的朋友可以資參考下。
    2017-12-12
  • SpringBoot配置文件高級(jí)用法實(shí)戰(zhàn)分享

    SpringBoot配置文件高級(jí)用法實(shí)戰(zhàn)分享

    Spring Boot配置文件的優(yōu)先級(jí)是一個(gè)重要的概念,它決定了當(dāng)存在多個(gè)配置文件時(shí),哪個(gè)配置文件中的配置將被優(yōu)先采用,本文給大家介紹了SpringBoot配置文件高級(jí)用法實(shí)戰(zhàn),文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-08-08
  • Java基礎(chǔ)之Comparable與Comparator概述

    Java基礎(chǔ)之Comparable與Comparator概述

    這篇文章主要介紹了Java基礎(chǔ)之Comparable與Comparator詳解,文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)java基礎(chǔ)的小伙伴們有非常好的幫助,需要的朋友可以參考下
    2021-04-04
  • Java之注解@Data和@ToString(callSuper=true)解讀

    Java之注解@Data和@ToString(callSuper=true)解讀

    在使用Lombok庫(kù)的@Data注解時(shí),若子類(lèi)未通過(guò)@ToString(callSuper=true)注明包含父類(lèi)屬性,toString()方法只打印子類(lèi)屬性,解決方法:1. 子類(lèi)重寫(xiě)toString方法;2. 子類(lèi)使用@Data和@ToString(callSuper=true),父類(lèi)也應(yīng)使用@Data
    2024-11-11
  • Java多線(xiàn)程并發(fā)開(kāi)發(fā)之DelayQueue使用示例

    Java多線(xiàn)程并發(fā)開(kāi)發(fā)之DelayQueue使用示例

    這篇文章主要為大家詳細(xì)介紹了Java多線(xiàn)程并發(fā)開(kāi)發(fā)之DelayQueue使用示例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-09-09
  • Spring Data JPA+kkpager實(shí)現(xiàn)分頁(yè)功能實(shí)例

    Spring Data JPA+kkpager實(shí)現(xiàn)分頁(yè)功能實(shí)例

    本篇文章主要介紹了Spring Data JPA+kkpager實(shí)現(xiàn)分頁(yè)功能實(shí)例,具有一定的參考價(jià)值,有興趣的可以了解一下
    2017-06-06
  • Java十分鐘精通異常處理機(jī)制

    Java十分鐘精通異常處理機(jī)制

    異常就是不正常,比如當(dāng)我們身體出現(xiàn)了異常我們會(huì)根據(jù)身體情況選擇喝開(kāi)水、吃藥、看病、等?異常處理方法。?java異常處理機(jī)制是我們java語(yǔ)言使用異常處理機(jī)制為程序提供了錯(cuò)誤處理的能力,程序出現(xiàn)的錯(cuò)誤,程序可以安全的退出,以保證程序正常的運(yùn)行等
    2022-03-03

最新評(píng)論

涿鹿县| 宁波市| 元谋县| 六枝特区| 红河县| 白玉县| 冷水江市| 北流市| 连南| 乌拉特后旗| 大城县| 航空| 新宁县| 阳原县| 博爱县| 屏山县| 礼泉县| 杭锦后旗| 新余市| 东兰县| 龙胜| 平利县| 海兴县| 新源县| 和龙市| 徐州市| 吉林省| 寿宁县| 陵水| 牟定县| 原阳县| 四子王旗| 页游| 长沙县| 宜兰县| 黄大仙区| 云和县| 墨江| 阜南县| 维西| 西乌珠穆沁旗|