Java實(shí)現(xiàn)批量化操作Excel文件的示例代碼
前言 | 問題背景
在操作Excel的場景中,通常會有一些針對Excel的批量操作,批量的意思一般有兩種:
對批量的Excel文件進(jìn)行操作。如導(dǎo)入多個(gè)Excel文件,并處理數(shù)據(jù),或?qū)С龆鄠€(gè)Excel文件。這類場景,往往操作很相似,但是要反復(fù)讀寫Excel文件。對單個(gè)或復(fù)數(shù)個(gè)進(jìn)行批量操作。如對Excel文件,進(jìn)行批量替換文本,批量添加公式或者批量增加樣式。這類場景,一般需要操作的Excel文件不多,但是需要反復(fù)執(zhí)行特定操作,這種時(shí)候需要有易用的API來幫忙。
現(xiàn)有的Excel組件中,POI是非常常用的組件,但是針對上述不同的場景,其分別會對組件提出兩類要求。
第一類場景會反復(fù)讀取或者寫入文件,需要組件對于內(nèi)存有足夠好的優(yōu)化,否則很容易出現(xiàn)內(nèi)存溢出(out of memory)的問題。
第二類場景則需要組件提供易用的API,例如替換字符串,如果沒有查找(find)或者替換(replace)的接口API。則需要自己遍歷單元格(cell)來查找值。
雖然POI在上面兩種要求上可能會有欠缺,但還有其他的組件可以選擇,比如EasyExcel,GcExcel等。
下面是以GcExcel為例,對上述兩類場景,分別列舉的例子。
什么是GcExcel

場景1 批量導(dǎo)入Excel文件,并讀取特定區(qū)域的數(shù)據(jù)
例如有多個(gè)Excel文件,名字都是GUID。這些Excel文件來自于填報(bào)的數(shù)據(jù),需要對其中的內(nèi)容進(jìn)行匯總。
如Excel的表單內(nèi)容如下圖:

