Apache POI中HSSFWorkbook、XSSFWorkbook、SXSSFWorkbook的區(qū)別解析
一、前言
在java項目中,我們經(jīng)常使用Apache POI的包導出Excel文件,但是在創(chuàng)建Workbook的時候,有三種選型HSSFWorkbook、XSSFWorkbook、SXSSFWorkbook可以選擇,本文總結一下這三個實現(xiàn)類的區(qū)別。
二、Workbook的三個實現(xiàn)類
在Apache POI中,Workbook接口 代表一個Excel工作簿(即一個Excel文件)。針對不同版本的Excel文件,POI提供了三個主要的實現(xiàn)類:
| 實現(xiàn)類 | 支持的文件格式 | 對應Excel版本 | 文件擴展名 |
|---|---|---|---|
| HSSFWorkbook | HSSF (Horrible SpreadSheet Format) | Excel 97-2003 | .xls |
| XSSFWorkbook | XSSF (XML SpreadSheet Format) | Excel 2007+ | .xlsx |
| SXSSFWorkbook | 基于XSSF的流式擴展 | Excel 2007+ | .xlsx |
SXSSFWorkbook
- 也是用于.xlsx格式,但它主要用于處理非常大的電子表格文件,通過在內(nèi)存中僅保留一定數(shù)量的行來優(yōu)化性能。
- SXSSFWorkbook非常適合用于生成非常大的電子表格文件,因為它可以減少內(nèi)存使用。
三個類的API設計高度一致,切換起來非常方便:
import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.apache.poi.xssf.streaming.SXSSFWorkbook; // 使用HSSFWorkbook創(chuàng)建.xls文件 Workbook workbook = new HSSFWorkbook(); // 使用XSSFWorkbook創(chuàng)建.xlsx文件 Workbook workbook = new XSSFWorkbook(); // 使用SXSSFWorkbook創(chuàng)建.xlsx文件(低內(nèi)存模式) Workbook workbook = new SXSSFWorkbook();
三、三個實現(xiàn)類的核心區(qū)別
3.1、HSSFWorkbook:老兵不死,但已逐漸凋零
HSSFWorkbook是POI中最古老的實現(xiàn),對應的是Excel 97-2003版本的二進制格式(.xls)。
主要特點:
- 行數(shù)限制:每個Sheet最多支持65535行,超過會報錯
- 列數(shù)限制:最多支持256列
- 內(nèi)存模型:
所有數(shù)據(jù)全部加載到內(nèi)存中 - 性能表現(xiàn):由于是二進制格式,處理速度反而是三個中最快的
適用場景:
- 需要兼容老舊系統(tǒng),必須輸出.xls格式
- 數(shù)據(jù)量很小(< 6.5萬行)
- 對性能要求極高且數(shù)據(jù)量可控
3.2、XSSFWorkbook:現(xiàn)代辦公的主力軍
隨著Excel 2007推出新的OpenXML格式(.xlsx),POI推出了XSSFWorkbook來支持這種基于XML的新格式。
主要特點:
- 行數(shù)限制:每個Sheet最多支持1048576行(約104萬行)
- 列數(shù)限制:最多支持16384列
- 內(nèi)存模型:
所有數(shù)據(jù)全部加載到內(nèi)存中,內(nèi)存占用是HSSFWorkbook的2-7倍 - 性能表現(xiàn):由于XML解析的開銷,處理速度最慢,比HSSFWorkbook慢約30倍
適用場景:
- 需要輸出.xlsx格式
- 數(shù)據(jù)量中等(幾十萬行以內(nèi))
- 內(nèi)存充足,且需要使用完整的Excel功能(樣式、公式、圖表等)
3.3、SXSSFWorkbook:大數(shù)據(jù)處理的救星
從POI 3.8版本開始,推出了基于XSSF的流式實現(xiàn)SXSSFWorkbook,專門為了解決大數(shù)據(jù)量導出時的內(nèi)存溢出問題。
主要特點:
- 行數(shù)限制:與XSSFWorkbook相同,支持百萬行級別
- 內(nèi)存模型:流式處理,
默認只在內(nèi)存中保留100行,超出的行會刷新到磁盤臨時文件中 - 性能表現(xiàn):介于HSSF和XSSF之間,但內(nèi)存占用穩(wěn)定,幾乎不隨數(shù)據(jù)量增長
功能限制(重要?。?/strong>
由于數(shù)據(jù)被刷新到磁盤,以下功能無法使用:
autoSizeColumn()- 自動調(diào)整列寬cloneSheet()- 克隆工作表- 對已刷新行的隨機訪問(
getRow()可能返回null) - 公式求值(涉及已刷新行的公式)
shiftColumns()- 列位移操作
適用場景:
- 百萬級數(shù)據(jù)導出
- 內(nèi)存受限的環(huán)境
- 不需要上述受限功能(或可以在導出完成后處理)
四、性能數(shù)據(jù)說話
口說無憑,我們來看一組權威的性能測試數(shù)據(jù)(來自Baeldung的JMH基準測試):
執(zhí)行時間對比(單位:毫秒)
| 行數(shù) | HSSFWorkbook | XSSFWorkbook | SXSSFWorkbook |
|---|---|---|---|
| 2,500 | 73 | 2,658 | 296 |
| 10,000 | 347 | 10,994 | 1,808 |
| 20,000 | 754 | 21,733 | 3,751 |
| 40,000 | 1,455 | 42,331 | 7,342 |
內(nèi)存消耗對比(單位:MB)
| 行數(shù) | HSSFWorkbook | XSSFWorkbook | SXSSFWorkbook |
|---|---|---|---|
| 2,500 | 828 | 1,871 | 258 |
| 10,000 | 1,268 | 4,136 | 209 |
| 20,000 | 1,766 | 7,443 | 209 |
| 40,000 | 1,475 | 10,119 | 210 |
從數(shù)據(jù)中可以清晰看到:
- XSSFWorkbook是典型的"內(nèi)存殺手",40k行數(shù)據(jù)消耗高達10GB內(nèi)存
- SXSSFWorkbook的內(nèi)存占用穩(wěn)定在210MB左右,優(yōu)勢極其明顯
- HSSFWorkbook雖然速度快,但受限于行數(shù)上限,無法處理大規(guī)模數(shù)據(jù)
五、實際開發(fā)中的選型建議
5.1、決策樹:三步選對Workbook
開始選型
↓
是否需要輸出.xls格式?
├─ 是 → 數(shù)據(jù)量<6.5萬行? → 是 → HSSFWorkbook
│ → 否 → 無法滿足,考慮分批導出或升級格式
↓
是否需要完整的Excel功能(樣式、公式、圖表等)?
├─ 是 → 數(shù)據(jù)量<10萬行且內(nèi)存充足? → 是 → XSSFWorkbook
│ → 否 → 考慮分批寫入+ XSSFWorkbook
↓
是否需要處理超大數(shù)據(jù)量(>10萬行)?
├─ 是 → 能否接受功能限制? → 是 → SXSSFWorkbook
│ → 否 → 考慮EasyExcel或分批導出
↓
默認選擇 → XSSFWorkbook(常規(guī)場景)5.2、實戰(zhàn)經(jīng)驗分享
場景1:常規(guī)報表導出(幾千到幾萬行)
// 推薦使用XSSFWorkbook,功能完整,開發(fā)簡單
try (Workbook workbook = new XSSFWorkbook()) {
// 正常的樣式、公式處理
}場景2:百萬級數(shù)據(jù)導出,無需復雜樣式
// SXSSFWorkbook是最佳選擇
SXSSFWorkbook workbook = new SXSSFWorkbook(100); // 設置內(nèi)存窗口大小為100
try {
// 分批寫入數(shù)據(jù)
for (...) {
Row row = sheet.createRow(...);
// 填充數(shù)據(jù)
}
} finally {
// 務必清理臨時文件
workbook.dispose();
workbook.close();
}場景3:需要復雜樣式,但數(shù)據(jù)量也大
這種情況下可以采取折中方案:
- 使用XSSFWorkbook創(chuàng)建模板,設置好所有樣式
- 使用SXSSFWorkbook基于模板填充數(shù)據(jù)
- 或者使用EasyExcel等封裝庫
六、SXSSFWorkbook使用注意事項
如果選擇了SXSSFWorkbook,有幾個坑需要特別注意:
6.1、及時清理臨時文件
SXSSFWorkbook workbook = new SXSSFWorkbook();
try {
// 處理數(shù)據(jù)...
} finally {
workbook.dispose(); // 刪除臨時文件
workbook.close();
}6.2、避免使用受限功能
// 以下代碼會拋出異常 sheet.autoSizeColumn(0); // IllegalStateException workbook.cloneSheet(0); // IllegalStateException
6.3、合理設置窗口大小
// 窗口大小設置原則: // - 越小,內(nèi)存占用越低,但功能限制影響越大 // - 越大,可用功能越多,但內(nèi)存占用越高 SXSSFWorkbook workbook = new SXSSFWorkbook(500); // 根據(jù)實際需求調(diào)整
七、結語
Apache POI的三個Workbook實現(xiàn)類各有千秋,沒有絕對的"最好",只有最適合你當前場景的選擇。簡單總結一下:
- HSSFWorkbook:老當益壯,但已是過去式
- XSSFWorkbook:中規(guī)中矩,日常開發(fā)主力
- SXSSFWorkbook:黑馬選手,大數(shù)據(jù)場景必備
在實際項目中,建議根據(jù)數(shù)據(jù)量、功能需求、內(nèi)存限制這三個維度綜合評估。如果數(shù)據(jù)量真的到了百萬級別,且功能需求復雜,也可以考慮阿里開源的EasyExcel,它在POI基礎上做了進一步的封裝和優(yōu)化,同樣值得關注。
希望這篇文章能幫你徹底搞懂POI的Workbook家族,從此不再為Excel導出發(fā)愁!
到此這篇關于Apache POI中HSSFWorkbook、XSSFWorkbook、SXSSFWorkbook的區(qū)別解析的文章就介紹到這了,更多相關apache poi詳解內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
- Java使用Apache POI和EasyExcel讀取Excel文件的實現(xiàn)方案
- 使用Java和Apache POI實現(xiàn)HTML轉Word的完整指南
- Java利用Apache POI實現(xiàn)多模板Word文檔生成的示例代碼
- SpringMVC框架使用 Apache POI實現(xiàn)導出Excel
- 使用Apache POI在Java中實現(xiàn)Excel單元格的合并
- 使用 Apache POI 在 Java 中寫入 Excel 文件的方法
- 使用Apache?POI和SpringBoot實現(xiàn)Excel文件上傳和解析功能
- SpringBoot使用Apache POI庫讀取Excel文件的操作詳解
- Java使用Apache.POI中HSSFWorkbook導出到Excel的實現(xiàn)方法
相關文章
centos7下搭建ZooKeeper3.4中間件常用命令小結
Zookeeper 作為一個分布式的服務框架,主要用來解決分布式集群中應用系統(tǒng)的一致性問題,它能提供基于類似于文件系統(tǒng)的目錄節(jié)點樹方式的數(shù)據(jù)存儲。這篇文章主要介紹了centos7下搭建ZooKeeper3.4中間件常用命令小結,需要的朋友可以參考下2019-07-07

