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

Java Apache POI 讀取 Excel (.xls) 完整範例:支援多儲存格型別與日期格式化

     編輯:Java 相關知識

Apache POI 是 Java 操作 Microsoft Office 文件的標準庫。本文示範使用 HSSF 元件讀取舊版 .xls (BIFF8) 格式,完整處理字串、數值、日期、公式、布林、空白、錯誤等七種儲存格型別,並正確格式化輸出。

Maven 相依性

<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>5.3.0</version> <!-- 請使用最新版 -->
</dependency>

完整讀取程式碼

import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import java.io.*;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

public class ExcelReader {
    public static void readExcel(String filePath) throws IOException {
        try (FileInputStream fis = new FileInputStream(filePath);
             POIFSFileSystem fs = new POIFSFileSystem(fis);
             HSSFWorkbook wb = new HSSFWorkbook(fs)) {

            HSSFSheet sheet = wb.getSheetAt(0);
            for (int rowIdx = 0; rowIdx <= sheet.getLastRowNum(); rowIdx++) {
                HSSFRow row = sheet.getRow(rowIdx);
                if (row == null) continue; // 空白列

                for (short colIdx = 0; colIdx < row.getLastCellNum(); colIdx++) {
                    HSSFCell cell = row.getCell(colIdx);
                    String value = parseCell(cell);
                    System.out.println(rowIdx + "," + colIdx + ":" + value);
                }
            }
        }
    }

    private static String parseCell(HSSFCell cell) {
        if (cell == null) return "";
        // 關鍵:設定編碼避免中文亂碼 (HSSF 專用)
        cell.setEncoding(HSSFCell.ENCODING_UTF_16);

        switch (cell.getCellType()) {
            case HSSFCell.CELL_TYPE_STRING:
                return cell.getStringCellValue();

            case HSSFCell.CELL_TYPE_NUMERIC:
                if (HSSFDateUtil.isCellDateFormatted(cell)) {
                    Date date = cell.getDateCellValue();
                    return (date != null) ? new SimpleDateFormat("yyyy-MM-dd").format(date) : "";
                } else {
                    // 避免科學記號,去除小數點後無意義的 0
                    return new DecimalFormat("0.######").format(cell.getNumericCellValue());
                }

            case HSSFCell.CELL_TYPE_FORMULA:
                // 公式儲存格可能有快取值或字串形式
                try {
                    String strVal = cell.getStringCellValue();
                    return strVal.isEmpty() ? String.valueOf(cell.getNumericCellValue()) : strVal;
                } catch (IllegalStateException e) {
                    return String.valueOf(cell.getNumericCellValue());
                }

            case HSSFCell.CELL_TYPE_BOOLEAN:
                return cell.getBooleanCellValue() ? "Y" : "N";

            case HSSFCell.CELL_TYPE_ERROR:
                return "ERROR:" + cell.getErrorCellValue();

            case HSSFCell.CELL_TYPE_BLANK:
            default:
                return "";
        }
    }

    public static void main(String[] args) throws IOException {
        readExcel("F:/1.xls");
    }
}

關鍵技術點解析

項目說明
cell.setEncoding(ENCODING_UTF_16)HSSF (.xls) 必須設定,否則中文會亂碼;XSSF (.xlsx) 不需要
HSSFDateUtil.isCellDateFormatted()判斷數值儲存格是否為日期格式(Excel 內部以數值儲存日期)
DecimalFormat("0.######")避免 1.0 輸出為 1,保留必要小數位
公式儲存格處理可能無快取值,需同時嘗試 getStringCellValue 與 getNumericCellValue
空白列/儲存格getRow 可能回傳 null,getCell 回傳 null 或型別為 BLANK

進階:支援 .xlsx (XSSF)

若需同時支援 .xls 與 .xlsx,建議使用 WorkbookFactory.create(inputStream) 自動偵測:

try (Workbook wb = WorkbookFactory.create(new FileInputStream(file))) {
    // 後續程式碼相同,介面為統一的 Workbook/Sheet/Row/Cell
}

效能與記憶體提示

  • 大檔案:.xls 受限於 65,535 列,.xlsx 支援 100 萬列。超大檔案建議使用 SXSSF (串流式寫入) 或 XSSF 的 EventModel (SAX 模式讀取)。
  • 記憶體:POI 預設將整份試算表載入記憶體,大檔案易造成 OOM。
  • 關閉資源:務必使用 try-with-resources 確保 Workbook.close() 被呼叫,釋放臨時檔案。

此範例涵蓋 .xls 讀取的完整型別處理邏輯,可直接整合至資料匯入、報表產生等實務專案中。

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