Java實現(xiàn)批量化操作Excel文件的示例代碼
前言 | 問題背景
在操作Excel的場景中,通常會有一些針對Excel的批量操作,批量的意思一般有兩種:
對批量的Excel文件進行操作。如導入多個Excel文件,并處理數據,或導出多個Excel文件。這類場景,往往操作很相似,但是要反復讀寫Excel文件。對單個或復數個進行批量操作。如對Excel文件,進行批量替換文本,批量添加公式或者批量增加樣式。這類場景,一般需要操作的Excel文件不多,但是需要反復執(zhí)行特定操作,這種時候需要有易用的API來幫忙。
現(xiàn)有的Excel組件中,POI是非常常用的組件,但是針對上述不同的場景,其分別會對組件提出兩類要求。
第一類場景會反復讀取或者寫入文件,需要組件對于內存有足夠好的優(yōu)化,否則很容易出現(xiàn)內存溢出(out of memory)的問題。
第二類場景則需要組件提供易用的API,例如替換字符串,如果沒有查找(find)或者替換(replace)的接口API。則需要自己遍歷單元格(cell)來查找值。
雖然POI在上面兩種要求上可能會有欠缺,但還有其他的組件可以選擇,比如EasyExcel,GcExcel等。
下面是以GcExcel為例,對上述兩類場景,分別列舉的例子。
什么是GcExcel
場景1 批量導入Excel文件,并讀取特定區(qū)域的數據
例如有多個Excel文件,名字都是GUID。這些Excel文件來自于填報的數據,需要對其中的內容進行匯總。
如Excel的表單內容如下圖:
需要對B3到C6的格子進行取值,可以用下面的代碼提取數據。
@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 //添加處理數據的邏輯 } } } }
通過listFiles()方法,獲取所有的Excel文件。循環(huán)讀取每一個文件,通過GcExcel打開Excel文件。使用IRange上的getValue()方法可以把Excel中的格子以二維數組的方式讀取出來。
之后就可以通過訪問二維數組來處理業(yè)務邏輯。
場景2 批量導出Excel文件,導出前把數據寫在特定位置
繼續(xù)以第一個Excel文件為例子,當在數據庫中已經存有一些數據,希望把數據寫入并導出到復數個Excel文件里或者導出為PDF文件。
真實的場景有,如企業(yè)發(fā)放工資,每個月需要給每一位員工發(fā)放一份電子版的工資單,因為每個員工的工資單信息不相同,這個場景下,則需要把數據批量導出為復數個PDF。
@Test public void testExportFormFile() { String outPutPath = "E:/testFolder"; //給valueList初始化數據,替換為從數據庫,CSV或者JSON等中獲取數據。 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可以直接把二維數組設置給一個range,從數據庫中把數據加載出來以后,可以整理成二維數組。
之后通過GcExcel的SetValue()把二維數組直接設置到sheet上,最后通過工作簿(workbook)上的save方法保存導出。
場景3 打開Excel文件,批量替換關鍵字
在這個場景中,需要把Excel文件作為模板,把其中的一些自定義關鍵字,替換成數據。
比如在有一個制式的報表,需要把數據填寫進去。例如表頭,姓名,報表相關的條目,數據等信息??赡軙褕蟊碇谱鞒梢粋€模板,之后把表頭,姓名等位置留空,或者用關鍵字作為占位符。例如“%Name%”可以作為名字的占位符,在填寫數據的時候,可以對%Name%進行替換。
@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)文件,準備好數據以后,直接通過IRange的replace方法替換自定義的關鍵字。
替換完之后,保存為新的Excel即可。
對于更高級復雜的數據填充,GcExcel也有模板功能,設置好模板后,可以直接綁定數據源,GcExcel會自動填充數據到模板里。
場景4 打開Excel模板文件,批量獲取計算結果
例如有一個Excel文件,用于計算保險或者行業(yè)數據。需要在固定的位置填入值,使用Excel中的公式計算結果。
@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的公式計算是在取值的時候計算的,因此不需要顯示調用calculate之類的方法,只需要把輸入的參數準備好,放在Excel特定的cell中,就可以直接獲取公式的計算結果了。
以上就是一些常見的批量處理Excel的方法,僅使用GcExcel Java的代碼為例,同樣的思路也可以使用其他的組件來實現(xiàn)。
到此這篇關于Java實現(xiàn)批量化操作Excel文件的示例代碼的文章就介紹到這了,更多相關Java操作Excel內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Hadoop+HBase+ZooKeeper分布式集群環(huán)境搭建步驟
這篇文章主要介紹了Hadoop+HBase+ZooKeeper分布式集群環(huán)境搭建,集群環(huán)境至少需要3個節(jié)點,1個Master,2個Slave,節(jié)點之間局域網連接,可以相互ping通,本文通過實例給大家介紹的非常詳細,需要的朋友可以參考下2022-04-04工作中禁止使用Executors快捷創(chuàng)建線程池原理詳解
這篇文章主要為大家介紹了工作中禁止使用Executors快捷創(chuàng)建線程池原理詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-11-11SpringBoot啟動時自動執(zhí)行代碼的幾種實現(xiàn)方式
這篇文章主要給大家介紹了關于SpringBoot啟動時自動執(zhí)行代碼的幾種實現(xiàn)方式,文中通過實例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2022-02-02解決springboot的JPA在Mysql8新增記錄失敗的問題
這篇文章主要介紹了解決springboot的JPA在Mysql8新增記錄失敗的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-06-06