"},スプレッドシートデータの可視化,Office Interop なしの Excel,ExcelとSQL Serverの統合"> フッターコンテンツにスキップ
IRONXLの使用

C#でExcelピボットテーブルを作成する方法

Excelでピボットテーブルをプログラムで生成するには、Office依存関係のあるC# Interopか、独立して動作する現代的なライブラリ(IronXL)が必要です。 このチュートリアルでは、両方のアプローチを示し、開発者が従来のInterop方法よりもIronXLを選ぶ理由を強調します。

この記事では、ピボットテーブルとグループを編集、作成、設計、計算する方法を、データの自動分析とエラーハンドリングと共に学びます。

Excelのピボットテーブルとは?

ピボットタイプは、Excelで追加できる最も強力なツールの1つです。 それは、大量のデータセットを要約する簡単でシンプルな方法です。 したがって、ピボットテーブルを使用すると、数値データを簡単に表示、理解し、分析することができます。 ピボットテーブルはExcelだけでなく、Google Sheets、Apple Numbers、CSVエクスポートなどの他のプログラムでも利用できます。 データを俯瞰して見るためのソリューションを提供し、データコンソールとして機能し、人々が情報を有意義に見ることを可能にし、現実にリンクします。

ピボットテーブルを誤った方法で作成し、その後C#で正しい方法でピボットテーブルを作成する方法を学びましょう。

C# Interopを使用してExcel表でピボットテーブルを作成する方法?

C# Excel Interopは、COM自動化を介してExcelのピボットテーブル機能に直接アクセスを提供します。 こちらが、C#でピボットテーブルを生成するためのツールを検索すると見つかる、伝統的なアプローチです: (廃止予定)

.NETで旧式の方法でピボットテーブルを作成する方法

using Excel = Microsoft.Office.Interop.Excel;
using System.Runtime.InteropServices;
// Create Excel application instance
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;
// Row area and column area 
// Create pivot cache and pivot table
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); // fields by field
// Configure pivot table fields
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
xlWorkbook.SaveAs(@"C:\Data\PivotReport.xlsx");
xlWorkbook.Close();
xlApp.Quit();
// Release COM objects to prevent memory leaks
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
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;
// Row area and column area 
// Create pivot cache and pivot table
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); // fields by field
// Configure pivot table fields
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
xlWorkbook.SaveAs(@"C:\Data\PivotReport.xlsx");
xlWorkbook.Close();
xlApp.Quit();
// Release COM objects to prevent memory leaks
Marshal.ReleaseComObject(pivotTable);
Marshal.ReleaseComObject(pivotCache);
Marshal.ReleaseComObject(xlPivotSheet);
Marshal.ReleaseComObject(xlSheet);
Marshal.ReleaseComObject(xlWorkbook);
Marshal.ReleaseComObject(xlApp);
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

このInteropの例では、行として製品を、列として地域を、データエリアで売上を合算したネイティブXLピボットテーブルを作成します。 機能的ではありますが、このアプローチではMicrosoft Officeのインストールと注意深いCOMオブジェクトの管理が必要です。 現代的でないこのアプローチを使用しない理由については、Microsoftのドキュメントを参照してください。

C# Interopはどのような問題を生み出すか?

Interopアプローチは重大な課題をいくつか提示します:

残念ながら、Stack Overflowや他のプログラミングウェブサイトは、2000年代初頭のアイデアに固定されたスレッドに固定されているため、引き続き推奨しています。

デプロイメントの依存関係: ソースコードを実行するすべてのマシン、特に本番サーバーにMicrosoft Officeのインストールが必要です。 これにより、ライセンスコストとデプロイメントの複雑さが加わります。

メモリ管理: COMオブジェクトは、Marshal.ReleaseComObject()を使用して明示的に解放する必要があります。 一つでもオブジェクトを見逃すと、Excelプロセスがメモリでハングしてしまうことが、Stack Overflowで広範に文書化されています。 ピボットキャッシュを考慮してください。

プラットフォームの制限詳細 : この旧式のソリューションは、OfficeがインストールされたWindowsでのみ機能します。 そして信じられないほど遅い可能性があり、ユーザーを混乱させ、メモリリークを引き起こす可能性があります。 Linux、macOS、Dockerコンテナ、またはAzure Functionsのようなクラウドプラットフォームをサポートしていません。

パフォーマンスの問題: Excelアプリケーションインスタンスの開始は遅く、特にサーバーサイド処理においてリソースを多く消費します。

バージョン互換性: 異なるOfficeバージョンはさまざまなCOMインターフェースを持つ可能性があり、環境間で互換性の問題を引き起こします。

IronXLはInteropなしでプログラムによるピボットテーブルをどのように作成するか?

