LoginSignup
5
3

More than 1 year has passed since last update.

OpenXMLでExcelファイルを操作しよう (2) - セルに値を設定したい

Last updated at Posted at 2021-09-26

はじめに

先月(2021/08)、技術評論社より『C#コードレシピ集』を出版しました。この本には、385のコードレシピが掲載されています。執筆している段階では385を超えるレシピを予定していたのですが、ページ数の関係(この本700ページを超える分厚い本です)でいくつかのレシピは没にしています。その中にOpen XMLを使ってExcelを操作するものがあります。そのまま眠らせてしまうのは残念ので、Qiitaでこのレシピを5回に分けて紹介しています。

  1. OpenXMLでExcelファイルを操作しよう (1) - Excelファイルを新規作成したい
  2. OpenXMLでExcelファイルを操作しよう (2) - セルに値を設定したい ← 今ここ
  3. OpenXMLでExcelファイルを操作しよう (3) - セルの値を読み込みたい
  4. OpenXMLでExcelファイルを操作しよう (4) - 全てのセルの値を取得したい
  5. OpenXMLでExcelファイルを操作しよう (5) - セルに書式を設定したい

コードレシピの環境は、C#9.0 + .NET 5 のコンソールアプリケーションです。

なお、『C#コードレシピ集』では、NPOIを使ってエクセルファイルを操作するレシピを掲載しています。

定義するメソッド

OpneXMLを利用してセルに値を設定するには、「シートを選択」「セルオブジェクトを作成」「セルに値を設定」という3つの手順を踏みます。

前回定義した、MyExcelBookクラスにこれらの機能を実装してみます。ここでは以下の4つのメソッドを定義しています。

メソッド 機能
SelectSheet シートを選択
CreateCell  セルオブジェクトの作成、すでに存在している場合はそのセルを返す
SetValueAtCell セルに値を設定
SetValue セルを作成し値を設定する。CreateCell, SetValueAtCellを連続して呼び出す

最後のSetValueメソッドは、CreateCell、SetValueAtCellのふたつのメソッドを連続して呼び出すことで、簡単にセルに値を設定する機能を呼び出せるようにしたものです。すでにCellが存在している場合は、上書きされます。

MyExcelBookクラス

では、MyExcelBookクラスを示します。

sealed class MyExcelBook : IDisposable {
    private MyExcelBook() { }

    public void Dispose() => _document?.Dispose();

    private SpreadsheetDocument _document;
    private WorkbookPart _workbookpart;
    private WorksheetPart _worksheetPart;
    private Sheets _sheets;

    public static MyExcelBook CreateBook(string filepath) {
        var book = new MyExcelBook();
        // Excelのドキュメントを新規に作成する
        book._document = SpreadsheetDocument.Create(filepath, SpreadsheetDocumentType.Workbook);

        // ドキュメントにワークブックを追加する
        book._workbookpart = book._document.AddWorkbookPart();
        book._workbookpart.Workbook = new Workbook();

        // ワークブックにシートの入れ物を追加する
        book._sheets = book._workbookpart.Workbook.AppendChild<Sheets>(new Sheets());
        return book;
    }

    public void Save() {
        _workbookpart.Workbook.Save();
        _document.Close();
    }

    public void CreateSheet(string sheetname) {
        // シート作成のための準備
        _worksheetPart = _workbookpart.AddNewPart<WorksheetPart>();
        _worksheetPart.Worksheet = new Worksheet(new SheetData());

        // シートを作成し追加する
        var max = (uint)(_sheets.Count() + 1);
        var sheet = new Sheet {
            Id = _workbookpart.GetIdOfPart(_worksheetPart),
            SheetId = max,
            Name = sheetname
        };
        _sheets.Append(sheet);
    }

    // 以降が追加したメンバー

    // シートを選択する
    public void SelectSheet(string sheetName) {
        // workbookから指定したシートを見つける
        var theSheet = _workbookpart.Workbook.Descendants<Sheet>().
            Where(s => s.Name == sheetName).FirstOrDefault();

        if (theSheet == null)
            throw new ArgumentException("sheetName");
        //  WorkSheetPartを取り出す。これが以降の操作で必要
        _worksheetPart = (WorksheetPart)(_workbookpart.GetPartById(theSheet.Id));
    }

    // セルを作成。存在していたらそのセルを返す
    public Cell CreateCell(string columnName, uint rowIndex) {
        // SheetDataを見つける
        var worksheet = _worksheetPart.Worksheet;
        var sheetData = worksheet.GetFirstChild<SheetData>();
        // 行を見つける
        var row = sheetData.Elements<Row>().FirstOrDefault(r => r.RowIndex == rowIndex);
        if (row == null) {
            //  行がなければ追加する
            row = new Row { RowIndex = rowIndex };
            sheetData.Append(row);
        }
        // その行の指定したカラムのセルを取り出す
        var cellReference = columnName + rowIndex;
        var cell = row.Elements<Cell>().FirstOrDefault(c => c.CellReference.Value == cellReference);
        if (cell != null)
            return cell;
        // セルがなければセルを追加する 
        var refCell = row.Elements<Cell>()
            .FirstOrDefault(c => string.Compare(c.CellReference.Value, cellReference, true) > 0);
        var newCell = new Cell() {
            CellReference = cellReference
        };
        row.InsertBefore(newCell, refCell);
        return newCell;
    }

    // 指定したセルに値を設定する
    public void SetValueAtCell(Cell cell, string text) {
        cell.CellValue = new CellValue(text);
        cell.DataType = new EnumValue<CellValues>(CellValues.String);
    }

    // column, rowで指定したセルに値を設定する。
    public void SetValue(string text, string columnName, uint rowIndex) {
        Cell cell = CreateCell(columnName, rowIndex);
        SetValueAtCell(cell, text);
    }
}

MyExcelBookクラスを使って、セルに値を設定する

以下、エクセルのBookを新規作成し、sheet1のセルA1, B2, C3に値を設定している例です。

using var book = MyExcelBook.CreateBook("example.xlsx");
book.CreateSheet("sheet1");
book.SelectSheet("sheet1");
book.SetValue("Text 1", "A", 1);
book.SetValue("Text 2", "B", 2);
book.SetValue("Text 3", "C", 3);
book.Save();

実行結果

以下のようなExcelファイルが作成されます。

スクリーンショット 2020-11-25 20.34.05.png

5
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
3