使用 IRONXL 如何使用 C# 在 Excel 中建立資料透視表,而不需要依賴 Office? Curtis Chau 更新:2026年1月5日 下載 IronXL NuGet 下載 DLL 下載 開始免費試用 法學碩士副本 法學碩士副本 將頁面複製為 Markdown 格式,用於 LLMs 在 ChatGPT 中打開 請向 ChatGPT 諮詢此頁面 在雙子座打開 請向 Gemini 詢問此頁面 在 Grok 中打開 向 Grok 詢問此頁面 打開困惑 向 Perplexity 詢問有關此頁面的信息 分享 在 Facebook 上分享 分享到 X(Twitter) 在 LinkedIn 上分享 複製連結 電子郵件文章 傳統上,在 C# 中以程式設計方式建立資料透視表需要 Office Interop 和複雜的 COM 管理,但像IronXL這樣的現代庫無需安裝 Office 即可產生跨平台資料透視表,支援 Docker 容器和雲端部署,同時消除記憶體洩漏。 以程式設計方式產生資料透視表需要使用 C# Interop 及其 Office 依賴項,或使用像IronXL這樣可以獨立工作的現代函式庫。 本教學示範了這兩種方法,重點介紹了為什麼開發人員越來越多地選擇IronXL 的容器友善解決方案而不是傳統方法。 在本文中,我們將學習如何編輯、建立、設計和計算具有自動分析和錯誤處理功能的透視表。 無論您是部署到 AWS還是在 Azure 上執行,本指南都涵蓋了 Excel 自動化的現代方法。 什麼是Excel資料透視表? 為什麼資料透視表對資料分析很重要? 資料透視表是 Excel 中最強大的工具之一,可用於匯總大型資料集。 它提供了一種簡單的方法來顯示、理解和分析數值資料。 資料透視表不僅在 Excel 中可用,而且在 Google Sheets、Apple Numbers 和 CSV 匯出中也可用。 它們透過建立與您的底層資訊連結的互動式摘要,將原始資料轉化為有意義的見解。 對於在 C# 中使用 Excel 公式的開發人員來說,資料透視表代表了至關重要的聚合功能。 與只能對單一單元格進行運算的基本數學函數不同,資料透視表可以對整個資料集進行 Excel 函數聚合。 何時應該使用資料透視表,何時應該使用常規報表? 讓我們先來探討一下建立資料透視表的錯誤方法,然後再學習在 C# 中建立資料透視表的正確方法: 如何使用 C# Interop 在 Excel 表格中建立資料透視表? 儘管Interop存在諸多局限性,但為什麼它仍然被使用? C# Excel Interop 透過 COM 自動化提供對 Excel 資料透視表功能的直接存取。 以下是許多開發人員在 C# 中搜尋資料透視表產生方法時遇到的傳統方法:(已棄用) 如何在 .NET 中以傳統方式建立資料透視表 using Excel = Microsoft.Office.Interop.Excel; using System.Runtime.InteropServices; // Create Excel application instance - requires Office installation Excel.Application xlApp = new Excel.Application(); Excel.Workbook xlWorkbook = xlApp.Workbooks.Open(@"C:\Data\SalesData.xlsx"); Excel.Worksheet xlSheet = (Excel.Worksheet)xlWorkbook.Sheets[1]; Excel.Worksheet xlPivotSheet = (Excel.Worksheet)xlWorkbook.Sheets.Add(); // Define data range for pivot table Excel.Range dataRange = xlSheet.UsedRange; // Create pivot cache and pivot table - COM objects require explicit cleanup Excel.PivotCache pivotCache = xlWorkbook.PivotCaches().Create( Excel.XlPivotTableSourceType.xlDatabase, dataRange, Type.Missing); Excel.PivotTable pivotTable = pivotCache.CreatePivotTable( xlPivotSheet.Cells[3, 1], "SalesPivot", Type.Missing, Type.Missing); // Configure pivot table fields - traditional row/column/data setup Excel.PivotField productField = (Excel.PivotField)pivotTable.PivotFields("Product"); productField.Orientation = Excel.XlPivotFieldOrientation.xlRowField; productField.Position = 1; Excel.PivotField regionField = (Excel.PivotField)pivotTable.PivotFields("Region"); regionField.Orientation = Excel.XlPivotFieldOrientation.xlColumnField; regionField.Position = 1; Excel.PivotField salesField = (Excel.PivotField)pivotTable.PivotFields("Sales"); pivotTable.AddDataField(salesField, "Sum of Sales", Excel.XlConsolidationFunction.xlSum); // Save and cleanup - critical for preventing memory leaks xlWorkbook.SaveAs(@"C:\Data\PivotReport.xlsx"); xlWorkbook.Close(); xlApp.Quit(); // Release COM objects to prevent memory leaks - must release in reverse order Marshal.ReleaseComObject(pivotTable); Marshal.ReleaseComObject(pivotCache); Marshal.ReleaseComObject(xlPivotSheet); Marshal.ReleaseComObject(xlSheet); Marshal.ReleaseComObject(xlWorkbook); Marshal.ReleaseComObject(xlApp); using Excel = Microsoft.Office.Interop.Excel; using System.Runtime.InteropServices; // Create Excel application instance - requires Office installation Excel.Application xlApp = new Excel.Application(); Excel.Workbook xlWorkbook = xlApp.Workbooks.Open(@"C:\Data\SalesData.xlsx"); Excel.Worksheet xlSheet = (Excel.Worksheet)xlWorkbook.Sheets[1]; Excel.Worksheet xlPivotSheet = (Excel.Worksheet)xlWorkbook.Sheets.Add(); // Define data range for pivot table Excel.Range dataRange = xlSheet.UsedRange; // Create pivot cache and pivot table - COM objects require explicit cleanup Excel.PivotCache pivotCache = xlWorkbook.PivotCaches().Create( Excel.XlPivotTableSourceType.xlDatabase, dataRange, Type.Missing); Excel.PivotTable pivotTable = pivotCache.CreatePivotTable( xlPivotSheet.Cells[3, 1], "SalesPivot", Type.Missing, Type.Missing); // Configure pivot table fields - traditional row/column/data setup Excel.PivotField productField = (Excel.PivotField)pivotTable.PivotFields("Product"); productField.Orientation = Excel.XlPivotFieldOrientation.xlRowField; productField.Position = 1; Excel.PivotField regionField = (Excel.PivotField)pivotTable.PivotFields("Region"); regionField.Orientation = Excel.XlPivotFieldOrientation.xlColumnField; regionField.Position = 1; Excel.PivotField salesField = (Excel.PivotField)pivotTable.PivotFields("Sales"); pivotTable.AddDataField(salesField, "Sum of Sales", Excel.XlConsolidationFunction.xlSum); // Save and cleanup - critical for preventing memory leaks xlWorkbook.SaveAs(@"C:\Data\PivotReport.xlsx"); xlWorkbook.Close(); xlApp.Quit(); // Release COM objects to prevent memory leaks - must release in reverse order Marshal.ReleaseComObject(pivotTable); Marshal.ReleaseComObject(pivotCache); Marshal.ReleaseComObject(xlPivotSheet); Marshal.ReleaseComObject(xlSheet); Marshal.ReleaseComObject(xlWorkbook); Marshal.ReleaseComObject(xlApp); Imports Excel = Microsoft.Office.Interop.Excel Imports System.Runtime.InteropServices ' Create Excel application instance - requires Office installation Dim xlApp As New Excel.Application() Dim xlWorkbook As Excel.Workbook = xlApp.Workbooks.Open("C:\Data\SalesData.xlsx") Dim xlSheet As Excel.Worksheet = CType(xlWorkbook.Sheets(1), Excel.Worksheet) Dim xlPivotSheet As Excel.Worksheet = CType(xlWorkbook.Sheets.Add(), Excel.Worksheet) ' Define data range for pivot table Dim dataRange As Excel.Range = xlSheet.UsedRange ' Create pivot cache and pivot table - COM objects require explicit cleanup Dim pivotCache As Excel.PivotCache = xlWorkbook.PivotCaches().Create(Excel.XlPivotTableSourceType.xlDatabase, dataRange, Type.Missing) Dim pivotTable As Excel.PivotTable = pivotCache.CreatePivotTable(xlPivotSheet.Cells(3, 1), "SalesPivot", Type.Missing, Type.Missing) ' Configure pivot table fields - traditional row/column/data setup Dim productField As Excel.PivotField = CType(pivotTable.PivotFields("Product"), Excel.PivotField) productField.Orientation = Excel.XlPivotFieldOrientation.xlRowField productField.Position = 1 Dim regionField As Excel.PivotField = CType(pivotTable.PivotFields("Region"), Excel.PivotField) regionField.Orientation = Excel.XlPivotFieldOrientation.xlColumnField regionField.Position = 1 Dim salesField As Excel.PivotField = CType(pivotTable.PivotFields("Sales"), Excel.PivotField) pivotTable.AddDataField(salesField, "Sum of Sales", Excel.XlConsolidationFunction.xlSum) ' Save and cleanup - critical for preventing memory leaks xlWorkbook.SaveAs("C:\Data\PivotReport.xlsx") xlWorkbook.Close() xlApp.Quit() ' Release COM objects to prevent memory leaks - must release in reverse order Marshal.ReleaseComObject(pivotTable) Marshal.ReleaseComObject(pivotCache) Marshal.ReleaseComObject(xlPivotSheet) Marshal.ReleaseComObject(xlSheet) Marshal.ReleaseComObject(xlWorkbook) Marshal.ReleaseComObject(xlApp) $vbLabelText $csharpLabel 此 Interop 範例建立了一個原生 Excel 資料透視表,其中產品為行,地區為列,銷售額匯總在資料區中。 雖然這種方法可行,但需要安裝 Microsoft Office 並進行仔細的 COM 物件管理。 微軟自己的文件現在也不鼓勵在現代開發中使用這種方法。 對於容器化部署,在不使用 Interop 的情況下使用 Excel至關重要。 如果 COM 物件沒有正確釋放會發生什麼情況? C# 互通會帶來哪些問題? 為什麼在容器化環境中互通會失敗? 互通性方法為現代DevOps實務和Docker 設定帶來了幾個重大挑戰: 部署相依性:需要在執行原始碼的每台機器上安裝 Microsoft Office,包括生產伺服器。 這會增加許可成本和部署複雜性。 記憶體管理:必須使用Marshal.ReleaseComObject()明確釋放 COM 物件。 即使缺少一個物件也會導致 Excel 進程在記憶體中掛起, Stack Overflow 上對此有大量記錄。 平台限制詳情:這個老式的解決方案僅適用於安裝了 Office 的 Windows 系統,速度可能非常慢,令使用者感到困惑,並可能導致記憶體洩漏。 不支援 Linux、macOS、Docker 容器或 Azure Functions 等雲端平台。 效能問題:啟動 Excel 應用程式執行個體速度慢且資源消耗大,尤其是伺服器端處理。 版本相容性:不同 Office 版本可能具有不同的 COM 接口,從而導致跨環境的相容性問題。 IronXL 如何在不使用互通的情況下以程式設計方式建立資料透視表? IronXL使用託管程式碼建立資料透視表,沒有 COM 依賴項,其建立方式有所不同。 雖然它不能建立 Excel 原生資料透視表,但它提供了強大的聚合功能。 如何以現代方式透過程式設計建立 XLSX 或 XLS 資料透視表 using IronXL; using System.Linq; using System.Data; // Essential for DataTable manipulation using static System.Data.DataTableExtensions; // Extension methods for LINQ queries class Program { static void Main(string[] args) { // Load Excel file - works on all platforms without Office WorkBook workbook = WorkBook.Load("SalesData.xlsx"); WorkSheet dataSheet = workbook.WorkSheets[0]; // Convert to DataTable for powerful manipulation - maintains data types var dataTable = dataSheet.ToDataTable(true); // true = use first row as column headers // Create pivot-style aggregation using LINQ - no COM objects needed var pivotData = dataTable.AsEnumerable() .GroupBy(row => new { Product = row["Product"].ToString(), Region = row["Region"].ToString() }) // Group by multiple dimensions .Select(g => new { Product = g.Key.Product, Region = g.Key.Region, TotalSales = g.Sum(row => Convert.ToDecimal(row["Sales"])), AverageSale = g.Average(row => Convert.ToDecimal(row["Sales"])), Count = g.Count() }); // Create pivot report worksheet - no Excel process started WorkSheet pivotSheet = workbook.CreateWorkSheet("PivotReport"); // Build cross-tabulation structure programmatically var products = pivotData.Select(p => p.Product).Distinct().OrderBy(p => p); var regions = pivotData.Select(p => p.Region).Distinct().OrderBy(r => r); // Create headers with formatting options pivotSheet["A1"].Value = "Product/Region"; int col = 2; foreach (var region in regions) { pivotSheet[$"{(char)('A' + col - 1)}1"].Value = region; // Dynamic column addressing col++; } // Populate pivot data - memory efficient for large datasets int row = 2; foreach (var product in products) { pivotSheet[$"A{row}"].Value = product; col = 2; foreach (var region in regions) { var sales = pivotData .Where(p => p.Product == product && p.Region == region) .Select(p => p.TotalSales) .FirstOrDefault(); pivotSheet[$"{(char)('A' + col - 1)}{row}"].Value = sales; col++; } row++; } // Add totals using Excel formulas - maintains live calculations pivotSheet[$"A{row}"].Value = "Total"; // Grand totals row for (int c = 2; c <= regions.Count() + 1; c++) { // Formula references ensure dynamic updates pivotSheet[$"{(char)('A' + c - 1)}{row}"].Formula = $"=SUM({(char)('A' + c - 1)}2:{(char)('A' + c - 1)}{row - 1})"; } // Apply professional formatting - currency format for sales data var dataRange = pivotSheet[$"B2:{(char)('A' + regions.Count())}{row}"]; dataRange.FormatString = "$#,##0.00"; // Save without Office dependencies - works in containers workbook.SaveAs("PivotReport.xlsx"); } } using IronXL; using System.Linq; using System.Data; // Essential for DataTable manipulation using static System.Data.DataTableExtensions; // Extension methods for LINQ queries class Program { static void Main(string[] args) { // Load Excel file - works on all platforms without Office WorkBook workbook = WorkBook.Load("SalesData.xlsx"); WorkSheet dataSheet = workbook.WorkSheets[0]; // Convert to DataTable for powerful manipulation - maintains data types var dataTable = dataSheet.ToDataTable(true); // true = use first row as column headers // Create pivot-style aggregation using LINQ - no COM objects needed var pivotData = dataTable.AsEnumerable() .GroupBy(row => new { Product = row["Product"].ToString(), Region = row["Region"].ToString() }) // Group by multiple dimensions .Select(g => new { Product = g.Key.Product, Region = g.Key.Region, TotalSales = g.Sum(row => Convert.ToDecimal(row["Sales"])), AverageSale = g.Average(row => Convert.ToDecimal(row["Sales"])), Count = g.Count() }); // Create pivot report worksheet - no Excel process started WorkSheet pivotSheet = workbook.CreateWorkSheet("PivotReport"); // Build cross-tabulation structure programmatically var products = pivotData.Select(p => p.Product).Distinct().OrderBy(p => p); var regions = pivotData.Select(p => p.Region).Distinct().OrderBy(r => r); // Create headers with formatting options pivotSheet["A1"].Value = "Product/Region"; int col = 2; foreach (var region in regions) { pivotSheet[$"{(char)('A' + col - 1)}1"].Value = region; // Dynamic column addressing col++; } // Populate pivot data - memory efficient for large datasets int row = 2; foreach (var product in products) { pivotSheet[$"A{row}"].Value = product; col = 2; foreach (var region in regions) { var sales = pivotData .Where(p => p.Product == product && p.Region == region) .Select(p => p.TotalSales) .FirstOrDefault(); pivotSheet[$"{(char)('A' + col - 1)}{row}"].Value = sales; col++; } row++; } // Add totals using Excel formulas - maintains live calculations pivotSheet[$"A{row}"].Value = "Total"; // Grand totals row for (int c = 2; c <= regions.Count() + 1; c++) { // Formula references ensure dynamic updates pivotSheet[$"{(char)('A' + c - 1)}{row}"].Formula = $"=SUM({(char)('A' + c - 1)}2:{(char)('A' + c - 1)}{row - 1})"; } // Apply professional formatting - currency format for sales data var dataRange = pivotSheet[$"B2:{(char)('A' + regions.Count())}{row}"]; dataRange.FormatString = "$#,##0.00"; // Save without Office dependencies - works in containers workbook.SaveAs("PivotReport.xlsx"); } } Imports IronXL Imports System.Linq Imports System.Data ' Essential for DataTable manipulation Imports System.Data.DataTableExtensions ' Extension methods for LINQ queries Module Program Sub Main(args As String()) ' Load Excel file - works on all platforms without Office Dim workbook As WorkBook = WorkBook.Load("SalesData.xlsx") Dim dataSheet As WorkSheet = workbook.WorkSheets(0) ' Convert to DataTable for powerful manipulation - maintains data types Dim dataTable = dataSheet.ToDataTable(True) ' True = use first row as column headers ' Create pivot-style aggregation using LINQ - no COM objects needed Dim pivotData = dataTable.AsEnumerable() _ .GroupBy(Function(row) New With { Key .Product = row("Product").ToString(), Key .Region = row("Region").ToString() }) _ .Select(Function(g) New With { .Product = g.Key.Product, .Region = g.Key.Region, .TotalSales = g.Sum(Function(row) Convert.ToDecimal(row("Sales"))), .AverageSale = g.Average(Function(row) Convert.ToDecimal(row("Sales"))), .Count = g.Count() }) ' Create pivot report worksheet - no Excel process started Dim pivotSheet As WorkSheet = workbook.CreateWorkSheet("PivotReport") ' Build cross-tabulation structure programmatically Dim products = pivotData.Select(Function(p) p.Product).Distinct().OrderBy(Function(p) p) Dim regions = pivotData.Select(Function(p) p.Region).Distinct().OrderBy(Function(r) r) ' Create headers with formatting options pivotSheet("A1").Value = "Product/Region" Dim col As Integer = 2 For Each region In regions pivotSheet($"{ChrW(Asc("A"c) + col - 1)}1").Value = region ' Dynamic column addressing col += 1 Next ' Populate pivot data - memory efficient for large datasets Dim row As Integer = 2 For Each product In products pivotSheet($"A{row}").Value = product col = 2 For Each region In regions Dim sales = pivotData _ .Where(Function(p) p.Product = product AndAlso p.Region = region) _ .Select(Function(p) p.TotalSales) _ .FirstOrDefault() pivotSheet($"{ChrW(Asc("A"c) + col - 1)}{row}").Value = sales col += 1 Next row += 1 Next ' Add totals using Excel formulas - maintains live calculations pivotSheet($"A{row}").Value = "Total" ' Grand totals row For c As Integer = 2 To regions.Count() + 1 ' Formula references ensure dynamic updates pivotSheet($"{ChrW(Asc("A"c) + c - 1)}{row}").Formula = $"=SUM({ChrW(Asc("A"c) + c - 1)}2:{ChrW(Asc("A"c) + c - 1)}{row - 1})" Next ' Apply professional formatting - currency format for sales data Dim dataRange = pivotSheet($"B2:{ChrW(Asc("A"c) + regions.Count())}{row}") dataRange.FormatString = "$#,##0.00" ' Save without Office dependencies - works in containers workbook.SaveAs("PivotReport.xlsx") End Sub End Module $vbLabelText $csharpLabel 這種現代方法創建的透視表可以在 Docker 容器中無縫運行,並支援各種 Excel 格式。 您也可以匯出為不同的格式,包括CSV 、 JSON 和 XML 。 輸出結果是什麼樣子的? 左側是顯示原始銷售資料的 Excel 表格,右側是按地區彙總產品銷售情況的資料透視表。 如何使用 IronXL 公式建立動態匯總? 什麼時候應該使用公式而不是靜態聚合? 對於需要類似資料透視表刷新功能的動態更新場景,IronXL 可以利用Excel 的內建公式。 這種方法更加優雅且易於維護,程式碼無需手冊或支援即可輕鬆理解。 它與用於視覺化資料呈現的條件格式配合使用效果很好。 基於公式的匯總如何維護資料連線? // Load the workbook - container-friendly approach WorkBook workbook = WorkBook.Load(inputPath); // Rename the first worksheet so formulas reference correctly WorkSheet dataSheet = workbook.WorkSheets[0]; dataSheet.Name = "DataSheet"; // Named reference for formulas // Convert worksheet to DataTable for efficient processing DataTable dataTable = dataSheet.ToDataTable(true); // Create new summary worksheet - no COM objects WorkSheet summarySheet = workbook.CreateWorkSheet("DynamicSummary"); // Get unique product-region combinations using LINQ var uniqueCombos = dataTable.AsEnumerable() .Select(row => new { Product = row["Product"].ToString(), Region = row["Region"].ToString() }) .Distinct() .OrderBy(x => x.Product) .ThenBy(x => x.Region); // Add header row with proper formatting summarySheet["A1"].Value = "Product"; summarySheet["B1"].Value = "Region"; summarySheet["C1"].Value = "Total Sales"; summarySheet["D1"].Value = "Count"; // Populate rows with formulas - maintains live data connection int rowIndex = 2; foreach (var combo in uniqueCombos) { summarySheet[$"A{rowIndex}"].Value = combo.Product; summarySheet[$"B{rowIndex}"].Value = combo.Region; // SUMIFS formula for conditional aggregation summarySheet[$"C{rowIndex}"].Formula = $"=SUMIFS(DataSheet!C:C,DataSheet!A:A,\"{combo.Product}\",DataSheet!B:B,\"{combo.Region}\")"; // COUNTIFS for record counting summarySheet[$"D{rowIndex}"].Formula = $"=COUNTIFS(DataSheet!A:A,\"{combo.Product}\",DataSheet!B:B,\"{combo.Region}\")"; rowIndex++; } // Optional: add total row with grand totals summarySheet[$"A{rowIndex}"].Value = "Total"; summarySheet[$"C{rowIndex}"].Formula = $"=SUM(C2:C{rowIndex - 1})"; summarySheet[$"D{rowIndex}"].Formula = $"=SUM(D2:D{rowIndex - 1})"; // Apply number formatting for professional appearance var salesColumn = summarySheet[$"C2:C{rowIndex}"]; salesColumn.FormatString = "$#,##0.00"; // Save output file - works in any environment workbook.SaveAs(outputPath); // No Office required // Load the workbook - container-friendly approach WorkBook workbook = WorkBook.Load(inputPath); // Rename the first worksheet so formulas reference correctly WorkSheet dataSheet = workbook.WorkSheets[0]; dataSheet.Name = "DataSheet"; // Named reference for formulas // Convert worksheet to DataTable for efficient processing DataTable dataTable = dataSheet.ToDataTable(true); // Create new summary worksheet - no COM objects WorkSheet summarySheet = workbook.CreateWorkSheet("DynamicSummary"); // Get unique product-region combinations using LINQ var uniqueCombos = dataTable.AsEnumerable() .Select(row => new { Product = row["Product"].ToString(), Region = row["Region"].ToString() }) .Distinct() .OrderBy(x => x.Product) .ThenBy(x => x.Region); // Add header row with proper formatting summarySheet["A1"].Value = "Product"; summarySheet["B1"].Value = "Region"; summarySheet["C1"].Value = "Total Sales"; summarySheet["D1"].Value = "Count"; // Populate rows with formulas - maintains live data connection int rowIndex = 2; foreach (var combo in uniqueCombos) { summarySheet[$"A{rowIndex}"].Value = combo.Product; summarySheet[$"B{rowIndex}"].Value = combo.Region; // SUMIFS formula for conditional aggregation summarySheet[$"C{rowIndex}"].Formula = $"=SUMIFS(DataSheet!C:C,DataSheet!A:A,\"{combo.Product}\",DataSheet!B:B,\"{combo.Region}\")"; // COUNTIFS for record counting summarySheet[$"D{rowIndex}"].Formula = $"=COUNTIFS(DataSheet!A:A,\"{combo.Product}\",DataSheet!B:B,\"{combo.Region}\")"; rowIndex++; } // Optional: add total row with grand totals summarySheet[$"A{rowIndex}"].Value = "Total"; summarySheet[$"C{rowIndex}"].Formula = $"=SUM(C2:C{rowIndex - 1})"; summarySheet[$"D{rowIndex}"].Formula = $"=SUM(D2:D{rowIndex - 1})"; // Apply number formatting for professional appearance var salesColumn = summarySheet[$"C2:C{rowIndex}"]; salesColumn.FormatString = "$#,##0.00"; // Save output file - works in any environment workbook.SaveAs(outputPath); // No Office required Imports System.Data Imports System.Linq ' Load the workbook - container-friendly approach Dim workbook As WorkBook = WorkBook.Load(inputPath) ' Rename the first worksheet so formulas reference correctly Dim dataSheet As WorkSheet = workbook.WorkSheets(0) dataSheet.Name = "DataSheet" ' Named reference for formulas ' Convert worksheet to DataTable for efficient processing Dim dataTable As DataTable = dataSheet.ToDataTable(True) ' Create new summary worksheet - no COM objects Dim summarySheet As WorkSheet = workbook.CreateWorkSheet("DynamicSummary") ' Get unique product-region combinations using LINQ Dim uniqueCombos = dataTable.AsEnumerable() _ .Select(Function(row) New With { .Product = row("Product").ToString(), .Region = row("Region").ToString() }) _ .Distinct() _ .OrderBy(Function(x) x.Product) _ .ThenBy(Function(x) x.Region) ' Add header row with proper formatting summarySheet("A1").Value = "Product" summarySheet("B1").Value = "Region" summarySheet("C1").Value = "Total Sales" summarySheet("D1").Value = "Count" ' Populate rows with formulas - maintains live data connection Dim rowIndex As Integer = 2 For Each combo In uniqueCombos summarySheet($"A{rowIndex}").Value = combo.Product summarySheet($"B{rowIndex}").Value = combo.Region ' SUMIFS formula for conditional aggregation summarySheet($"C{rowIndex}").Formula = $"=SUMIFS(DataSheet!C:C,DataSheet!A:A,""{combo.Product}"",DataSheet!B:B,""{combo.Region}"")" ' COUNTIFS for record counting summarySheet($"D{rowIndex}").Formula = $"=COUNTIFS(DataSheet!A:A,""{combo.Product}"",DataSheet!B:B,""{combo.Region}"")" rowIndex += 1 Next ' Optional: add total row with grand totals summarySheet($"A{rowIndex}").Value = "Total" summarySheet($"C{rowIndex}").Formula = $"=SUM(C2:C{rowIndex - 1})" summarySheet($"D{rowIndex}").Formula = $"=SUM(D2:D{rowIndex - 1})" ' Apply number formatting for professional appearance Dim salesColumn = summarySheet($"C2:C{rowIndex}") salesColumn.FormatString = "$#,##0.00" ' Save output file - works in any environment workbook.SaveAs(outputPath) ' No Office required $vbLabelText $csharpLabel 這些公式與來源資料保持即時連接,當資料表變更時自動更新—類似於資料透視表刷新行為,但沒有互通依賴性。 對於複雜的場景,您可以 建立 Excel 圖表或使用命名區域來更好地管理公式。 基於公式的方法能帶來哪些效能優勢? 將此程式碼套用到我們的範例 Excel 文件,將產生以下輸出: ! Excel電子表格顯示了產品銷售數據,包含產品、地區、總銷售額和數量等列,顯示了不同地區各種電子產品(筆記型電腦、手機、平板電腦)的銷售情況,其中部分地區的銷售額為零。 基於公式的方法具有顯著的效能優勢:它們在 Excel 的計算引擎中原生執行,支援後台計算,並且可以與Excel 的列印設定無縫整合以產生報表。 您也可以套用儲存格格式和樣式來提高可讀性。 C# Interop 與 IronXL 在資料透視表方面有何不同? 哪些部署場景較適合採用哪一種方法? 方面 C# 互通 IronXL 辦公室要求 是的 - 完全安裝 否 - 獨立庫 平台支援 僅限 Windows 系統 Windows、Linux、macOS、Docker 記憶體管理 需要手動清理 COM 對象 自動 .NET 垃圾回收 部署 複雜 - 辦公室許可 簡單 - 單一 DLL 表現 Excel進程啟動緩慢 快速記憶體計算 雲端相容 否 - Azure 限制 是的 -支援 Azure Functions 原生透視表 是的 無 - 聚合替代方案 發展速度 速度慢 - COM 複雜性 快速直覺的 API 容器支援 不行 - 無法在 Docker 中運行 是的 -完全支援 Docker 許可證管理 辦公室單機許可 簡易許可證密鑰 每種解決方案需要哪些資源? C# 互通需要大量的系統資源:完整的 Office 安裝(2-4GB 磁碟空間)、Windows 作業系統、足夠的記憶體以運行 Excel 進程,以及 COM 註冊的管理權限。 相較之下,IronXL 只需要 .NET 執行時間和大約 50MB 的庫,因此非常適合資源受限的環境。 IronXL 的檔案大小限制有詳細的文件說明,可用於容量規劃。 你該選擇哪一種方法? 互通性何時仍然有意義? 選擇 C# 互通的條件: 必須使用原生 Excel 資料透視表對象 僅在安裝了 Office 的 Windows 系統上運作 僅部署到您管理的桌面系統 現有遺留程式碼依賴互通性 使用舊版 .NET Framework 需要使用其他 Excel 功能無法實現的特定功能。 針對這些有限的場景,請確保正確的錯誤處理和 COM 清理模式。 為什麼DevOps團隊更喜歡 IronXL? 選擇 IronXL 的情況: 部署到伺服器或雲端環境(Azure、AWS) 建構跨平台應用程式 要求更高的性能和可靠性 避免辦公室軟體授權費用 需要更簡潔、更容易維護的程式碼 支援 Mac、iOS、Android 或 Linux 系統 使用現代 .NET Core 和 .NET 5+ 希望能夠完全透過程式控制資料透視表的配置 建立Blazor 應用程式 建立從 SQL 資料庫載入 Excel 的微服務 IronXL 還提供廣泛的安全功能,包括工作簿加密和工作表保護。 現代發展的最佳路徑是什麼? 雖然 C# Excel Interop 可以開發原生透視表,但其部署限制和複雜性使其在現代應用程式中越來越不實用。 IronXL 的功能集透過資料聚合和基於公式的匯總提供了強大的替代方案,消除了對 Office 的依賴,同時保持了分析能力。 對於尋求無需 Interop 即可進行資料透視表開發的開發人員來說,IronXL 提供了一條更優的途徑,避免了 COM 的複雜性,可在所有平台上運行,並簡化了部署。 雖然沒有原生透視對象,但更大的靈活性、更好的性能以及無需 Office 許可的要求彌補了這一不足。 您可以建立電子表格、載入現有文件,甚至可以在需要時使用 VB.NET 。 現代DevOps實踐需要對容器友善的解決方案。 IronXL 透過全面的文件、豐富的範例和定期更新來滿足不斷變化的部署需求。 !{--01001100010010010100001001010010010000010101001001011001010111110100011101000101010101 01000101111101010011010101000100000101010010010101000100010101000100010111110101011101001000110 1010101000100100001011111010100000101001001001111010001000101010101010000110101010100101010101011 10101010001010010010010010010000010100110001011111010000100100110001001111101000011010010111111010000110100101110-- 準備好讓您的 Excel 自動化流程現代化,並使用現代 C# 建立您自己的資料透視表程式碼了嗎? 透過 NuGet 套件管理器,您可以在幾秒鐘內將 IronXL 整合到您的 C# 應用程式中。 您可以試用免費試用版或購買 IronXL 許可證,以消除生產應用程式中的互通依賴關係。 常見問題解答 使用 IronXL 在 Excel 中建立資料透視表有何好處? IronXL 可讓您在 Excel 中建立資料透視表,而不需要依賴 Office,相較於傳統的 C# Interop 方法,IronXL 是更精簡、更有效率的解決方案。 IronXL 如何處理透視表的資料處理? IronXL.Excel 提供強大的資料處理功能,可建立透視式報表,而不會產生與 Excel Interop 相關的複雜問題。 IronXL 可以獨立於 Excel Interop 使用嗎? 是的,IronXL.Excel 可獨立運作,讓開發人員無需依賴 Excel Interop 及其相關的依賴項目即可產生資料透視表。 為何開發人員偏愛 IronXL,而非 Excel 的傳統 Interop 方法? 開發人員之所以偏愛 IronXL,是因為它省去了傳統 Interop 方法所需的 Office 相依性,簡化了建立資料透視表的流程。 使用 IronXL 需要安裝 Microsoft Office 嗎? 不需要,IronXL 不需要安裝 Microsoft Office,因為它獨立於 Office 運作,不像 C# Interop 需要 Office 的依賴。 IronXL 是否與現代 C# 程式設計相容? 是的,IronXL.Excel 旨在與現代 C# 程式設計無縫整合,提供處理 Excel 資料處理任務的當代方法。 Curtis Chau 立即與工程團隊聊天 技術撰稿人 Curtis Chau 擁有電腦科學學士學位(卡爾頓大學),專長於前端開發,精通 Node.js、TypeScript、JavaScript 和 React。Curtis 對製作直覺且美觀的使用者介面充滿熱情,他喜歡使用現代化的架構,並製作結構良好且視覺上吸引人的手冊。除了開發之外,Curtis 對物聯網 (IoT) 也有濃厚的興趣,他喜歡探索整合硬體與軟體的創新方式。在空閒時間,他喜歡玩遊戲和建立 Discord bots,將他對技術的熱愛與創意結合。 相關文章 發表日期 2026年2月15日 如何使用 OleDb vs IronXL.Excel 將 DataTable 匯出至 Excel C# 學習如何使用 OleDb vs IronXL.Excel 將 DataTable 匯出至 Excel C#。 閱讀更多 發表日期 2026年2月15日 如何在未安裝 Office 的情況下使用 IronXL 開啟 VB.NET 中的現有 Excel 檔案 了解如何使用 IronXL for .NET 在未安裝 Office 的情況下在 VB.NET 中開啟現有的 Excel 檔案。 閱讀更多 發表日期 2026年2月15日 C# CSV to XLSX:完整開發人員指南 使用 IronXL 在 C# 中將 CSV 轉換為 XLSX。載入 CSV 檔案、保留資料類型、新增圖表,以及匯出為 Excel 格式,而無需 Microsoft Office 的相依性。 閱讀更多 Blazor Export to Excel:在 C# 中使用 IronXL 的完整指南在 C# 中使用 StreamReader 讀...
發表日期 2026年2月15日 如何使用 OleDb vs IronXL.Excel 將 DataTable 匯出至 Excel C# 學習如何使用 OleDb vs IronXL.Excel 將 DataTable 匯出至 Excel C#。 閱讀更多
發表日期 2026年2月15日 如何在未安裝 Office 的情況下使用 IronXL 開啟 VB.NET 中的現有 Excel 檔案 了解如何使用 IronXL for .NET 在未安裝 Office 的情況下在 VB.NET 中開啟現有的 Excel 檔案。 閱讀更多
發表日期 2026年2月15日 C# CSV to XLSX:完整開發人員指南 使用 IronXL 在 C# 中將 CSV 轉換為 XLSX。載入 CSV 檔案、保留資料類型、新增圖表,以及匯出為 Excel 格式,而無需 Microsoft Office 的相依性。 閱讀更多