HOWTO · Csharp
C# で Excel ファイルに書き込む
Microsoft Office API を使用して、C# で Excel ファイルに書き込むことができます。
このページの内容
C# から Excel ブックにデータを書き込むには、インストール済みのデスクトップ版 Excel を自動操作する場合に Microsoft Office Interop を使用します。Interop ではブックを作成し、セルに値を入力して、ネイティブの .xlsx ファイルとして保存できます。プログラムを実行するコンピューターには Excel がインストールされている必要があります。配置先の環境で Excel を利用できない場合は、ブックファイルを直接書き込むスプレッドシートライブラリを使用してください。
アプリケーションに適した Excel への書き込み方法を選ぶ
Microsoft Office Interop は Excel を起動し、COM を介してオブジェクトモデルと通信します。Excel 自体に依存するデスクトップ自動化、たとえば Excel 固有のブック動作を利用する場合に適しています。Interop は単独でファイルを書き込むライブラリではありません。プロジェクトに Interop の参照を追加しても、別のコンピューターに Excel がインストールされるわけではありません。
ワークシート、数式、書式が不要な単純な表データなら、より手軽な方法として CSV ファイルを使えます。Excel で CSV のテキストを開くことはできますが、CSV は Excel ブックではなく、ブックの機能も保存できません。以下では、この2つの出力方法を分けて説明します。
C# で Microsoft Office Interop を設定する
Visual Studio で、プロジェクトの[参照]ダイアログから Microsoft Excel Object Library への COM 参照を追加します。このライブラリのバージョンは、インストールされている Office のリリースによって異なります。早期バインディングの参照を追加したら、Microsoft.Office.Interop.Excel をインポートします。たとえば using Excel = Microsoft.Office.Interop.Excel; と書くと、Excel の型と名前が似た .NET の型を区別できます。
以下のブック作成例では、Excel の COM ProgID を使った遅延バインディングを使用するため、ソースコード内でこの名前空間を使う必要はありません。ただし、Excel を自動操作する点は同じで、実行時には Windows 上で Excel が必要です。コンパイル時に Excel の型を使い、IntelliSense も利用したい場合は早期バインディングを選びます。配置先でインストール済み Excel のバージョンを管理でき、バージョン固有の参照を避けたい場合は遅延バインディングを選びます。参照を追加しただけでは、サーバーや別のコンピューターで Excel を使えるようにはなりません。
ブックを作成してセルにデータを書き込む
この Interop の例では Excel を起動してブックを追加し、見出しと2行のデータを書き込んで、システムの一時ディレクトリにネイティブの .xlsx ファイルとして保存します。形式を表す値 51 は、Excel の xlOpenXMLWorkbook ファイル形式です。GUID を使って実行ごとに異なる出力ファイル名を作るため、非表示の Excel インスタンスが上書き確認の応答を待つことはありません。このコードは、デスクトップ版 Excel をインストールした Windows 環境を想定しています。実行時の出力例は示していません。
このセクションのコードと表示されるラベルや出力は英語のままです。
using System;
using System.IO;
using System.Runtime.InteropServices;
class Program
{
static void Main()
{
if (Environment.OSVersion.Platform != PlatformID.Win32NT)
{
Console.WriteLine("This example requires Windows with Excel installed.");
return;
}
object excelApp = null;
object workbooks = null;
object workbook = null;
object worksheets = null;
object worksheet = null;
object cells = null;
try
{
Type excelType = Type.GetTypeFromProgID("Excel.Application");
if (excelType == null)
{
Console.WriteLine("Excel is not registered on this computer.");
return;
}
dynamic app = Activator.CreateInstance(excelType);
excelApp = app;
app.Visible = false;
workbooks = app.Workbooks;
dynamic books = workbooks;
workbook = books.Add();
dynamic book = workbook;
worksheets = book.Worksheets;
dynamic sheets = worksheets;
worksheet = sheets[1];
dynamic sheet = worksheet;
cells = sheet.Range["A1:B3"];
dynamic dataRange = cells;
object[,] values =
{
{ "Name", "Age" },
{ "Ava", 28 },
{ "Liam", 31 }
};
dataRange.Value2 = values;
string fileName = "example-" + Guid.NewGuid().ToString("N") + ".xlsx";
string path = Path.Combine(Path.GetTempPath(), fileName);
book.SaveAs(path, 51);
Console.WriteLine("Saved " + Path.GetFileName(path));
}
catch (Exception ex)
{
Console.WriteLine("Excel operation failed: " + ex.Message);
}
finally
{
CloseWorkbook(workbook);
ReleaseComObject(cells);
ReleaseComObject(worksheet);
ReleaseComObject(worksheets);
ReleaseComObject(workbook);
ReleaseComObject(workbooks);
QuitExcel(excelApp);
ReleaseComObject(excelApp);
}
}
static void CloseWorkbook(object value)
{
if (value == null) return;
try { ((dynamic)value).Close(false); }
catch { }
}
static void QuitExcel(object value)
{
if (value == null) return;
try { ((dynamic)value).Quit(); }
catch { }
}
static void ReleaseComObject(object value)
{
if (value == null) return;
try
{
if (Marshal.IsComObject(value)) Marshal.FinalReleaseComObject(value);
}
catch { }
}
}
単純な表データには、Excel で開けるカンマ区切りテキストを書き出す、別の CSV の例もあります。これはブックを作成するものではなく、複数のシート、数式、書式にも対応しません。サンプルの値には CSV 用の引用符は不要です。任意のテキストを書き込む場合は、カンマ、引用符、改行を含むフィールドを引用符で囲み、フィールド内の引用符は2つ重ねてください。
この例を実行します。
using System;
using System.IO;
class Program
{
static void Main()
{
string path = "example.csv";
string contents = "Name,Age\nJohn Doe,30\n";
File.WriteAllText(path, contents);
Console.WriteLine("Wrote " + path);
}
}
Wrote example.csv
既存の Excel ファイルに書き込む
ブックをフルパスで開き、選択した範囲を COM 参照として保持し、クリーンアップ時に解放します。Save は開いたファイルをそのまま更新します。新しいパスに保存する場合やコピーを作る場合は SaveAs を使用してください。サンプルのパスは、編集するブックのパスに置き換えます。この Windows 向けデスクトップ Excel の例についても、実行時の出力例は示していません。
このセクションのコードと表示されるラベルや出力は英語のままです。
using System;
using System.IO;
using System.Runtime.InteropServices;
class Program
{
static void Main()
{
if (Environment.OSVersion.Platform != PlatformID.Win32NT)
{
Console.WriteLine("This example requires Windows with Excel installed.");
return;
}
object excelApp = null;
object workbooks = null;
object workbook = null;
object worksheets = null;
object worksheet = null;
object cells = null;
string path = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
"report.xlsx");
try
{
if (!File.Exists(path))
throw new FileNotFoundException("Workbook not found; update the sample path.", path);
Type excelType = Type.GetTypeFromProgID("Excel.Application");
if (excelType == null)
throw new InvalidOperationException("Excel is not registered on this computer.");
dynamic app = Activator.CreateInstance(excelType);
excelApp = app;
app.Visible = false;
workbooks = app.Workbooks;
dynamic books = workbooks;
workbook = books.Open(path);
dynamic book = workbook;
worksheets = book.Worksheets;
dynamic sheets = worksheets;
worksheet = sheets[1];
dynamic sheet = worksheet;
cells = sheet.Range["B2:C2"];
dynamic selectedCells = cells;
selectedCells.Value2 = new object[,] { { "Reviewed", DateTime.Today.ToString("yyyy-MM-dd") } };
book.Save();
Console.WriteLine("Updated " + Path.GetFileName(path));
}
catch (Exception ex)
{
Console.WriteLine("Excel operation failed: " + ex.Message);
}
finally
{
CloseWorkbook(workbook);
ReleaseComObject(cells);
ReleaseComObject(worksheet);
ReleaseComObject(worksheets);
ReleaseComObject(workbook);
ReleaseComObject(workbooks);
QuitExcel(excelApp);
ReleaseComObject(excelApp);
}
}
static void CloseWorkbook(object value)
{
if (value == null) return;
try { ((dynamic)value).Close(false); }
catch { }
}
static void QuitExcel(object value)
{
if (value == null) return;
try { ((dynamic)value).Quit(); }
catch { }
}
static void ReleaseComObject(object value)
{
if (value == null) return;
try
{
if (Marshal.IsComObject(value)) Marshal.FinalReleaseComObject(value);
}
catch { }
}
}
対象が CSV の場合は、ファイル入出力を使って行を書き換えてください。CSV にはワークシートやセルのオブジェクトモデルがありません。
Excel を終了してエラーに対処する
パスが利用できない場合や、保存先に書き込み権限がない場合、ファイル操作は失敗することがあります。Interop では、Excel の起動、ブックを開く操作、セルへの書き込み、保存でもエラーが発生し、ブックが使用中の場合も失敗することがあります。アプリケーションが役立つメッセージを表示または記録できる箇所でエラーを捕捉してください。ブックを閉じる処理、Quit、COM 参照の解放は finally に置きます。エラーを捕捉するだけでは Excel の後始末はできません。この例では各クリーンアップ処理を個別に保護しているため、終了処理の1つが失敗しても、後続の後始末を試みます。
Excel アプリケーションを使う時間は必要な処理の間だけにし、追跡されていない Range オブジェクトなど、余分な COM 参照を保持しないでください。例を応用する際は、一時出力先のパスを任意の保存先に変更します。書式を設定する場合は、値を書き込んだ後に、対象ワークシートの範囲プロパティを設定します。CSV 出力には書式を保持できません。アプリケーションで CSV の例を使う場合は、ファイル入出力のエラー処理も追加してください。