Excel ファイルは、レポート、請求書、データのエクスポート、設定シートなど、さまざまな業務ワークフローで利用されています。C# 開発者であれば、Excel ファイルをプログラムから生成、読み取り、編集する必要に直面することも少なくありません。幸い、.NET エコシステムには成熟したライブラリが数多くあり、サーバーに Microsoft Office をインストールしなくても、Excel の処理を効率的に実装できます。
この記事では、C# 開発者が知っておきたい、実用的な Excel 自動化のタスクを 8 つ紹介します。特定のライブラリだけに焦点を当てるのではなく、それぞれの用途に適したツールを取り上げ、利用可能な選択肢を幅広く紹介します。これにより、自分のプロジェクトに合った方法を選びやすくなります。
タスク 1:Excel ワークブックをゼロから作成する
Excel ワークブックの新規作成は、C# でよく行われる Excel 自動化のタスクの 1 つです。月次売上レポートの生成、顧客情報のエクスポート、請求書の作成など、いずれの場合も、通常は新しいワークブックを作成し、データを入力するところから始まります。
シンプルなワークブックを作成する場合は、ClosedXML が適しています。直感的で扱いやすい API を備えており、Open XML の内部構造を意識することなく、ワークシートの作成、セルへの値の書き込み、Excel ファイルの保存を簡単に行えます。
次の例では、新しいワークブックを作成し、「売上レポート」 という名前のワークシートを追加して、サンプルデータを数行入力した後、Excel ファイルとして保存します。
using ClosedXML.Excel;
var workbook = new XLWorkbook();
var sheet = workbook.Worksheets.Add("売上レポート");
// ヘッダーを追加
sheet.Cell("A1").Value = "製品名";
sheet.Cell("B1").Value = "数量";
sheet.Cell("C1").Value = "売上高";
// データ行を追加
sheet.Cell("A2").Value = "ノートパソコン";
sheet.Cell("B2").Value = 25;
sheet.Cell("C2").Value = 32500;
sheet.Cell("A3").Value = "モニター";
sheet.Cell("B3").Value = 18;
sheet.Cell("C3").Value = 5400;
workbook.SaveAs("売上レポート.xlsx");
コードを実行すると、標準的な .xlsx ファイルが生成されます。このファイルは Microsoft Excel や、その他の互換性のある表計算アプリケーションで開くことができます。
この例では数行のデータしか扱っていませんが、データベース、API、業務アプリケーションから数千件のレコードをエクスポートする場合にも、同じ方法を利用できます。ワークブックの作成方法を理解したら、次のセクションで紹介する書式設定、数式、グラフなどの機能を追加して、さらに高度な処理へと発展させることができます。
タスク 2:既存の Excel ファイルからデータを読み取る
Excel ファイルの生成は、処理の半分にすぎません。従業員情報のアップロード、商品カタログのインポート、財務レポートの処理など、既存のスプレッドシートからデータを読み取る必要があるアプリケーションも数多くあります。
この用途に適した、成熟した .NET ライブラリはいくつかあります。NPOI は、.xls と .xlsx の両方をサポートする必要がある場合や、ライセンス条件を考慮したい場合に適した選択肢です。EPPlus も広く利用されているライブラリで、シンプルな API を備え、大きなファイルの処理にも効率的に対応できます。
ここでは、Excel データの読み取りを簡単かつ効率的に行える、人気の .NET ライブラリである EPPlus を使用します。ワークシートの API は分かりやすく、数行のコードでセルにアクセスしたり、行を順番に処理したり、値を取得したりできます。
次の例では、最初のワークシートからデータを読み取り、各行の内容をコンソールに出力します。
using OfficeOpenXml;
Console.OutputEncoding = Encoding.UTF8;
ExcelPackage.License.SetNonCommercialPersonal("あなたの名前");
using var package = new ExcelPackage(new FileInfo("売上レポート.xlsx"));
var sheet = package.Workbook.Worksheets[0];
int rowCount = sheet.Dimension.Rows;
int colCount = sheet.Dimension.Columns;
for (int row = 1; row <= rowCount; row++)
{
for (int col = 1; col <= colCount; col++)
{
var cellValue = sheet.Cells[row, col].Text;
Console.Write(cellValue.PadRight(15));
}
Console.WriteLine();
}
この方法は、各行が 1 つのレコードを表す構造化されたスプレッドシートに適しています。実際のアプリケーションでは、読み取ったデータを検証したり、オブジェクトにマッピングしたり、データベースにインポートして後続の処理に利用したりできます。
Excel ファイルを読み取る際には、ユーザーが作成したスプレッドシートのデータが必ずしも整っているとは限らない点に注意しましょう。空行、値の欠落、想定外のデータ型、統一されていない日付形式などは、よくある問題です。データを処理する前に基本的な検証を行うことで、実行時エラーを防ぎ、インポート処理の信頼性を高められます。
タスク 3:セルの書式を設定する(フォント、色、罫線)
生のデータも有用ですが、適切に書式設定されたスプレッドシートは、読みやすく、共有もしやすくなります。フォント、色、罫線、数値形式を統一することで、レポートの見栄えが向上し、重要な情報も見つけやすくなります。
Excel ワークシートの書式設定には、Spire.XLS for .NET が豊富なスタイル設定 API を提供しています。セルのフォントや背景色から、罫線、配置、数値形式まで、ワークシートのさまざまな要素をカスタマイズできます。
次の例では、見出しに書式を設定したシンプルな売上表を作成し、データ行にもスタイルを適用します。
using Spire.Xls;
using System.Drawing;
Workbook workbook = new Workbook();
Worksheet sheet = workbook.Worksheets[0];
sheet.Name = "売上レポート";
// ヘッダーを定義
string[] headers = { "製品名", "数量", "売上高" };
for (int col = 0; col < headers.Length; col++)
{
CellRange cell = sheet.Range[1, col + 1];
cell.Text = headers[col];
// 太字の白いフォント
cell.Style.Font.IsBold = true;
cell.Style.Font.Color = Color.White;
// 濃紺の背景
cell.Style.Color = Color.FromArgb(31, 73, 125);
// 中央揃え
cell.Style.HorizontalAlignment = HorizontalAlignType.Center;
}
// データ行を追加
object[,] data = {
{ "ノートパソコン", 25, 32500 },
{ "モニター", 18, 5400 },
{ "キーボード", 60, 3600 }
};
for (int row = 0; row < 3; row++)
{
for (int col = 0; col < 3; col++)
{
CellRange cell = sheet.Range[row + 2, col + 1];
if (col == 0)
cell.Text = data[row, col].ToString();
else
cell.NumberValue = Convert.ToDouble(data[row, col]);
// データ行に薄いグレーの背景
cell.Style.Color = Color.FromArgb(217, 225, 242);
// 罫線を追加
cell.Style.Borders[BordersLineType.EdgeTop].LineStyle = LineStyleType.Thin;
cell.Style.Borders[BordersLineType.EdgeBottom].LineStyle = LineStyleType.Thin;
cell.Style.Borders[BordersLineType.EdgeLeft].LineStyle = LineStyleType.Thin;
cell.Style.Borders[BordersLineType.EdgeRight].LineStyle = LineStyleType.Thin;
}
}
// 列幅を自動調整
sheet.AllocatedRange.AutoFitColumns();
workbook.SaveToFile("書式設定レポート.xlsx", ExcelVersion.Version2016);
いくつかの書式設定を追加するだけで、ワークシートの可読性が向上し、データをより見やすく提示できます。実際のアプリケーションでは、行ごとの背景色の切り替え、条件付き書式、カスタム数値形式、セルの配置なども活用することで、見やすさと使いやすさを兼ね備えたレポートを作成できます。
書式設定に少し手間をかけるだけでも、ユーザー体験は大きく改善します。特に、顧客、管理職、その他の非技術系の関係者と共有するレポートでは、その効果が顕著です。
タスク 4:数式を扱う
Excel の大きな強みの 1 つは、組み込みの数式計算機能です。C# のコード内で値を計算する代わりに、ワークシートへ数式を直接書き込み、Excel に計算を任せることができます。これにより、レポートの保守が容易になり、アプリケーションを変更することなく、ユーザーがデータを更新できるようになります。
数式を扱う場合、NPOI は一般的な Excel 数式の書き込みをサポートしているため、プログラムからスプレッドシートを生成する際の実用的な選択肢となります。
次の例では、売上表を作成し、表の末尾に集計用の数式を追加します。
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
var workbook = new XSSFWorkbook();
var sheet = workbook.CreateSheet("売上レポート");
// ヘッダー
var headerRow = sheet.CreateRow(0);
headerRow.CreateCell(0).SetCellValue("製品名");
headerRow.CreateCell(1).SetCellValue("数量");
headerRow.CreateCell(2).SetCellValue("売上高");
// データ行
var data = new (string Product, int Quantity, double Revenue)[]
{
("ノートパソコン", 25, 32500),
("モニター", 18, 5400),
("キーボード", 60, 3600),
};
for (int i = 0; i < data.Length; i++)
{
var row = sheet.CreateRow(i + 1);
row.CreateCell(0).SetCellValue(data[i].Product);
row.CreateCell(1).SetCellValue(data[i].Quantity);
row.CreateCell(2).SetCellValue(data[i].Revenue);
}
// 数式を含む集計行
int summaryRow = data.Length + 1;
var summary = sheet.CreateRow(summaryRow);
summary.CreateCell(0).SetCellValue("合計");
var quantityCell = summary.CreateCell(1);
quantityCell.SetCellFormula($"SUM(B2:B{summaryRow})");
var revenueCell = summary.CreateCell(2);
revenueCell.SetCellFormula($"SUM(C2:C{summaryRow})");
using var stream = new FileStream("数式付き売上.xlsx", FileMode.Create);
workbook.Write(stream);
生成されたファイルを Excel で開くと、SUM 数式が自動的に計算されます。NPOI は AVERAGE、IF、VLOOKUP、COUNTIF などの、より複雑な数式にも対応しています。同じ方法で数式の文字列を設定するだけで利用できます。
ただし、NPOI は数式をファイルに書き込みますが、生成時にその計算結果を評価するわけではありません。Excel を開かずにプログラムから計算済みの値を取得する必要がある場合は、EPPlus など、数式の評価に対応したライブラリを検討するとよいでしょう。
タスク 5:グラフを挿入する
グラフを使うと、生の数値を視覚的な情報に変換できるため、レポートの内容を理解しやすくなります。売上レポート、KPI ダッシュボード、財務サマリーなどでよく利用され、Excel 上で手作業でグラフを作成しなくても、ユーザーが傾向を把握できるようになります。
EPPlus は一般的なグラフの種類を多数サポートしており、通常のレポート作成に適しています。より高度なカスタマイズ、多様なグラフ形式、または高い再現性の描画が必要な場合は、より包括的なグラフ API を備えた Spire.XLS for .NET も選択肢になります。また、Excel をインストールする必要がないため、サーバー側で処理を実行する場合にも適しています。
次の例では、売上データを含む表を作成し、その上に縦棒グラフを挿入します。
using Spire.Xls;
using Spire.Xls.Charts;
using System.Drawing;
namespace ColumnChart
{
class Program
{
static void Main(string[] rgs)
{
// Workbook インスタンスを作成
Workbook workbook = new Workbook();
// 最初のワークシートを取得
Worksheet sheet = workbook.Worksheets[0];
// 指定したセルにデータを追加
sheet.Range["A1"].Value = "国";
sheet.Range["A2"].Value = "日本";
sheet.Range["A3"].Value = "アメリカ";
sheet.Range["A4"].Value = "フランス";
sheet.Range["A5"].Value = "ドイツ";
sheet.Range["B1"].Value = "6月";
sheet.Range["B2"].NumberValue = 5000;
sheet.Range["B3"].NumberValue = 8000;
sheet.Range["B4"].NumberValue = 9000;
sheet.Range["B5"].NumberValue = 8500;
sheet.Range["C1"].Value = "8月";
sheet.Range["C2"].NumberValue = 3000;
sheet.Range["C3"].NumberValue = 5000;
sheet.Range["C4"].NumberValue = 7000;
sheet.Range["C5"].NumberValue = 6000;
// セルのスタイルを設定
sheet.Range["A1:C1"].Style.Font.IsBold = true;
sheet.Range["A1:C1"].Style.KnownColor = ExcelColors.Black;
sheet.Range["A1:C1"].Style.Font.Color = Color.White;
sheet.Range["A1:C5"].Style.HorizontalAlignment = HorizontalAlignType.Center;
sheet.Range["A1:C5"].Style.VerticalAlignment = VerticalAlignType.Center;
// 数値形式を設定
sheet.Range["B2:C5"].Style.NumberFormat = "\"¥\"#,##0";
// ワークシートに縦棒グラフを追加
Chart chart = sheet.Charts.Add(ExcelChartType.ColumnClustered);
// グラフのデータ範囲を設定
chart.DataRange = sheet.Range["A1:C5"];
chart.SeriesDataFromRange = false;
// グラフの位置を設定
chart.LeftColumn = 1;
chart.TopRow = 7;
chart.RightColumn = 11;
chart.BottomRow = 29;
// グラフタイトルを設定して書式設定
chart.ChartTitle = "国別の売上市場";
chart.ChartTitleArea.Size = 13;
chart.ChartTitleArea.IsBold = true;
// 項目軸を設定して書式設定
chart.PrimaryCategoryAxis.Title = "国";
chart.PrimaryCategoryAxis.Font.Color = Color.Blue;
// 数値軸を設定して書式設定
chart.PrimaryValueAxis.Title = "売上(円)";
chart.PrimaryValueAxis.HasMajorGridLines = false;
chart.PrimaryValueAxis.MinValue = 1000;
chart.PrimaryValueAxis.TitleArea.TextRotationAngle = 90;
// データポイントにデータラベルを表示
foreach (ChartSerie cs in chart.Series)
{
cs.Format.Options.IsVaryColor = true;
cs.DataPoints.DefaultDataPoint.DataLabels.HasValue = true;
}
// グラフの凡例の位置を設定
chart.Legend.Position = LegendPositionType.Top;
// 結果ファイルを保存
workbook.SaveToFile("縦棒グラフ.xlsx", ExcelVersion.Version2010);
}
}
}
コードを実行すると、データ表と、その右側に配置された縦棒グラフを含むワークブックが生成されます。Spire.XLS は、折れ線グラフ、横棒グラフ、円グラフ、面グラフ、散布図など、さまざまな種類のグラフにも対応しています。ExcelChartType の列挙値を変更するだけで、データに適したグラフへ簡単に切り替えられます。
タスク 6:ウィンドウ枠の固定とオートフィルターの適用
使いやすいスプレッドシートに必要なのは、データだけではありません。操作や閲覧がしやすいことも重要です。レポートの行数が数百行、あるいは数千行に増えると、列見出しを見失ったり、必要な情報をすばやく見つけられなかったりすることがあります。
こうした問題を改善する簡単な方法が、ウィンドウ枠の固定とオートフィルターです。先頭行を固定すれば、スクロールしても列見出しを表示したままにできます。また、フィルターを使えば、ワークシートのデータそのものを変更することなく、並べ替えや絞り込みを行えます。
ClosedXML と EPPlus は、どちらもシンプルな API でこれらの機能を利用できます。ここでは ClosedXML を使用します。
次の例では、先頭行を固定し、すべての列でフィルターを使用できる商品一覧を作成します。
using ClosedXML.Excel;
var workbook = new XLWorkbook();
var sheet = workbook.Worksheets.Add("製品一覧");
// ヘッダーを書き込み
sheet.Cell("A1").Value = "製品名";
sheet.Cell("B1").Value = "カテゴリ";
sheet.Cell("C1").Value = "価格";
sheet.Cell("D1").Value = "在庫";
// データを書き込み
var data = new (string Product, string Category, double Price, int Stock)[]
{
("ノートパソコン", "電子機器", 1300, 25),
("モニター", "電子機器", 300, 18),
("キーボード", "アクセサリ", 60, 60),
("マウス", "アクセサリ", 20, 45),
("ウェブカメラ", "アクセサリ", 80, 30),
};
for (int i = 0; i < data.Length; i++)
{
int row = i + 2;
sheet.Cell(row, 1).Value = data[i].Product;
sheet.Cell(row, 2).Value = data[i].Category;
sheet.Cell(row, 3).Value = data[i].Price;
sheet.Cell(row, 4).Value = data[i].Stock;
}
// ヘッダー行を固定
sheet.SheetView.FreezeRows(1);
// データ範囲でオートフィルターを有効化
sheet.RangeUsed().SetAutoFilter();
workbook.SaveAs("製品一覧.xlsx");
生成されたファイルを開くと、スクロールしても先頭行が固定され、各列の見出しにフィルター用のドロップダウン矢印が表示されます。
これらの機能は数行のコードで実装できますが、特に大規模なレポートを分析担当者、管理職、業務ユーザーなどが確認する場合に、操作性を大きく改善できます。このような小さな工夫を加えることで、自動生成された Excel レポートを、より実用的で完成度の高いものにできます。
タスク 7:ワークシートとワークブックを保護する
書式を整えたワークブックを作成したら、次は内容が誤って変更されないように保護することを検討しましょう。数式や重要なデータを変更せずに維持する必要があるレポート、テンプレート、財務諸表などでは、特に重要です。
Excel には、ワークシートの保護、編集の制限、変更時のパスワード要求など、組み込みの保護機能が用意されています。これらの機能を利用すれば、ユーザーによる閲覧を可能にしながら、データの整合性を維持しやすくなります。
ワークブックの保護には、Spire.XLS for .NET が使いやすい API を提供しています。
次の例では、パスワードを設定してワークブックを保護します。
using Spire.Xls;
// Workbook オブジェクトを作成
Workbook workbook = new Workbook();
// Excel ファイルを読み込み
workbook.LoadFromFile("サンプル.xlsx");
// ワークシートを保護
workbook.Protect("psd-123");
// ワークブックを別の Excel ファイルに保存
workbook.SaveToFile("保護されたレポート.xlsx", ExcelVersion.Version2016);
ユーザーが生成されたワークブックを開く際には、正しいパスワードの入力が必要になります。これにより、パスワードによる保護を通じて、ワークブックへの不正なアクセスを防ぐのに役立ちます。
また、特定のセルだけをロックし、入力欄は編集できるようにすることも可能です。これにより、ワークブックの構造や計算式を維持しながら、ユーザーが必要なデータを入力できるようになります。
タスク 8:Excel を PDF に変換する
Excel ファイルは編集やデータ分析に適していますが、共有する際には必ずしも最適な形式とは限りません。デバイスによってレイアウトが変わったり、数式が誤って変更されたりする可能性があるほか、受信者が Excel をインストールしていない場合もあります。
そのため、多くの業務アプリケーションでは、顧客、管理職、その他の関係者に送信する前に、スプレッドシートを PDF としてエクスポートします。PDF は元のレイアウトを維持しやすく、印刷にも適しているため、意図したとおりの見た目で文書を共有できます。
Excel から PDF への変換には、Spire.XLS for .NET を利用できます。書式、グラフ、画像、ページレイアウトを維持しながら、高品質な PDF ファイルを生成できます。
次の例では、既存の Excel ワークブックを読み込み、PDF 文書として直接エクスポートします。
using Spire.Xls;
Workbook workbook = new Workbook();
workbook.LoadFromFile("売上レポート.xlsx");
workbook.ConverterSetting.SheetFitToWidth = true;
// PDF に変換
workbook.SaveToFile("売上レポート.pdf", FileFormat.PDF);
数行のコードで、印刷、アーカイブ、共有に利用できる PDF 版の Excel ワークブックを作成できます。生成された文書はワークブックの外観を維持するため、異なるデバイス間でも一貫した書式で表示する必要があるレポートに適しています。
PDF 以外にも、Excel ワークブックを HTML や画像としてエクスポートすることも一般的です。こうした方法を活用すれば、同じスプレッドシートの内容を、さまざまなアプリケーションや配布方法に合わせて再利用できます。
まとめ
C# での Excel 自動化は、決して複雑なものではありません。この記事で紹介したように、.NET エコシステムには、ワークブックの生成や書式設定から、グラフの挿入、コンテンツの保護、PDF へのエクスポートまで、さまざまなスプレッドシート処理に対応する成熟したライブラリがそろっています。
社内業務システム、レポート作成基盤、顧客向けアプリケーションのいずれを開発する場合でも、これらの Excel 自動化の手法を習得することで、作業時間を短縮し、手作業を減らし、ユーザーにとって使いやすいアプリケーションを実現できます。
この記事が、C# プロジェクトでより高度な Excel 処理を構築するための出発点になれば幸いです。








