首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Apache POI 操作 Excel 完整指南:03/07 版本讀寫、樣式、合併單元格、流式處理大數據

     編輯:Java 綜合教學

Apache POI 操作 Excel 完整指南:03/07 版本讀寫、樣式、合併單元格、流式處理大數據

POI 是 Java 操作 Office 文檔的標準庫,支援 Excel 97-2003 (.xls, HSSF) 和 Excel 2007+ (.xlsx, XSSF)。本文覆蓋基礎讀寫、樣式設置、合併單元格、統一接口讀取、大數據流式處理(SXSSF)。

核心概念

  • Workbook:工作簿(整個 Excel 文件)
  • Sheet:工作表(一個 Sheet)
  • Row:行
  • Cell:單元格(列+行交叉)

依賴坐標

<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>5.2.3</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>5.2.3</version>
</dependency>
<!-- 可選:SXSSF 大數據流式寫入 -->

1. 寫入 .xls (HSSF - Excel 97-2003)

public void writeXls() throws IOException {
    HSSFWorkbook wb = new HSSFWorkbook();
    HSSFSheet sheet = wb.createSheet("Sheet1");
    HSSFRow row = sheet.createRow(2);      // 第3行 (0-based)
    HSSFCell cell = row.createCell(2);     // 第3列
    cell.setCellValue("Hello World");
    
    try (FileOutputStream fos = new FileOutputStream("test.xls")) {
        wb.write(fos);
    }
    wb.close();
}

2. 寫入 .xlsx (XSSF - Excel 2007+)

public void writeXlsx() throws IOException {
    XSSFWorkbook wb = new XSSFWorkbook();
    XSSFSheet sheet = wb.createSheet("Sheet1");
    XSSFRow row = sheet.createRow(2);
    XSSFCell cell = row.createCell(2);
    cell.setCellValue("Hello World");
    
    try (FileOutputStream fos = new FileOutputStream("test.xlsx")) {
        wb.write(fos);
    }
    wb.close();
}

3. 統一接口讀取(自動識別版本)

public void readExcel(String filePath) throws IOException {
    try (FileInputStream fis = new FileInputStream(filePath);
         Workbook wb = WorkbookFactory.create(fis)) {  // 自動識別 .xls/.xlsx
        
        Sheet sheet = wb.getSheetAt(0);
        Row row = sheet.getRow(2);
        Cell cell = row.getCell(2);
        String value = cell.getStringCellValue();
        System.out.println("值: " + value);
    }
}

關鍵:WorkbookFactory.create() 自動識別格式,返回統一 Workbook 接口,後續操作無需區分版本。

4. 樣式設置實戰

public void writeWithStyle() throws IOException {
    HSSFWorkbook wb = new HSSFWorkbook();
    HSSFSheet sheet = wb.createSheet("Styled");
    
    // 單元格樣式
    HSSFCellStyle style = wb.createCellStyle();
    style.setAlignment(HSSFCellStyle.ALIGN_CENTER);      // 水平居中
    style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER); // 垂直居中
    
    // 字體
    HSSFFont font = wb.createFont();
    font.setFontHeightInPoints((short) 16);
    font.setColor(HSSFFont.COLOR_RED);
    font.setBold(true);
    style.setFont(font);
    
    // 背景色(需設置前景色+填充模式)
    style.setFillForegroundColor(HSSFColor.HSSFColorPredefined.BLUE_GREY.getIndex());
    style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
    
    // 合併單元格:行2-2,列2-3
    CellRangeAddress region = new CellRangeAddress(2, 2, 2, 3);
    sheet.addMergedRegion(region);
    
    // 列寬/行高
    sheet.setColumnWidth(2, 12000);
    // sheet.setDefaultRowHeightInPoints(30);
    
    HSSFRow row = sheet.createRow(2);
    HSSFCell cell = row.createCell(2);
    cell.setCellValue("Styled Cell");
    cell.setCellStyle(style);
    
    try (FileOutputStream fos = new FileOutputStream("styled.xls")) {
        wb.write(fos);
    }
    wb.close();
}

POI操作示意

5. 讀取數據類型處理

public Object getCellValue(Cell cell) {
    if (cell == null) return null;
    switch (cell.getCellType()) {
        case STRING: return cell.getStringCellValue();
        case NUMERIC:
            if (DateUtil.isCellDateFormatted(cell)) return cell.getDateCellValue();
            return cell.getNumericCellValue();
        case BOOLEAN: return cell.getBooleanCellValue();
        case FORMULA: return cell.getCellFormula();
        default: return null;
    }
}

6. 大數據導出:SXSSF 流式寫入(低內存)

public void writeBigData() throws IOException {
    // 保留最近 100 行在內存,其餘刷入磁盤臨時文件
    SXSSFWorkbook wb = new SXSSFWorkbook(100);  
    SXSSFSheet sheet = wb.createSheet("BigData");
    
    for (int i = 0; i < 100000; i++) {
        Row row = sheet.createRow(i);
        row.createCell(0).setCellValue("Row " + i);
        row.createCell(1).setCellValue(Math.random());
        if (i % 1000 == 0) {
            // 定期 flush 釋放內存
            // wb.getPackage().getParts()... 實際由 SXSSF 自動管理
        }
    }
    
    try (FileOutputStream fos = new FileOutputStream("big.xlsx")) {
        wb.write(fos);
    }
    wb.dispose();  // 刪除臨時文件,必須調用
    wb.close();
}

7. 常見坑與最佳實踐

  • 數字格式:Excel 數字默認 General,導出金額/日期需設置 DataFormat
  • 中文亂碼:確保字體支持中文(如微軟雅黑),font.setFontName("Microsoft YaHei")
  • 日期類型:用 DateUtil.isCellDateFormatted() 判斷,cell.getDateCellValue() 讀取
  • 公式計算:FormulaEvaluator evaluator = wb.getCreationHelper().createFormulaEvaluator();
  • 資源關閉:Workbook 實現 Closeable,用 try-with-resources
  • SXSSF 臨時文件:wb.dispose() 清理,否則殘留大量臨時文件

總結

POI 核心模式:Workbook → Sheet → Row → Cell。統一接口 WorkbookFactory 屏蔽版本差異,樣式/合併/列寬屬於 Sheet/Workbook 級別。大數據場景必用 SXSSF,配合 dispose() 清理。導入導出功能建議封裝通用工具類,支援模板導出、註解驅動映射。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved