C#でExcelピボットテーブルを作成する方法
Excelでピボットテーブルをプログラムで生成するには、Office依存関係のあるC# 相互運用性か、独立して動作する現代的なライブラリ(IronXL)が必要です。 このチュートリアルでは、両方のアプローチを示し、開発者が従来のInterop方法よりもIronXLを選ぶ理由を強調します。
この記事では、ピボットテーブルとグループを編集、作成、設計、計算する方法を、データの自動分析とエラーハンドリングと共に学びます。
Excelのピボットテーブルとは?
ピボットタイプは、Excelで追加できる最も強力なツールの1つです。 それは、大量のデータセットを要約する簡単でシンプルな方法です。 したがって、ピボットテーブルを使用すると、数値データを簡単に表示、理解し、分析することができます。 ピボットテーブルはExcelだけでなく、Google Sheets、Apple Numbers、CSVエクスポートなどの他のプログラムでも利用できます。 データを俯瞰して見るためのソリューションを提供し、データコンソールとして機能し、人々が情報を有意義に見ることを可能にし、現実にリンクします。
ピボットテーブルを誤った方法で作成し、その後C#で正しい方法でピボットテーブルを作成する方法を学びましょう。
C# 相互運用性を使用して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このInteropの例では、行として製品を、列として地域を、データエリアで売上を合算したネイティブXLピボットテーブルを作成します。 機能的ではありますが、このアプローチではMicrosoft Officeのインストールと注意深いCOMオブジェクトの管理が必要です。 なぜこのアプローチを現代で使用しないのかに関するMicrosoftの文書を参照してください。
C# 相互運用性はどのような問題を生み出すか?
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したがって、2025年にはこうしてピボットテーブルを作成します。
出力

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); //filenameIRON VB CONVERTER ERROR developers@ironsoftware.comこれらの数式は、ソースデータへのライブ接続を維持し、データシートが変更されると自動的に更新されます - ピボットテーブルのリフレッシュ動作と似ていますが、Interopの依存関係はありません。
このコードを以前の例からのExcelファイル(XLS/XLSX)に適用すると、ページにフィールド出力を得られます:

C# 相互運用性とIronXLをピボットテーブルのために比較する
アスペクト | C# 相互運用性 | IronXL |
|---|---|---|
オフィス必須 | はい - フルインストール | いいえ - スタンドアロンライブラリ |
プラットフォームサポート | Windowsのみ | Windows、Linux、macOS、Docker |
メモリ管理 | 手動のCOMクリーンアップが必要 | 自動 .NET ガベージコレクション |
デプロイメント | 複雑 - Officeライセンス | シンプル - 単一のDLL |
パフォーマンス | 遅い - Excel プロセスの起動 | 高速 - メモリ内計算 |
クラウド対応 | いいえ - Azure の制限 | はい - Azure Functions のサポート |
ネイティブピボットテーブル | はい | いいえ - 集約の代替手段 |
開発スピード | 遅い - COMの複雑さ | 高速 - 直感的なAPI |
どのアプローチを選ぶべきか?
C# 相互運用性を選択する場合:
- ネイティブな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ライセンス要件が排除されることで相殺されます。
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特有のプログラミング言語を学ぶ必要がありません。






