日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

easyexcel 设置标题_EasyExcel,让 excel 导入导出更加简单

發(fā)布時間:2025/4/16 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 easyexcel 设置标题_EasyExcel,让 excel 导入导出更加简单 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

做積極的人,而不是積極廢人!

來源:jianshu.com/p/8f3defdc76d4EasyExcelGitHub上的官方說明快速開始maven倉庫地址導入導出總結

EasyExcel

在做excel導入導出的時候,發(fā)現項目中封裝的工具類及其難用,于是去gitHub上找了一些相關的框架,最終選定了EasyExcel。之前早有聽聞該框架,但是一直沒有去了解,這次借此學習一波,提高以后的工作效率。

實際使用中,發(fā)現是真的很easy,大部分api通過名稱就能知道大致意思,這點做的很nice。參考文檔,大部分場景的需求基本都能夠滿足。

GitHub上的官方說明圖片

快速開始

maven倉庫地址

com.alibaba

easyexcel

2.1.2

導入

如下圖excel表格:

建立導入對應實體類@Data

publicclassReqCustomerDailyImport{

/**

*客戶名稱

*/

@ExcelProperty(index=0)

privateStringcustomerName;

/**

*MIS編碼

*/

@ExcelProperty(index=1)

privateStringmisCode;

/**

*月度滾動額

*/

@ExcelProperty(index=3)

privateBigDecimalmonthlyQuota;

/**

*最新應收賬款余額

*/

@ExcelProperty(index=4)

privateBigDecimalaccountReceivableQuota;

/**

*本月利率(年化)

*/

@ExcelProperty(index=5)

privateBigDecimaldailyInterestRate;

}

Controller代碼

@PostMapping('/import')

publicvoidimportCustomerDaily(@RequestParamMultipartFilefile)throwsIOException{

InputStreaminputStream=file.getInputStream();

ListreqCustomerDailyImports=EasyExcel.read(inputStream)

.head(ReqCustomerDailyImport.class)

//設置sheet,默認讀取第一個

.sheet()

//設置標題所在行數

.headRowNumber(2)

.doReadSync();

}

運行結果圖片

可以看出只需要在實體對象使用@ExcelProperty注解,讀取時指定該class,即可讀取,并且自動過濾了空行,對于excel的讀取及其簡單。不過此時發(fā)現一個問題,這樣我如果要校驗字段該怎么辦?要將字段類型轉換成另外一個類型呢?

不必擔心,我們可以想到的問題,作者肯定也考慮到了,下面來一個Demo

代碼如下ListreqCustomerDailyImports=EasyExcel.read(inputStream)

//這個轉換是成全局的,所有java為string,excel為string的都會用這個轉換器。

//如果就想單個字段使用請使用@ExcelProperty指定converter

.registerConverter(newStringConverter())

//注冊監(jiān)聽器,可以在這里校驗字段

.registerReadListener(newCustomerDailyImportListener())

.head(ReqCustomerDailyImport.class)

.sheet()

.headRowNumber(2)

.doReadSync();

}

監(jiān)聽器

publicclassCustomerDailyImportListenerextendsAnalysisEventListener{

ListmisCodes=Lists.newArrayList();

/**

*每解析一行,回調該方法

*@paramdata

*@paramcontext

*/

@Override

publicvoidinvoke(Objectdata,AnalysisContextcontext){

StringmisCode=((ReqCustomerDailyImport)data).getMisCode();

if(StringUtils.isEmpty(misCode)){

thrownewRuntimeException(String.format('第%s行MIS編碼為空,請核實',context.readRowHolder().getRowIndex()+1));

}

if(misCodes.contains(misCodes)){

thrownewRuntimeException(String.format('第%s行MIS編碼已重復,請核實',context.readRowHolder().getRowIndex()+1));

}else{

misCodes.add(misCode);

}

}

/**

*出現異常回調

*@paramexception

*@paramcontext

*@throwsException

*/

@Override

publicvoidonException(Exceptionexception,AnalysisContextcontext)throwsException{

//ExcelDataConvertException:當數據轉換異常的時候,會拋出該異常,此處可以得知第幾行,第幾列的數據

if(exceptioninstanceofExcelDataConvertException){

IntegercolumnIndex=((ExcelDataConvertException)exception).getColumnIndex()+1;

IntegerrowIndex=((ExcelDataConvertException)exception).getRowIndex()+1;

Stringmessage='第'+rowIndex+'行,第'+columnIndex+'列'+'數據格式有誤,請核實';

thrownewRuntimeException(message);

}elseif(exceptioninstanceofRuntimeException){

throwexception;

}else{

super.onException(exception,context);

}

}

/**

*解析完全部回調

*@paramcontext

*/

@Override

publicvoiddoAfterAllAnalysed(AnalysisContextcontext){

misCodes.clear();

}

}

轉換器publicclassStringConverterimplementsConverter{

@Override

publicClasssupportJavaTypeKey(){

returnString.class;

}

@Override

publicCellDataTypeEnumsupportExcelTypeKey(){

returnCellDataTypeEnum.STRING;

}

/**

*將excel對象轉成Java對象,這里讀的時候會調用

*

*@paramcellDataNotNull

*@paramcontentPropertyNullable

*@paramglobalConfigurationNotNull

*@return

*/

@Override

publicStringconvertToJavaData(CellDatacellData,ExcelContentPropertycontentProperty,

GlobalConfigurationglobalConfiguration){

return'自定義:'+cellData.getStringValue();

}

/**

*將Java對象轉成String對象,寫出的時候調用

*

*@paramvalue

*@paramcontentProperty

*@paramglobalConfiguration

*@return

*/

@Override

publicCellDataconvertToExcelData(Stringvalue,ExcelContentPropertycontentProperty,

GlobalConfigurationglobalConfiguration){

returnnewCellData(value);

}

}

