【ClosedXML】C#でExcelファイルを操作する


この記事ではClosedXMLの基礎的な扱いについて触れます。インポート及びエクスポート（Web画面からのファイル扱い含む）については別記事にする予定です。

## ClosedXMLを使用した理由
- 無償かつ商用利用可（MITライセンス）
- `Open XML SDK`というMicrosoft公式のSDKをラッパーしている
- VBAに似た記述形式で書ける
- 書き込み、読み込みが比較的早い

:::note warn
COM参照について
Googleで「Excel C#」等で検索するとClosedXMLのようなライブラリではなく、`Microsoft.Office.Interop.Excel`を使ったCOM参照による方法が出てきます。しかし、これは実行時にExcelアプリケーションを実際に用意することが必要になることや、プロセス管理及び処理の面から考えても推奨しません。
詳細は以下のQiita記事（Excelファイルを C# と VB.NET で読み込む "正しい" 方法）で解説されていますのでご確認ください。

:::

https://qiita.com/midori44/items/acab9106e6dad9653e73

:::note info
グラフ生成について
執筆時点において、ClosedXMLではグラフの生成に対応していません。
グラフが必要な場合は`SpreadSheetLight`等の類似ライブラリを使用する必要があります。
:::

## ClosedXMLの導入
Visual Studioの場合は、NuGetパッケージマネージャーで「ClosedXML」と検索し、インストールしてください。バージョンについて特に指定のない場合は「最新の安定版」を選択してください。

Visual Studio以外の場合やNuGetマネージャーについての詳細は以下公式リンクを参照してください。

https://learn.microsoft.com/ja-jp/nuget/consume-packages/install-use-packages-visual-studio

## 操作方法
基本となるコードは以下の通りです。
このコードではSample Sheetというシートを作成し、このシートに値を入力しています。
``` base.cs
// Excelワークブック(本体)を作成する
using var workbook = new XLWorkbook();
// ワークシートを作成する
var worksheet = workbook.AddWorksheet("Sample Sheet");
// セルを操作する
worksheet.Cell("A1").Value = "Hello World!";
worksheet.Cell(2,1).Value = "Excel Sample";// (2,1)はB1と同一の位置
// Excelワークブック(本体)を保存する
workbook.SaveAs("HelloWorld.xlsx");
```

### Workbook - ワークブック
- 新規作成
    - 引数を空にしてXLWorkbookのインスタンスを作成
- 読み込み
    - パス指定
        - Excelファイルのパスを渡す
    - 実データ指定
        - MemoryStreamやFileStram等の実データを渡す
- 保存
    - パス指定
        - 保存したいパスを渡す
    - stream保存
        - MemoryStreamやFileStram等を渡す
``` workbook.cs
// 新規作成
using var createWb = new XLWorkbook();
// 読み込み (パス指定)
using var readByPathWb = new XLWorkbook("HelloWorld.xlsx");
// 読み込み (実データ指定)
MemoryStream stream;
using var readByStreamWb = new XLWorkbook(stream);
// 保存 (パス保存)
createWb.SaveAs("SavedExcel.xlsx");
// 保存 (stream保存)
MemoryStream stream;
createWb.SaveAs(stream);
```

### Worksheet - ワークシ－ト
- 追加
    - 最後尾に追加
        - 引数にシート名を設定してAddWorksheetを呼ぶ
    - 挿入
        - 引数にシート名と番号を設定してAddWorksheetを呼ぶ（0で1番左に追加）
- 取得
    - シート名指定
        - 引数にシート名を指定してWorksheetを呼ぶ
    - 番号指定
        - 引数にシート番号を指定してWorksheetを呼ぶ（1が1番左のシート）
``` worksheet.cs
using var wb = new XLWorkbook();

// 追加 (最後尾に追加)
var addWs = wb.AddWorksheet("worksheetTitle");
// 追加 (挿入)
var insertWs = wb.AddWorksheet("insertWorksheetTitle", 0);
// 取得 (シート名指定)
var readByNameWs = wb.Worksheet("worksheetTitle");
// 取得 (番号指定)
var readByNumberWs = wb.Worksheet(1);// 1番目のシート
```

### Row, Column - 行、列
行と列それぞれ同様の記法で取得可
- 単一取得
    - 番号指定で取得（列は"A"等の文字指定可能）
- 複数取得
    - 取得範囲を指定（"2:6"、2, 6、"B:F"など複数の方法で指定可能）
- 空白セルを除く指定
    - 読み込んだ全セルの内、空白でないセルに対して指定ができる
``` row-column.cs
using var wb = new XLWorkbook();
var ws = wb.AddWorksheet("sampleWorksheet");

// 単一取得
var row = ws.Row(1);// 1行目取得
var column = ws.Column(1);// 1列目取得
// 複数取得
var allRows = ws.Rows();// 全取得
var allColumns = ws.Columns();// 全取得
var RangeRows = ws.Rows("2:6");// 2行目から6行目取得
var RangeColumns = ws.Columns("2:6");// 2列目から6列目取得 (B:Fと同様)

// 空白セルを除く指定 (Columnも同様に指定可能)
var allUsedRows = ws.RowsUsed();// 空白除く全取得
var lastUsedRows = ws.LastRowUsed();// 空白除く最終行取得
```

### Cell - セル
- セル取得
    - 行列や文字列形式で取得可能
    - ワークシートや行及び列を基準にして取得
- セル内の値
``` cell.cs
using var wb = new XLWorkbook();
var ws = wb.AddWorksheet("sampleWorksheet");
var row = ws.Row(1);
var column = ws.Column(1);

// セル取得
var cell = ws.Cell("A1");// A1セル
var cell2 = ws.Cell(1,1);// 1行1列目 (A1セル指定と同様)
var rowCell = row.Cell(1);// 行内の1つ目のセル取得
var columnCell = column.Cell(1);// 列内の1つ目のセル取得

// セル内の書式
cell.Value = "sample value";// 値の設定
cell.Style.Font.SetFontSize(20);// 文字の大きさ
cell.Style.Font.SetFontName("Arial");// 字体
```




## 公式ドキュメント
その他の操作は公式ドキュメントをご覧ください。

GitHub - ClosedXML / ClosedXML

https://github.com/ClosedXML/ClosedXML

Documentation

https://docs.closedxml.io/en/latest/

Wiki

https://github.com/closedxml/closedxml/wiki