IronXLは、COM依存関係なしでの管理コードを使用してピボットテーブルの作成に異なるアプローチを取ります。 それはネイティブExcelピボットテーブルを作成しませんが、強力な集約機能を提供します:

現代的な方法でプログラム的にXLSXまたはXLSのピボットテーブルを作成する方法:

using IronXL;
using System.Linq;
using System.Data; // Keep this namespace
using static System.Data.DataTableExtensions; // Use 'using static' for DataTableExtensions
class Program
{
    static void Main(string[] args)
    {
        // Load Excel file - no Office required
        WorkBook workbook = WorkBook.Load("SalesData.xlsx");
        WorkSheet dataSheet = workbook.WorkSheets[0];
        // Convert to DataTable for powerful manipulation
        var dataTable = dataSheet.ToDataTable(true); // true = use first row as column headers
        // Create pivot-style aggregation using LINQ
        var pivotData = dataTable.AsEnumerable()
            .GroupBy(row => new {
                Product = row["Product"].ToString(),
                Region = row["Region"].ToString()
            }) //range
            .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
        WorkSheet pivotSheet = workbook.CreateWorkSheet("PivotReport");
        // Build cross-tabulation structure
        var products = pivotData.Select(p => p.Product).Distinct().OrderBy(p => p);
        var regions = pivotData.Select(p => p.Region).Distinct().OrderBy(r => r);
        // Create headers
        pivotSheet["A1"].Value = "Product/Region";
        int col = 2;
        foreach (var region in regions)
        {
            pivotSheet[$"{(char)('A' + col - 1)}1"].Value = region; // string  
            col++;
        }
        // Populate pivot data
        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
        pivotSheet[$"A{row}"].Value = "Total"; // grand totals
        for (int c = 2; c <= regions.Count() + 1; c++)
        {
            pivotSheet[$"{(char)('A' + c - 1)}{row}"].Formula = $"=SUM({(char)('A' + c - 1)}2:{(char)('A' + c - 1)}{row - 1})";
        }
        // Proceeding to apply formatting
        var dataRange = pivotSheet[$"B2:{(char)('A' + regions.Count())}{row}"];
        dataRange.FormatString = "$#,##0.00";
        workbook.SaveAs("PivotReport.xlsx");
    }
}
using IronXL;
using System.Linq;
using System.Data; // Keep this namespace
using static System.Data.DataTableExtensions; // Use 'using static' for DataTableExtensions
class Program
{
    static void Main(string[] args)
    {
        // Load Excel file - no Office required
        WorkBook workbook = WorkBook.Load("SalesData.xlsx");
        WorkSheet dataSheet = workbook.WorkSheets[0];
        // Convert to DataTable for powerful manipulation
        var dataTable = dataSheet.ToDataTable(true); // true = use first row as column headers
        // Create pivot-style aggregation using LINQ
        var pivotData = dataTable.AsEnumerable()
            .GroupBy(row => new {
                Product = row["Product"].ToString(),
                Region = row["Region"].ToString()
            }) //range
            .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
        WorkSheet pivotSheet = workbook.CreateWorkSheet("PivotReport");
        // Build cross-tabulation structure
        var products = pivotData.Select(p => p.Product).Distinct().OrderBy(p => p);
        var regions = pivotData.Select(p => p.Region).Distinct().OrderBy(r => r);
        // Create headers
        pivotSheet["A1"].Value = "Product/Region";
        int col = 2;
        foreach (var region in regions)
        {
            pivotSheet[$"{(char)('A' + col - 1)}1"].Value = region; // string  
            col++;
        }
        // Populate pivot data
        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
        pivotSheet[$"A{row}"].Value = "Total"; // grand totals
        for (int c = 2; c <= regions.Count() + 1; c++)
        {
            pivotSheet[$"{(char)('A' + c - 1)}{row}"].Formula = $"=SUM({(char)('A' + c - 1)}2:{(char)('A' + c - 1)}{row - 1})";
        }
        // Proceeding to apply formatting
        var dataRange = pivotSheet[$"B2:{(char)('A' + regions.Count())}{row}"];
        dataRange.FormatString = "$#,##0.00";
        workbook.SaveAs("PivotReport.xlsx");
    }
}
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

したがって、2025年にはこうしてピボットテーブルを作成します。

出力

C#でExcelピボットテーブルを作成する方法:図1 - 作成したピボットテーブルを表示する元のExcelファイル

IronXLの式を使用して動的なサマリーを作成する方法?

動的な更新が必要なシナリオでは、ピボットテーブルの作成と類似したピボットテーブルの更新機能を計算するために、IronXLはExcelの組み込み数式を活用して回答を得ることができます。 一般的に、この方法は前述の回答よりも望ましいです - レコードはより現代的でエレガントな方法で処理されており、コードと同様に簡単に理解できます。 簡単に設定でき、サポートに連絡したりマニュアルを読む必要はありません。

