




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
第Java使用EasyExcel動態(tài)添加自增序號列本文將介紹如何通過使用EasyExcel自定義攔截器實現(xiàn)在最終的Excel文件中新增一列自增的序號列,最終的效果如下:
此外,本文所使用的完整代碼示例已上傳到GitHub。
實現(xiàn)
本文主要是通過自定義一個繼承AbstractRowWriteHandler的攔截器來實現(xiàn)在最終導(dǎo)出的結(jié)果中新增序號列,通過修改源碼中保存頭部標(biāo)題的Map內(nèi)容來給自己添加的序號列留出位置,先展示最終的代碼:
*自定義excel行處理器,增加序號列
*@authorbutterfly
*@date2025-09-05
@Component
publicclassAddNoHandlerextendsAbstractRowWriteHandler{
privatebooleaninit=true;
@Override
publicvoidbeforeRowCreate(WriteSheetHolderwriteSheetHolder,WriteTableHolderwriteTableHolder,
IntegerrowIndex,IntegerrelativeRowIndex,BooleanisHead){
if(init){
//修改存儲頭部及對應(yīng)字段信息的map,將其中的內(nèi)容均右移一位,給新增的序列號預(yù)留為第一列
ExcelWriteHeadPropertyexcelWriteHeadProperty=writeSheetHolder.excelWriteHeadProperty();
MapInteger,HeadheadMap=excelWriteHeadProperty.getHeadMap();
MapInteger,ExcelContentPropertycontentMap=excelWriteHeadProperty.getContentPropertyMap();
intsize=headMap.size();
for(intcurrent=size;currentcurrent--){
intprevious=current-1;
headMap.put(current,headMap.get(previous));
contentMap.put(current,contentMap.get(previous));
//空出第一列
headMap.remove(0);
contentMap.remove(0);
//只需要修改一次map即可,故使用init變量進(jìn)行控制
init=false;
@Override
publicvoidafterRowCreate(WriteSheetHolderwriteSheetHolder,WriteTableHolderwriteTableHolder,Rowrow,
IntegerrelativeRowIndex,BooleanisHead){
//在行創(chuàng)建完成后添加序號列
Cellcell=row.createCell(0);
introwNum=row.getRowNum();
if(rowNum==0){
cell.setCellValue(ExcelConstant.TITLE);
}else{
cell.setCellValue(rowNum);
@Override
publicvoidafterRowDispose(WriteSheetHolderwriteSheetHolder,WriteTableHolderwriteTableHolder,Rowrow,
IntegerrelativeRowIndex,BooleanisHead){
if(row.getLastCellNum()1){
//將自定義新增的序號列的樣式設(shè)置與默認(rèn)的樣式一致
row.getCell(0).setCellStyle(row.getCell(1).getCellStyle());
}
afterRowCreate和afterRowDispose方法中的內(nèi)容很好理解,一個用于控制控制新增序號列的內(nèi)容,一個用于控制新增列的樣式。而beforeRowCreate中的內(nèi)容則稍微復(fù)雜,主要用于給新增的序號列空出位置。同時,由于beforeRowCreate會在每次創(chuàng)建行時均會被調(diào)用,但是原始的存儲頭部信息的Map只需要修改一次,因此這里通過使用init變量控制只會修改一次。
思路
通過查看com.alibaba.excel.write.executor.ExcelWriteAddExecutor類中的addOneRowOfDataToExcel方法源碼,可以看到在新增行的前后會分別調(diào)用beforeRowCreate和afterRowCreate方法,并且在一行數(shù)據(jù)添加完成后會調(diào)用afterRowDispose,這也是上述攔截器生效的原理,源碼如下:
privatevoidaddOneRowOfDataToExcel(ObjectoneRowData,intn,intrelativeRowIndex,
MapInteger,FieldsortedAllFiledMap){
//行數(shù)據(jù)為空,直接返回
if(oneRowData==null){
return;
//創(chuàng)建數(shù)據(jù)行對象,同時分別在創(chuàng)建行前后調(diào)用攔截器
WriteHandlerUtils.beforeRowCreate(writeContext,n,relativeRowIndex,Boolean.FALSE);
Rowrow=WorkBookUtil.createRow(writeContext.writeSheetHolder().getSheet(),n);
WriteHandlerUtils.afterRowCreate(writeContext,row,relativeRowIndex,Boolean.FALSE);
//將實體數(shù)據(jù)內(nèi)容填充到行中
if(oneRowDatainstanceofList){
addBasicTypeToExcel((List)oneRowData,row,relativeRowIndex);
}else{
//下面會繼續(xù)查看這個方法
addJavaObjectToExcel(oneRowData,row,relativeRowIndex,sortedAllFiledMap);
//行創(chuàng)建完成后,調(diào)用相應(yīng)攔截器
WriteHandlerUtils.afterRowDispose(writeContext,row,relativeRowIndex,Boolean.FALSE);
而之所以我們修改headMap和contentMap的內(nèi)容就可以實現(xiàn)最終效果,只需要繼續(xù)查看該類中addJavaObjectToExcel方法的代碼即可知道原因:
privatevoidaddJavaObjectToExcel(ObjectoneRowData,Rowrow,intrelativeRowIndex,
MapInteger,FieldsortedAllFiledMap){
WriteHoldercurrentWriteHolder=writeContext.currentWriteHolder();
//將自己的實體數(shù)據(jù)映射到beanMap
BeanMapbeanMap=BeanMap.create(oneRowData);
SetStringbeanMapHandledSet=newHashSetString
intcellIndex=0;
//Ifit'saclassitneedstobecastbytype
if(HeadKindEnum.CLASS.equals(writeContext.currentWriteHolder().excelWriteHeadProperty().getHeadKind())){
//我們修改的就是這里的headMap和contentPropertyMap內(nèi)容
MapInteger,HeadheadMap=writeContext.currentWriteHolder().excelWriteHeadProperty().getHeadMap();
MapInteger,ExcelContentPropertycontentPropertyMap=
writeContext.currentWriteHolder().excelWriteHeadProperty().getContentPropertyMap();
//遍歷所有的列頭,插入數(shù)據(jù)
for(Map.EntryInteger,ExcelContentPropertyentry:contentPropertyMap.entrySet()){
//獲取cell的下標(biāo),后續(xù)將內(nèi)容插入指定的列
cellIndex=entry.getKey();
ExcelContentPropertyexcelContentProperty=entry.getValue();
Stringname=excelContentProperty.getField().getName();
if(!beanMap.containsKey(name)){
continue;
//控制單元格的內(nèi)容
Headhead=headMap.get(cellIndex);
WriteHandlerUtils.beforeCellCreate(writeContext,row,head,cellIndex,
relativeRowIndex,Boolean.FALSE);
Cellcell=WorkBookUtil.createCell(row,cellIndex);
WriteHandlerUtils.afterCellCreate(writeContext,cell,head,relativeRowIndex,Boolean.FALSE);
Objectvalue=beanMap.get(name);
CellDatacellData=converterAndSet(currentWriteHolder,excelContentProperty.getField().getType(),
cell,value,excelContentProperty,head,relativeRowIndex);
WriteHandlerUtils.afterCellDispose(writeContext,cellData,cell,head,
relativeRowIndex,Boolean.FALSE);
beanMapHandledSet.add(name);
//省略了后面無關(guān)的內(nèi)容
其它
通過以上自定義的攔截器,就可以寫一個簡單的demo進(jìn)行測試:
*Excel下載控制器
*@authorbutterfly
*@date2025-09-05
@RestController
publicclassExcelController{
*添加序號列測試
*@paramresponseresponse
@GetMapping("/col")
publicvoidcol(HttpServletResponseresponse){
try{
ListStudentstudents=getStudentList();
EasyExcel.write(response.getOutputStream(),Student.class)
.registerWriteHandler(newAddNoHandler())
.sheet()
.doWrite(students);
}catch(Exceptione){
System.out.println(ExcelConstant.DOWNLOAD_FAILED);
*生成學(xué)生列表
*@return學(xué)生列表
privateListStudentgetStudentList(){
returnArrays.asList(
newStudent("2025090101","張三",19),
newStudent("2025090102","李四",18),
newStudent("2025090103","王二",20)
然后是前端的測試代碼:
!DOCTYPEhtml
htmllang="en"
head
metacharset="UTF-8"
title文件下載測試/title
scriptsrc="/axios/0.21.2/axios.min.js"/script
/head
body
button添加序號列測試/button
script
functioncol(){
download('http://localhost:8080/col','col.xlsx')
functiondownload(url,name){
axios({
url:url,
responseType:'blob'
}).then((re
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- DB31/T 478.17-2014主要工業(yè)產(chǎn)品用水定額及其計算方法第17部分:倉儲
- DB31/T 1373-2022海三棱藨草種群生態(tài)修復(fù)技術(shù)規(guī)程
- DB31/T 1190.2-2019蔬菜病蟲害綠色防控技術(shù)規(guī)范第2部分:殺蟲燈
- 2025房屋租賃合同范本全面版
- 設(shè)計溝通與表達(dá)技巧考核試卷
- 2024年垃圾前端收轉(zhuǎn)裝備項目投資申請報告代可行性研究報告
- 2024年紙品清潔資金申請報告代可行性研究報告
- 網(wǎng)絡(luò)安全考試技巧與試題
- 老舊小區(qū)電梯加裝與安全檢測服務(wù)協(xié)議
- 智能家居暖通系統(tǒng)定制設(shè)計與施工協(xié)議
- 美容整形中的健康管理與風(fēng)險防控
- 班組長能力提升人際交往與矛盾處理
- 金橋焊材產(chǎn)品質(zhì)量證明書-可-編-輯
- 環(huán)保知識培訓(xùn)
- 齒輪測量中心校準(zhǔn)規(guī)范
- 河道治理工程地質(zhì)勘察報告
- 二手房買賣標(biāo)準(zhǔn)協(xié)議書
- 寶鋼BQB 481-2023全工藝?yán)滠堉蓄l無取向電工鋼帶文件
- 《建筑施工安全檢查標(biāo)準(zhǔn)》jgj59
- 出境產(chǎn)品企業(yè)自檢自控計劃
- 勾股定理說課課件
評論
0/150
提交評論