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

C# 讀取 Excel 必備技能:Aspose.Cells 核心操作與資料匯入實戰

     編輯:關於C語言

在企業級應用中,Excel 仍是資料交換最通用的格式。Aspose.Cells 作為無需安裝 Office、支援 .xls/.xlsx/.csv/.ods 全格式的純 .NET 元件,是伺服器端匯入匯出的首選。本文聚焦「讀取資料並轉為 DataTable/DataSet」的高頻場景,提供生產可用的最佳實踐。

環境準備

// NuGet 安裝
Install-Package Aspose.Cells

// 命名空間
using Aspose.Cells;
using System.Data;

核心類別速覽

類別職責
Workbook代表整個 Excel 檔案,入口點
Worksheet單一工作表
Cells儲存格集合,提供索引器、區域操作、匯出功能
Cell單一儲存格,含 Value, StringValue, Type, Style

場景一:逐列逐欄精細讀取 (適合複雜驗證/轉換)

public IEnumerable<Dictionary<string, object>> ReadExcelRowByRow(string filePath, int sheetIndex = 0, bool hasHeader = true)
{
    var workbook = new Workbook(filePath);
    var sheet = workbook.Worksheets[sheetIndex];
    var cells = sheet.Cells;

    int startRow = hasHeader ? cells.FirstRow + 1 : cells.FirstRow;
    int endRow = cells.MaxDataRow;
    int startCol = cells.FirstColumn;
    int endCol = cells.MaxDataColumn;

    // 取得標題列
    var headers = new List<string>();
    if (hasHeader)
    {
        for (int c = startCol; c <= endCol; c++)
            headers.Add(cells[cells.FirstRow, c].StringValue.Trim());
    }

    for (int r = startRow; r <= endRow; r++)
    {
        var rowDict = new Dictionary<string, object>();
        bool allNull = true;

        for (int c = startCol; c <= endCol; c++)
        {
            var cell = cells[r, c];
            object val = cell.Type == CellValueType.IsNull ? null : cell.Value;
            string key = hasHeader && c < headers.Count ? headers[c] : $"Col{c}";
            rowDict[key] = val;
            if (val != null) allNull = false;
        }

        if (!allNull) yield return rowDict; // 跳過全空列
    }
}

場景二:一鍵匯出 DataTable (效能最佳、程式碼最少)

public DataTable ExportToDataTable(string filePath, int sheetIndex = 0, bool firstRowAsHeader = true)
{
    var workbook = new Workbook(filePath);
    var cells = workbook.Worksheets[sheetIndex].Cells;

    // ExportDataTable 參數:startRow, startCol, totalRows, totalCols, exportColumnName
    // firstRowAsHeader=true 時:第 0 列當欄位名,資料從第 1 列開始
    // firstRowAsHeader=false 時:第 0 列也是資料,欄位名自動產生 Column0, Column1...
    int totalRows = cells.MaxDataRow + 1; // MaxDataRow 是 0-based 索引
    int totalCols = cells.MaxDataColumn + 1;

    var options = new ExportTableOptions
    {
        ExportColumnName = firstRowAsHeader,
        CheckMergedCells = true,        // 合併儲存格自動填充
        PlotVisibleRowsOnly = false,    // 包含隱藏列
        ExportAsString = false          // 保留原始型別 (DateTime, double, bool)
    };

    return cells.ExportDataTable(0, 0, totalRows, totalCols, options);
}

ExportTableOptions 關鍵屬性

  • ExportColumnName:第一列是否為標題
  • CheckMergedCells:合併儲存格值複製到每個子儲存格
  • ExportAsString:false 保強型別 (推薦),true 全轉字串
  • FormatStrategy:CellValueFormatStrategy.DisplayString 可套用儲存格格式 (如貨幣、百分比)

場景三:大檔案串流式讀取 (低記憶體佔用)

針對 10MB+ 或 10萬列以上檔案,避免一次載入整個 Workbook:

public IEnumerable<DataRow> StreamReadLargeExcel(string filePath, int sheetIndex = 0)
{
    var loadOptions = new LoadOptions(LoadFormat.Xlsx)
    {
        MemorySetting = MemorySetting.MemoryPreference, // 優先使用記憶體,不足則磁碟
        ParsingFormulaOnOpen = false,                   // 不解析公式加速
        OnlyLoadDocumentProperties = false
    };

    using (var workbook = new Workbook(filePath, loadOptions))
    {
        var sheet = workbook.Worksheets[sheetIndex];
        var cells = sheet.Cells;

        // 建立 DataTable 結構
        var dt = new DataTable();
        for (int c = cells.FirstColumn; c <= cells.MaxDataColumn; c++)
            dt.Columns.Add(cells[0, c].StringValue); // 假設第一列為標題

        // 使用 LightCells API 事件驅動逐列讀取 (Aspose.Cells 進階功能)
        // 此處簡化示範:仍用 Cells 但分批處理
        const int batchSize = 1000;
        for (int r = 1; r <= cells.MaxDataRow; r += batchSize)
        {
            int end = Math.Min(r + batchSize - 1, cells.MaxDataRow);
            for (int i = r; i <= end; i++)
            {
                var row = dt.NewRow();
                for (int c = cells.FirstColumn; c <= cells.MaxDataColumn; c++)
                    row[c] = cells[i, c].Value;
                dt.Rows.Add(row);
                yield return row;
            }
            // 可選:釋放已處理區塊記憶體 (需 LightCells 完整實作)
        }
    }
}

常見資料型別處理對照表

Excel 儲存格Cell.Value 型別建議轉換
數值 (含日期)double / DateTimecell.Type == CellValueType.IsNumeric ? DateTime.FromOADate(val) : val
布林bool直接使用
文字stringcell.StringValue (保留前導零)
錯誤值 (#N/A)stringcell.Value.ToString().StartsWith("#") 判斷
公式string (公式文本) / 計算後值workbook.CalculateFormula() 後取 cell.Value

授權與部署提醒

  1. 授權檔:new License().SetLicense("Aspose.Total.lic") 放在程式啟動時執行一次,否則產出檔案會有評浮水印
  2. 無相依性:部署只需複製 Aspose.Cells.dll,目標機器無需安裝 Excel
  3. .NET Core / 5+ 相容:完整支援跨平台 (Linux Docker 容器同樣適用)

替代方案快速比較

方案優點缺點適用場景
Aspose.Cells功能最全、效能強、無 Office 相依、商業支援收費 (較貴)企業級專案、複雜報表、伺服器端批次處理
EPPlus開源免費 (v5 起 Polyform Noncommercial)、API 直覺僅支援 .xlsx、大檔案記憶體壓力大中小專案、預算有限、.xlsx 為主
NPOI免費、支援 .xls/.xlsx、HSSF/XSSF 雙引擎API 較底層、效能較慢、文件較少需相容舊 .xls、無授權預算
ClosedXML語法優雅、LINQ 風格、開源僅 .xlsx、大檔案表現一般快速開發、程式碼可讀性優先

掌握 Workbook → Worksheet → Cells → ExportDataTable 這條黃金路徑,配合 ExportTableOptions 微調匯出行為,即能以最少程式碼穩健解決 90% 的 Excel 匯入需求。若專案涉及超大檔案或高併發,再引入 LightCells 事件流或評估 EPPlus/NPOI 開源替代方案。

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