// Load the workbook
WorkBook workbook = WorkBook.Load(inputPath);
// Rename the first worksheet so formulas reference correctly
WorkSheet dataSheet = workbook.WorkSheets[0];
dataSheet.Name = "DataSheet";
// Convert worksheet to DataTable
DataTable dataTable = dataSheet.ToDataTable(true);
// Create new summary worksheet
WorkSheet summarySheet = workbook.CreateWorkSheet("DynamicSummary");
// Get unique product-region combinations
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
summarySheet["A1"].Value = "Product";
summarySheet["B1"].Value = "Region";
summarySheet["C1"].Value = "Total Sales";
summarySheet["D1"].Value = "Count";
// Populate rows with formulas
int rowIndex = 2;
foreach (var combo in uniqueCombos)
{
    summarySheet[$"A{rowIndex}"].Value = combo.Product;
    summarySheet[$"B{rowIndex}"].Value = combo.Region;
    // Adjust column references if your Sales column is C (not D)
    summarySheet[$"C{rowIndex}"].Formula =
        $"=SUMIFS(DataSheet!C:C,DataSheet!A:A,\"{combo.Product}\",DataSheet!B:B,\"{combo.Region}\")";
    summarySheet[$"D{rowIndex}"].Formula =
        $"=COUNTIFS(DataSheet!A:A,\"{combo.Product}\",DataSheet!B:B,\"{combo.Region}\")";
    rowIndex++;
}
// Optional: add total row
summarySheet[$"A{rowIndex}"].Value = "Total";
summarySheet[$"C{rowIndex}"].Formula = $"=SUM(C2:C{rowIndex - 1})";
summarySheet[$"D{rowIndex}"].Formula = $"=SUM(D2:D{rowIndex - 1})";
// Save output file
workbook.SaveAs(outputPath);  //filename
// Load the workbook
WorkBook workbook = WorkBook.Load(inputPath);
// Rename the first worksheet so formulas reference correctly
WorkSheet dataSheet = workbook.WorkSheets[0];
dataSheet.Name = "DataSheet";
// Convert worksheet to DataTable
DataTable dataTable = dataSheet.ToDataTable(true);
// Create new summary worksheet
WorkSheet summarySheet = workbook.CreateWorkSheet("DynamicSummary");
// Get unique product-region combinations
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
summarySheet["A1"].Value = "Product";
summarySheet["B1"].Value = "Region";
summarySheet["C1"].Value = "Total Sales";
summarySheet["D1"].Value = "Count";
// Populate rows with formulas
int rowIndex = 2;
foreach (var combo in uniqueCombos)
{
    summarySheet[$"A{rowIndex}"].Value = combo.Product;
    summarySheet[$"B{rowIndex}"].Value = combo.Region;
    // Adjust column references if your Sales column is C (not D)
    summarySheet[$"C{rowIndex}"].Formula =
        $"=SUMIFS(DataSheet!C:C,DataSheet!A:A,\"{combo.Product}\",DataSheet!B:B,\"{combo.Region}\")";
    summarySheet[$"D{rowIndex}"].Formula =
        $"=COUNTIFS(DataSheet!A:A,\"{combo.Product}\",DataSheet!B:B,\"{combo.Region}\")";
    rowIndex++;
}
// Optional: add total row
summarySheet[$"A{rowIndex}"].Value = "Total";
summarySheet[$"C{rowIndex}"].Formula = $"=SUM(C2:C{rowIndex - 1})";
summarySheet[$"D{rowIndex}"].Formula = $"=SUM(D2:D{rowIndex - 1})";
// Save output file
workbook.SaveAs(outputPath);  //filename
IRON VB CONVERTER ERROR developers@ironsoftware.com
$vbLabelText   $csharpLabel

これらの数式はソースデータへのライブ接続を維持し、データシートが変更されると自動的に更新します - しかし、Interop依存関係なしに、ピボットテーブル更新動作に類似した動作です。

このコードを以前の例からのExcelファイル(XLS/XLSX)に適用すると、ページにフィールド出力を得られます:

C#でExcelピボットテーブルを作成する方法:図2 - メモ: C#動的サマリー出力は位置コンテキストに見えます。

C# InteropとIronXLをピボットテーブルのために比較する

アスペクト

C# Interop

IronXL

Officeが必要

はい - フルインストール

いいえ - スタンドアロンライブラリ

プラットフォームサポート

Windowsのみ

Windows、Linux、macOS、Docker

メモリ管理

手動でのCOMクリーンアップが必要

自動.NETガベージコレクション

デプロイメント

複雑 - Officeライセンス

簡単 - 単一DLL

パフォーマンス

遅い - Excelプロセスの起動

速い - メモリ内計算

クラウド互換性

いいえ - Azureの制限

はい - Azure Functionsサポート

ネイティブピボットテーブル

