




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
第Java使用EasyExcel動態(tài)添加自增序號列本文將介紹如何通過使用EasyExcel自定義攔截器實(shí)現(xiàn)在最終的Excel文件中新增一列自增的序號列,最終的效果如下:
此外,本文所使用的完整代碼示例已上傳到GitHub。
實(shí)現(xiàn)
本文主要是通過自定義一個繼承AbstractRowWriteHandler的攔截器來實(shí)現(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í)體數(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)容就可以實(shí)現(xiàn)最終效果,只需要繼續(xù)查看該類中addJavaObjectToExcel方法的代碼即可知道原因:
privatevoidaddJavaObjectToExcel(ObjectoneRowData,Rowrow,intrelativeRowIndex,
MapInteger,FieldsortedAllFiledMap){
WriteHoldercurrentWriteHolder=writeContext.currentWriteHolder();
//將自己的實(shí)體數(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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年科學(xué)家精神思政大課心得體會模版
- 細(xì)菌性腦膜炎的臨床護(hù)理
- 有關(guān)數(shù)學(xué)的四年級教學(xué)總結(jié)模版
- 兩位數(shù)減兩位數(shù)(不退位)教學(xué)設(shè)計
- 兒童單純性肥胖的臨床護(hù)理
- 中介合同范例范例
- 上班人員簽合同范例
- 醫(yī)療衛(wèi)生系統(tǒng)內(nèi)的綠色供應(yīng)鏈管理與實(shí)施效果研究報告
- 供貨合同范例餐飲
- 公會與主播合同范例
- 9E燃機(jī)系統(tǒng)培訓(xùn)演3.25
- 蘇霍姆林斯基教育思想-PPT課件
- 脊髓損傷康復(fù)評定治療PPT課件
- 啤酒貼標(biāo)機(jī)畢業(yè)設(shè)計論文
- 玻璃纖維生產(chǎn)工藝流程培訓(xùn)
- 無砟軌道底座板首件施工總結(jié)(最新)
- 寶鋼總平面圖
- 鹽邊縣攀西紅格礦業(yè)有限責(zé)任公司紅格北礦區(qū)東排土場初步設(shè)計安全專篇
- 作文紙模板帶字?jǐn)?shù)
- (完整word版)機(jī)械制造工藝學(xué)教案
- ZDJ-4A型自動電位滴定儀操作方法
評論
0/150
提交評論