可以看出注冊了一個監(jiān)聽器:CustomerDailyImportListener,還注冊了一個轉換器:StringConverter。流程為:框架讀取一行數據,先執(zhí)行轉換器,當一行數據轉換完成,執(zhí)行監(jiān)聽器的回調方法,如果轉換的過程中,出現轉換異常,也會回調監(jiān)聽器中的onException方法。因此,可以在監(jiān)聽器中校驗數據,在轉換器中轉換數據類型或者格式。

運行結果圖片

修改一下表格,測試校驗是否生效圖片

再次導入,查看運行結果圖片

導入相關常用API

注解ExcelProperty 指定當前字段對應excel中的那一列。可以根據名字或者Index去匹配。當然也可以不寫,默認第一個字段就是index=0,以此類推。千萬注意,要么全部不寫,要么全部用index,要么全部用名字去匹配。千萬別三個混著用,除非你非常了解源代碼中三個混著用怎么去排序的。ExcelIgnore 默認所有字段都會和excel去匹配,加了這個注解會忽略該字段。DateTimeFormat 日期轉換,用String去接收excel日期格式的數據會調用這個注解。里面的value參照java.text.SimpleDateFormat。NumberFormat 數字轉換,用String去接收excel數字格式的數據會調用這個注解。里面的value參照java.text.DecimalFormat。

EasyExcel相關參數readListener 監(jiān)聽器,在讀取數據的過程中會不斷的調用監(jiān)聽器。converter 轉換器,默認加載了很多轉換器。也可以自定義,如果使用的是registerConverter,那么該轉換器是全局的,如果要對單個字段生效,可以在ExcelProperty注解的converter指定轉換器。headRowNumber 需要讀的表格有幾行頭數據。默認有一行頭,也就是認為第二行開始起為數據。head 與clazz二選一。讀取文件頭對應的列表,會根據列表匹配數據,建議使用class。autoTrim 字符串、表頭等數據自動trim。sheetNo 需要讀取Sheet的編碼,建議使用這個來指定讀取哪個Sheet。sheetName 根據名字去匹配Sheet,excel 2003不支持根據名字去匹配。

導出

建立導出對應實體類

@Data

@Builder

publicclassRespCustomerDailyImport{

@ExcelProperty('客戶編碼')

privateStringcustomerName;

@ExcelProperty('MIS編碼')

privateStringmisCode;

@ExcelProperty('月度滾動額')

privateBigDecimalmonthlyQuota;

@ExcelProperty('最新應收賬款余額')

privateBigDecimalaccountReceivableQuota;

@NumberFormat('#.##%')

@ExcelProperty('本月利率(年化)')

privateBigDecimaldailyInterestRate;

}

Controller代碼@GetMapping('/export')

publicvoidexport(HttpServletResponseresponse)throwsIOException{

//生成數據

ListrespCustomerDailyImports=Lists.newArrayList();

for(inti=0;i<50;i++){

RespCustomerDailyImportrespCustomerDailyImport=RespCustomerDailyImport.builder()

.misCode(String.valueOf(i))

.customerName('customerName'+i)

.monthlyQuota(newBigDecimal(String.valueOf(i)))

.accountReceivableQuota(newBigDecimal(String.valueOf(i)))

.dailyInterestRate(newBigDecimal(String.valueOf(i))).build();

respCustomerDailyImports.add(respCustomerDailyImport);

}

response.setContentType('application/vnd.ms-excel');

response.setCharacterEncoding('utf-8');

//這里URLEncoder.encode可以防止中文亂碼當然和easyexcel沒有關系

StringfileName=URLEncoder.encode('導出','UTF-8');

response.setHeader('Content-disposition','attachment;filename='+fileName+'.xlsx');

EasyExcel.write(response.getOutputStream(),RespCustomerDailyImport.class)

.sheet('sheet0')

//設置字段寬度為自動調整,不太精確

.registerWriteHandler(newLongestMatchColumnWidthStyleStrategy())

.doWrite(respCustomerDailyImports);

}

導出效果圖片

導出相關常用API

注解ExcelProperty 指定寫到第幾列,默認根據成員變量排序。value指定寫入的名稱,默認成員變量的名字。ExcelIgnore 默認所有字段都會寫入excel,這個注解會忽略這個字段。DateTimeFormat 日期轉換,將Date寫到excel會調用這個注解。里面的value參照java.text.SimpleDateFormat。NumberFormat 數字轉換,用Number寫excel會調用這個注解。里面的value參照java.text.DecimalFormat。

EasyExcel相關參數needHead 監(jiān)聽器是否導出頭。useDefaultStyle 寫的時候是否是使用默認頭。head 與clazz二選一。寫入文件的頭列表,建議使用class。autoTrim 字符串、表頭等數據自動trim。sheetNo 需要寫入的編碼。默認0。sheetName 需要些的Sheet名稱,默認同sheetNo。

總結

可以看出不管是excel的讀取還是寫入,都是一個注解加上一行代碼完成,可以讓我們少些很多解析的代碼,極大減少了重復的工作量。當然這兩個例子使用了最簡單的方式,EasyExcel還支持更多場景,例如讀,可以讀多個sheet,也可以解析一行數據或者多行數據做一次入庫操作;寫的話,支持復雜頭,指定列寫入,重復多次寫入,多個sheet寫入,根據模板寫入等等。更多的例子可以去參考EasyExcel官方文檔https://www.yuque.com/easyexcel/doc/easyexcel

《新程序員》:云原生和全面數字化實踐50位技術專家共同創(chuàng)作,文字、視頻、音頻交互閱讀

總結

以上是生活随笔為你收集整理的easyexcel 设置标题_EasyExcel,让 excel 导入导出更加简单的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。