はい

いいえ - 集約代替

開発速度

遅い - COMの複雑さ

速い - 直感的なAPI

どのアプローチを選ぶべきか?

C# Interopを選択する場合:

  • ネイティブなExcelピボットテーブルオブジェクトが絶対に必要
  • Windows上でOfficeがインストールされたすべてのターゲットマシンでのみ作業
  • 管理するデスクトップシステムでのみデプロイする
  • 既存のレガシーコードがInteropに依存している
  • レガシー.NET Frameworkバージョンを使用する

IronXLを選択する場合:

  • サーバーまたはクラウド環境やサービスにデプロイする場合(Azure、AWS ...)
  • クロスプラットフォームアプリケーションを構築する
  • より良い性能と信頼性を求める
  • Officeライセンス費用を避ける
  • 簡単で、メンテナブルなコードを求める
  • Mac、iOS、Android、Linuxシステムをサポートする
  • 現代の.NET Framework Coreと.NET 5,6,7,8,9,10で作業する場合
  • 開発コンソール/IDE内でピボットテーブルの各フィールドをデータ範囲からプログラム的に設定を行うために完全なアクセスを希望している場合。

結論

C# Excel Interopはネイティブピボットテーブルを開発できますが、そのデプロイメント制限と複雑さは、現代のアプリケーションにはますます不向きになっています。 IronXLは、データ集約と数式ベースのサマリーを提供し、Office依存を排除しながら、分析機能を維持します。 これが役に立った場合は投票、コメント、または登録してください。

Interopを使用せずにピボットテーブルを開発するための代替オプションを求める開発者には、IronXLはCOMの複雑さを避け、すべてのプラットフォームで機能し、デプロイメントを簡素化する優れた道を提供します。 ネイティブピボットオブジェクトがないことのトレードオフは、より柔軟性が高く、パフォーマンスが向上し、Officeライセンス要件が排除されることで相殺されます。

今IronXLを始めましょう。
green arrow pointer

Excelの自動化をモダナイズし、現代的なC#で自分のピボットテーブルコードを作成する準備ができていますか?

IronXLはNuGetパッケージマネージャーを通じてあなたのC#アプリケーションに秒で実装できます。 無料トライアルを試してください本番アプリケーションでInterop依存関係を排除するために。

よくある質問

Excelにおけるピボットテーブルとは何?

Excelのピボットテーブルは、データを要約し、分析し、調査し、提示するための強力なツールです。これにより、列を行に変換したり、その逆を行ったりすることで、動的なデータ分析が可能になります。

C#でExcelのピボットテーブルを作成するためにIronXLを使用する理由は?

IronXLは、Office Interopに依存せずにC#でExcelピボットテーブルを作成することを可能にし、Excelのインストールを必要とせず、依存関係を削減し、現代的で効率的な選択肢となります。

IronXLはExcel操作においてC# Interopとどのように比較されますか?

IronXLは、Officeのインストールを必要とするC# Interopと比較して、より簡潔で独立したアプローチを提供します。IronXLは、Interopの複雑さなしにピボットテーブルやその他のExcel操作の作成を簡素化します。

Excelがインストールされていない場合でもピボットテーブルを生成できますか?

はい、IronXLを使用すると、Microsoft Officeに独立して動作するため、Excelがインストールされていなくても、C#アプリケーション内でピボットテーブルを生成できます。

IronXLは大規模なデータセットに適していますか?

IronXLは大規模なデータセットを効率的に処理するよう設計されているため、強力なデータ操作とピボットテーブル生成を必要とするアプリケーションに適しています。

IronXLを従来の方法よりも使用する利点は何ですか?

IronXLは、C# Interopのような従来の方法に対する現代の、依存関係のない代替手段を提供し、使いやすさ、柔軟性、Excelのインストールを必要とせずに複雑なデータ操作をサポートします。

IronXLでピボットテーブルを使用するためにVBAを学ぶ必要がありますか?

いいえ、IronXLを使用すると、開発者はC#内で直接ピボットテーブルを作成および管理できるため、VBAや他のExcel特有のプログラミング言語を学ぶ必要がありません。

Curtis Chau
テクニカルライター

Curtis Chauは、カールトン大学でコンピュータサイエンスの学士号を取得し、Node.js、TypeScript、JavaScript、およびReactに精通したフロントエンド開発を専門としています。直感的で美しいユーザーインターフェースを作成することに情熱を持ち、Curtisは現代のフレームワークを用いた開発や、構造の良い視覚的に魅力的なマニュアルの作成を楽しんでいます。

開発以外にも、CurtisはIoT(Internet of Things)への強い関心を持ち、ハードウェアとソフトウェアの統合方法を模索しています。余暇には、ゲームをしたりDiscordボットを作成したりして、技術に対する愛情と創造性を組み合わせています。