需要對B3到C6的格子進(jìn)行取值,可以用下面的代碼提取數(shù)據(jù)。
@Test
public void testImportFormFile() {
String folderPath = "path/testFolder"; //使用你的路徑
File folder = new File(folderPath);
File[] files = folder.listFiles();
if (files != null) {
for (File file: files){
if(file.isFile() && file.getName().endsWith(".xlsx")){
Workbook wb = new Workbook();
wb.open(file.getAbsolutePath());
Object[][] value = (Object[][]) wb.getActiveSheet().getRange("B3:C6").getValue();
System.out.println(value[0][1]); //小葡萄
System.out.println(value[1][1]); //20.0
System.out.println(value[2][1]); //開發(fā)部
System.out.println(value[3][1]); //610123456789012345
//添加處理數(shù)據(jù)的邏輯
}
}
}
}
通過listFiles()方法,獲取所有的Excel文件。循環(huán)讀取每一個(gè)文件,通過GcExcel打開Excel文件。使用IRange上的getValue()方法可以把Excel中的格子以二維數(shù)組的方式讀取出來。
之后就可以通過訪問二維數(shù)組來處理業(yè)務(wù)邏輯。
場景2 批量導(dǎo)出Excel文件,導(dǎo)出前把數(shù)據(jù)寫在特定位置
繼續(xù)以第一個(gè)Excel文件為例子,當(dāng)在數(shù)據(jù)庫中已經(jīng)存有一些數(shù)據(jù),希望把數(shù)據(jù)寫入并導(dǎo)出到復(fù)數(shù)個(gè)Excel文件里或者導(dǎo)出為PDF文件。
真實(shí)的場景有,如企業(yè)發(fā)放工資,每個(gè)月需要給每一位員工發(fā)放一份電子版的工資單,因?yàn)槊總€(gè)員工的工資單信息不相同,這個(gè)場景下,則需要把數(shù)據(jù)批量導(dǎo)出為復(fù)數(shù)個(gè)PDF。
@Test
public void testExportFormFile() {
String outPutPath = "E:/testFolder";
//給valueList初始化數(shù)據(jù),替換為從數(shù)據(jù)庫,CSV或者JSON等中獲取數(shù)據(jù)。
ArrayList<Object[][]> valueList = new ArrayList<Object[][]>();
for (Object[][] value : valueList) {
Workbook wb = new Workbook();
wb.getActiveSheet().getRange("B3:C6").setValue(value);
wb.save(outPutPath + UUID.randomUUID().toString() + ".xlsx");
}
}
GcExcel可以直接把二維數(shù)組設(shè)置給一個(gè)range,從數(shù)據(jù)庫中把數(shù)據(jù)加載出來以后,可以整理成二維數(shù)組。
之后通過GcExcel的SetValue()把二維數(shù)組直接設(shè)置到sheet上,最后通過工作簿(workbook)上的save方法保存導(dǎo)出。
場景3 打開Excel文件,批量替換關(guān)鍵字
在這個(gè)場景中,需要把Excel文件作為模板,把其中的一些自定義關(guān)鍵字,替換成數(shù)據(jù)。
比如在有一個(gè)制式的報(bào)表,需要把數(shù)據(jù)填寫進(jìn)去。例如表頭,姓名,報(bào)表相關(guān)的條目,數(shù)據(jù)等信息??赡軙褕?bào)表制作成一個(gè)模板,之后把表頭,姓名等位置留空,或者用關(guān)鍵字作為占位符。例如“%Name%”可以作為名字的占位符,在填寫數(shù)據(jù)的時(shí)候,可以對%Name%進(jìn)行替換。
@Test
public void testReplaceTemplateFile() {
String templateFilePath = "test.xlsx";
Workbook wb = new Workbook();
wb.open(templateFilePath);
IRange usedRange = wb.getActiveSheet().getUsedRange();
//load data
ArrayList<Object[]> valueList = new ArrayList<Object[]>();
for (Object[] value : valueList) {
usedRange.replace(value[0],value[1]);
}
wb.save("result.xlsx", SaveFileFormat.Xlsx);
}
通過工作簿(workbook)打開模板(template)文件,準(zhǔn)備好數(shù)據(jù)以后,直接通過IRange的replace方法替換自定義的關(guān)鍵字。
替換完之后,保存為新的Excel即可。
對于更高級復(fù)雜的數(shù)據(jù)填充,GcExcel也有模板功能,設(shè)置好模板后,可以直接綁定數(shù)據(jù)源,GcExcel會自動填充數(shù)據(jù)到模板里。
場景4 打開Excel模板文件,批量獲取計(jì)算結(jié)果
例如有一個(gè)Excel文件,用于計(jì)算保險(xiǎn)或者行業(yè)數(shù)據(jù)。需要在固定的位置填入值,使用Excel中的公式計(jì)算結(jié)果。
@Test
public void testCalcFormulaByTemplateFile() {
String templateFilePath = "E:/testFolder/testFormula.xlsx";
Workbook wb = new Workbook();
wb.open(templateFilePath);
//``獲取特定的值,比如以下
ArrayList<Object[]> valueList = new ArrayList<Object[]>();
for (Object[] value : valueList) {
Object A1Value = value[0];
Object A2Value = value[1];
Object result = null;
wb.getActiveSheet().getRange("A1").setValue(A1Value);
wb.getActiveSheet().getRange("A2").setValue(A2Value);
result = wb.getActiveSheet().getRange("A3").getValue();
System.out.println(result);
}
}
GcExcel的公式計(jì)算是在取值的時(shí)候計(jì)算的,因此不需要顯示調(diào)用calculate之類的方法,只需要把輸入的參數(shù)準(zhǔn)備好,放在Excel特定的cell中,就可以直接獲取公式的計(jì)算結(jié)果了。
以上就是一些常見的批量處理Excel的方法,僅使用GcExcel Java的代碼為例,同樣的思路也可以使用其他的組件來實(shí)現(xiàn)。
到此這篇關(guān)于Java實(shí)現(xiàn)批量化操作Excel文件的示例代碼的文章就介紹到這了,更多相關(guān)Java操作Excel內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
checkpoint 機(jī)制具體實(shí)現(xiàn)示例詳解
這篇文章主要為大家介紹了checkpoint 機(jī)制具體實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02
Netty分布式flush方法刷新buffer隊(duì)列源碼剖析
這篇文章主要為大家介紹了Netty分布式flush方法刷新buffer隊(duì)列源碼剖析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-03-03
mybatisPlus條件構(gòu)造器常用方法小結(jié)
這篇文章主要介紹了mybatisPlus條件構(gòu)造器常用方法,首先是.select和其他條件,本文結(jié)合示例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2022-10-10
Feign Client 超時(shí)時(shí)間配置不生效的解決
這篇文章主要介紹了Feign Client 超時(shí)時(shí)間配置不生效的解決方案,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-09-09
全網(wǎng)最深分析SpringBoot MVC自動配置失效的原因
這篇文章主要介紹了全網(wǎng)最深分析SpringBoot MVC自動配置失效的原因,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-07-07

