Java使用poi實(shí)現(xiàn)excel的導(dǎo)入操作指南
創(chuàng)建項(xiàng)目測(cè)試
1 創(chuàng)建springBoot項(xiàng)目
2 pom導(dǎo)入相關(guān)依賴
<!--導(dǎo)入依賴jar包--> <!--xls(03)--> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.9</version> </dependency> <!--xlsx(07)--> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>3.9</version> </dependency> <!--日期格式化工具--> <dependency> <groupId>joda-time</groupId> <artifactId>joda-time</artifactId> <version>2.10.1</version> </dependency> <!--單元測(cè)試--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency>
3 本地創(chuàng)建兩個(gè)excel 分別是03版和07版
首先03版,它最多有65536行
但是07版的,是沒(méi)有限制的
他們對(duì)應(yīng)的后綴也是不一樣的,03版本的xls,07版本的是xslx,這意味著操作它們的工具類也不相同.03版本用的是poi,07版用的則是poi-ooxml
4 Java的宗旨就是萬(wàn)物皆對(duì)象,我們也要把excel當(dāng)成我們的一個(gè)對(duì)象去處理
1 工作薄
首先我們打開(kāi)的excel就是一個(gè)大對(duì)象,也叫工作簿,它包括以下內(nèi)容
2 工作表
每一個(gè)sheet也是我們excel對(duì)象的屬性,也叫工作表,我們肯定是現(xiàn)有工作簿才會(huì)有工作表,而且會(huì)默認(rèn)自帶sheet,也可以根據(jù)我們的需要自行添加sheet工作表
3 行
excel中有很多行,每一行也是我們excel對(duì)象的屬性(橫的叫行,豎的叫列)
4 列
excel中有很多列,每一列也是我們excel對(duì)象的屬性(橫的叫行,豎的叫列)
5 單元格
一行一列有很多個(gè)單元格,每一個(gè)單元格也是我們excel對(duì)象的屬性
創(chuàng)建我們的測(cè)試類,創(chuàng)建Workbook對(duì)象,按著ctrl點(diǎn)進(jìn)去發(fā)現(xiàn)它是一個(gè)接口
點(diǎn)擊箭頭可以看到它的三個(gè)實(shí)現(xiàn)類
定義工作簿,工作表,行列,單元格,和我們手動(dòng)創(chuàng)建excel是一樣的操作,只不過(guò)是用代碼來(lái)實(shí)現(xiàn)
03版本excel IO操作寫(xiě)的全部代碼如下
package com.wyh.Test; import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import org.joda.time.DateTime; import org.junit.Test; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.util.Date; /** * @program: JavaExecl * @description: 寫(xiě)excel 03版本 * @author: 魏一鶴 * @createDate: 2021-12-12 10:42 **/ public class ExcelWrite03 { //全局路徑,供我們操作使用方便 static String path= "D:\Tools\JavaWorkSpace\JavaExecl\" ; @Test public void ExcelWrite03() throws Exception { //1創(chuàng)建一個(gè)工作簿 Workbook workbook=new HSSFWorkbook(); //2創(chuàng)建一個(gè)工作表 工作簿里面包含工作表,所以創(chuàng)建工作表要通過(guò)工作簿創(chuàng)建 //默認(rèn)的工作表是沒(méi)有名字的,需要我們手動(dòng)賦值,和我們?cè)趀xcel中更改sheet工作表的名稱是一樣的 操作 Sheet sheet=workbook.createSheet( "用戶表" ); //3創(chuàng)建行 行也是在我們的表中存在的,所以需要用到表來(lái)創(chuàng)建 //默認(rèn)從0開(kāi)始 也就是第一行 Row row1 = sheet.createRow(0); //創(chuàng)建單元格 第一行的第一個(gè)數(shù)據(jù) 用坐標(biāo)表示為(1,1) Cell cell11 = row1.createCell(0); //創(chuàng)建單元格 第一行的第二個(gè)數(shù)據(jù) 用坐標(biāo)表示為(1,2) Cell cell12 = row1.createCell(1); //給單元格賦值 cell11.setCellValue( "姓名" ); cell12.setCellValue( "魏一鶴" ); //創(chuàng)建第二行 Row row2=sheet.createRow(1); //創(chuàng)建第二行的第一列 Cell cell21 = row2.createCell(0); Cell cell22 = row2.createCell(1); //給單元格賦值(2.1) cell21.setCellValue( "出生日期" ); //創(chuàng)建時(shí)間并且格式化 String s = new DateTime().toString( "yyyy-MM-dd HH:mm:ss" ); //給單元格賦值(2.2) cell22.setCellValue(s); //生成一張表 其實(shí)就是IO流操作 03版本就是使用xls文件結(jié)尾 FileOutputStream fileOutputStream = new FileOutputStream(path + "用戶測(cè)試03.xls" ); //輸出工作簿 workbook.write(fileOutputStream); //關(guān)閉流 fileOutputStream.close(); System.out.println( "用戶測(cè)試03.xls生成完畢" ); } }
07版本excel IO操作寫(xiě)的全部代碼如下
package com.wyh.Test; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.joda.time.DateTime; import org.junit.Test; import java.io.FileOutputStream; /** * @program: JavaExecl * @description: 07版本excel寫(xiě)操作 * @author: 魏一鶴 * @createDate: 2021-12-12 23:58 **/ public class ExcelWrite07 { //全局路徑,供我們操作使用方便 static String path= "D:\Tools\JavaWorkSpace\JavaExecl\" ; @Test public void ExcelWrite07() throws Exception { //07版和03最大的差別就是使用的工具不一樣 03是HSSF 07是XSSF //其他代碼無(wú)需改動(dòng) //1創(chuàng)建一個(gè)工作簿 Workbook workbook=new XSSFWorkbook(); //2創(chuàng)建一個(gè)工作表 工作簿里面包含工作表,所以創(chuàng)建工作表要通過(guò)工作簿創(chuàng)建 //默認(rèn)的工作表是沒(méi)有名字的,需要我們手動(dòng)賦值,和我們?cè)趀xcel中更改sheet工作表的名稱是一樣的 操作 Sheet sheet=workbook.createSheet( "用戶表" ); //3創(chuàng)建行 行也是在我們的表中存在的,所以需要用到表來(lái)創(chuàng)建 //默認(rèn)從0開(kāi)始 也就是第一行 Row row1 = sheet.createRow(0); //創(chuàng)建單元格 第一行的第一個(gè)數(shù)據(jù) 用坐標(biāo)表示為(1,1) Cell cell11 = row1.createCell(0); //創(chuàng)建單元格 第一行的第二個(gè)數(shù)據(jù) 用坐標(biāo)表示為(1,2) Cell cell12 = row1.createCell(1); //給單元格賦值 cell11.setCellValue( "今日學(xué)習(xí)" ); cell12.setCellValue( "api和easyExcl導(dǎo)出導(dǎo)入excel" ); //創(chuàng)建第二行 Row row2=sheet.createRow(1); //創(chuàng)建第二行的第一列 Cell cell21 = row2.createCell(0); Cell cell22 = row2.createCell(1); //給單元格賦值(2.1) cell21.setCellValue( "學(xué)習(xí)日期" ); //創(chuàng)建時(shí)間并且格式化 String s = new DateTime().toString( "yyyy-MM-dd HH:mm:ss" ); //給單元格賦值(2.2) cell22.setCellValue(s); //生成一張表 其實(shí)就是IO流操作 07版本就是使用xlsx文件結(jié)尾 FileOutputStream fileOutputStream = new FileOutputStream(path + "用戶測(cè)試07.xlsx" ); //輸出工作簿 workbook.write(fileOutputStream); //關(guān)閉流 fileOutputStream.close(); System.out.println( "用戶測(cè)試07.xls生成完畢" ); } }
運(yùn)行后發(fā)現(xiàn),會(huì)在項(xiàng)目本地生成我們定義的excel,打開(kāi)查看
03版和07版的區(qū)別如下:
1 03版本有最大長(zhǎng)度現(xiàn)在 07版本沒(méi)有
2 03版本后綴xls 07版本后綴xlsx
3 03版本使用的工具是HSSF,07版本使用的是XSSF
5 大數(shù)據(jù)繞導(dǎo)入導(dǎo)出(批量)
真實(shí)開(kāi)發(fā)中,大多數(shù)就是大數(shù)據(jù)批量導(dǎo)入或者導(dǎo)出excel
大文件寫(xiě)HSSF
缺點(diǎn):最多只能處理65536行,否則會(huì)報(bào)內(nèi)存溢出異常
優(yōu)點(diǎn):過(guò)程中寫(xiě)入緩存,不操作磁盤(pán),最后一次性寫(xiě)入磁盤(pán),速度快
大文件寫(xiě)XSSF
缺點(diǎn):寫(xiě)數(shù)據(jù)時(shí)速度非常慢,非常消耗內(nèi)存,也會(huì)發(fā)生內(nèi)存溢出,比如100萬(wàn)條
優(yōu)點(diǎn):可以寫(xiě)較大的數(shù)據(jù)量,比如20萬(wàn)條
03版本HSSF循環(huán)導(dǎo)入65536行數(shù)據(jù)(03版本最大行就是65536)
03版本HSSF循環(huán)插入65536條
package com.wyh.Test; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import org.junit.Test; import java.io.FileOutputStream; /** * @program: JavaExecl * @description: 大數(shù)據(jù)量寫(xiě)03版本 * @author: 魏一鶴 * @createDate: 2021-12-14 23:31 **/ public class BigDateExcelWrite03 { //全局路徑,供我們操作使用方便 static String path = "D:\Tools\JavaWorkSpace\JavaExecl\" ; @Test public void BigDateExcelWrite03() throws Exception { //開(kāi)始時(shí)間 用于計(jì)算時(shí)間差 long beginTime = System.currentTimeMillis(); //創(chuàng)建工作簿 03版本使用HSSF Workbook workbook = new HSSFWorkbook(); //創(chuàng)建工作表 這里就不給它命令了 按照默認(rèn)的來(lái) Sheet sheet = workbook.createSheet(); //寫(xiě)入數(shù)據(jù) 循環(huán)插入65536行數(shù)據(jù),03版的HSSF最多只能插入65536行 for (int rowNum = 0; rowNum < 65536; rowNum++) { //循環(huán)創(chuàng)建行 Row row = sheet.createRow(rowNum); for(int cellNum=0;cellNum<10;cellNum++){ //循環(huán)插入列 Cell cell = row.createCell(cellNum); //循環(huán)設(shè)置值 cell.setCellValue(cellNum); } } System.out.println( "生成excel表完畢" ); //03版本的后綴是xls //開(kāi)啟文件流 FileOutputStream fileOutputStream = new FileOutputStream(path + "BigDateExcelWrite03.xlsx" ); //開(kāi)始寫(xiě)excel workbook.write(fileOutputStream); //關(guān)閉流 fileOutputStream.close(); //結(jié)束時(shí)間 long endTime = System.currentTimeMillis(); //輸出花費(fèi)的時(shí)間 System.out.println( "花費(fèi)的時(shí)間:" +(double)(endTime - beginTime)/1000); } }
運(yùn)行發(fā)現(xiàn)excel已經(jīng)創(chuàng)建成功,速度也非常的快
打開(kāi)查看
已知03版本xls最多存65536行,那么如果我們循環(huán)插入65537行會(huì)怎么樣呢? 保留源代碼,循環(huán)最大值設(shè)置為65537
再次運(yùn)行發(fā)現(xiàn)會(huì)報(bào)錯(cuò)
java.lang.IllegalArgumentException: Invalid row number (65536) outside allowable range (0..65535)
07版本XSSF循環(huán)插入65536條
把后綴改為xlsx,把HSSF緩存XSSF即可
package com.wyh.Test; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.junit.Test; import java.io.FileOutputStream; /** * @program: JavaExecl * @description: 大數(shù)據(jù)量寫(xiě)03版本 * @author: 魏一鶴 * @createDate: 2021-12-14 23:31 **/ public class BigDateExcelWrite07 { //全局路徑,供我們操作使用方便 static String path = "D:\Tools\JavaWorkSpace\JavaExecl\" ; @Test public void BigDateExcelWrite07() throws Exception { //開(kāi)始時(shí)間 用于計(jì)算時(shí)間差 long beginTime = System.currentTimeMillis(); //創(chuàng)建工作簿 07版本的使用XSSF Workbook workbook = new XSSFWorkbook(); //創(chuàng)建工作表 這里就不給它命令了 按照默認(rèn)的來(lái) Sheet sheet = workbook.createSheet(); //寫(xiě)入數(shù)據(jù) 循環(huán)插入65536行數(shù)據(jù),03版的HSSF最多只能插入65536行 for (int rowNum = 0; rowNum < 65536; rowNum++) { //循環(huán)創(chuàng)建行 Row row = sheet.createRow(rowNum); for(int cellNum=0;cellNum<10;cellNum++){ //循環(huán)插入列 Cell cell = row.createCell(cellNum); //循環(huán)設(shè)置值 cell.setCellValue(cellNum); } } System.out.println( "生成excel表完畢" ); //037版本的后綴是xlsx //開(kāi)啟文件流 FileOutputStream fileOutputStream = new FileOutputStream(path + "BigDateExcelWrite07.xlsx" ); //開(kāi)始寫(xiě)excel workbook.write(fileOutputStream); //關(guān)閉流 fileOutputStream.close(); //結(jié)束時(shí)間 long endTime = System.currentTimeMillis(); //輸出花費(fèi)的時(shí)間 System.out.println( "花費(fèi)的時(shí)間:" +(double)(endTime - beginTime)/1000); } }
雖然也運(yùn)行成功,但是可以明顯感覺(jué)到速度不如03版HSSF,但是可以存更多的數(shù)據(jù)
打開(kāi)excel查看發(fā)現(xiàn)數(shù)據(jù)到了65536停并沒(méi)有結(jié)束,說(shuō)明07版本XSSF上限不是65536,是可以存儲(chǔ)更多的,可以寫(xiě)更多的數(shù)據(jù)
如果我們正在查看同一個(gè)文件,但是又進(jìn)行其他操作,就會(huì)出現(xiàn)以下錯(cuò)誤,我們把我們正在查看的文件關(guān)閉讓它運(yùn)行,等運(yùn)行結(jié)束后再次打開(kāi)即可
java.io.FileNotFoundException: D:\Tools\JavaWorkSpace\JavaExecl\BigDateExcelWrite07.xlsx (另一個(gè)程序正在使用此文件,進(jìn)程無(wú)法訪問(wèn)。)
07版本XSSF導(dǎo)入100000條數(shù)據(jù),把循環(huán)數(shù)改為100000即可
既然XSSF可以存這么多數(shù)據(jù),但是速度比較慢,有沒(méi)有方法可以優(yōu)化效率呢(緩存,這個(gè)問(wèn)題也可以叫做如何給poi加速
它就是Workbook借口三個(gè)實(shí)現(xiàn)類之一的SXSSFWorkbook,其他的兩個(gè)我們上面都有操作過(guò)
這時(shí)候需要用到我們的SXSSF
優(yōu)點(diǎn):可以寫(xiě)非常大的數(shù)據(jù)量.如100萬(wàn)條甚至更多,寫(xiě)速度非???占用更少的
注意
1 過(guò)程中會(huì)產(chǎn)生臨時(shí)文件,需要清理臨時(shí)文件
2 默認(rèn)由100條記錄被保存在內(nèi)存中,如果超過(guò)這數(shù)量,則最前面的數(shù)據(jù)被寫(xiě)入臨時(shí)文件,當(dāng)然緩存數(shù)量也可以自定義
3 如果自定義內(nèi)存中數(shù)據(jù)的數(shù)量,可以使用new SXSSFWorkbook(數(shù)量)
SXSSF循環(huán)插入100000條數(shù)據(jù)
package com.wyh.Test; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.xssf.streaming.SXSSFWorkbook; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.junit.Test; import java.io.FileOutputStream; /** * @program: JavaExecl * @description: 大數(shù)據(jù)量寫(xiě)03版本 * @author: 魏一鶴 * @createDate: 2021-12-14 23:31 **/ public class BigDateExcelWrite07Super { //全局路徑,供我們操作使用方便 static String path = "D:\Tools\JavaWorkSpace\JavaExecl\" ; @Test public void BigDateExcelWrite07Super() throws Exception { //開(kāi)始時(shí)間 用于計(jì)算時(shí)間差 long beginTime = System.currentTimeMillis(); //創(chuàng)建工作簿 07版本的使用XSSF Workbook workbook = new SXSSFWorkbook(); //創(chuàng)建工作表 這里就不給它命令了 按照默認(rèn)的來(lái) Sheet sheet = workbook.createSheet(); //寫(xiě)入數(shù)據(jù) 循環(huán)插入65536行數(shù)據(jù),03版的HSSF最多只能插入65536行 for (int rowNum = 0; rowNum < 100000; rowNum++) { //循環(huán)創(chuàng)建行 Row row = sheet.createRow(rowNum); for(int cellNum=0;cellNum<10;cellNum++){ //循環(huán)插入列 Cell cell = row.createCell(cellNum); //循環(huán)設(shè)置值 cell.setCellValue(cellNum); } } System.out.println( "生成excel表完畢" ); //037版本的后綴是xlsx //開(kāi)啟文件流 FileOutputStream fileOutputStream = new FileOutputStream(path + "BigDateExcelWrite07Super.xlsx" ); //開(kāi)始寫(xiě)excel workbook.write(fileOutputStream); //關(guān)閉流 fileOutputStream.close(); //由于SXSSF會(huì)產(chǎn)生臨時(shí)文件,這里我們需要清除下臨時(shí)文件 ((SXSSFWorkbook) workbook).dispose(); //結(jié)束時(shí)間 long endTime = System.currentTimeMillis(); //輸出花費(fèi)的時(shí)間 System.out.println( "花費(fèi)的時(shí)間:" +(double)(endTime - beginTime)/1000); } }
運(yùn)行發(fā)現(xiàn),excel也正常生成了,但是它(SXSSF)的速度比XSSF快的多
查看我們的super
這就是我們的臨時(shí)文件,隨著我們把文件的關(guān)閉,臨時(shí)文件也會(huì)隨之消失
以上就是Java使用poi實(shí)現(xiàn)excel的導(dǎo)入操作指南的詳細(xì)內(nèi)容,更多關(guān)于Java poi excel導(dǎo)入的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Java基礎(chǔ)知識(shí)精通注釋與數(shù)據(jù)類型及常量與變量
本文給大家介紹了Java的注釋與數(shù)據(jù)類型和常量變量,這些都是最基礎(chǔ)的知識(shí),文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-04-04Java注冊(cè)郵箱激活驗(yàn)證實(shí)現(xiàn)代碼
這篇文章主要介紹了Java注冊(cè)郵箱激活驗(yàn)證實(shí)現(xiàn)代碼,有需要的朋友可以參考一下2013-12-12解決RabbitMq消息隊(duì)列Qos?Prefetch消息堵塞問(wèn)題
這篇文章主要為大家介紹了關(guān)于如何解決解決RabbitMq?Qos?Prefetch消息堵塞的問(wèn)題分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助2022-01-01教你怎么用java一鍵自動(dòng)生成數(shù)據(jù)庫(kù)文檔
最近小編也在找這樣的插件,就是不想寫(xiě)文檔了,浪費(fèi)時(shí)間和心情啊,果然我找到一款比較好用,操作簡(jiǎn)單不復(fù)雜.screw 是一個(gè)簡(jiǎn)潔好用的數(shù)據(jù)庫(kù)表結(jié)構(gòu)文檔的生成工具,支持 MySQL、Oracle、PostgreSQL 等主流的關(guān)系數(shù)據(jù)庫(kù).需要的朋友可以參考下2021-05-05關(guān)于Selenium的UI自動(dòng)化測(cè)試屏幕截圖功能實(shí)例代碼
今天小編就為大家分享一篇關(guān)于Selenium的UI自動(dòng)化測(cè)試屏幕截圖功能實(shí)例代碼,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-05-05Java Speech API實(shí)現(xiàn)語(yǔ)音識(shí)別
Java語(yǔ)音識(shí)別是一項(xiàng)非常有用的功能,它可以將語(yǔ)音轉(zhuǎn)換為文本,從而實(shí)現(xiàn)語(yǔ)音輸入和語(yǔ)音控制功能,在當(dāng)今數(shù)字化時(shí)代,語(yǔ)音識(shí)別技術(shù)逐漸成為人機(jī)交互的重要方式之一,語(yǔ)音識(shí)別技術(shù)可以幫助我們將語(yǔ)音數(shù)據(jù)轉(zhuǎn)化為文字,進(jìn)而進(jìn)行后續(xù)的處理和分析2023-10-10