1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

DataGridViewの表データをエクセルファイルに出力する(C# WinForm)

Last updated at Posted at 2022-08-23

DataGridViewの表データを、エクセルファイルに変換するプログラムを作成しました。

デモプロジェクト

2022/09/16追記:列の並び替えにも対応しました

Windwosフォーム画面イメージ
image

エクセルファイル画面イメージ
image

使用ライブラリ

C#からエクセルファイルを出力するライブラリです。
ClosedXmlと比較して、3倍~8倍速いです。(100行程度の場合。10万行だと圧倒的な差がでます。)
ただし凝った装飾などは指定できません。(数値書式、日付書式のカスタマイズは可能)
ですので、お手軽にダンプ出力したい用途に向いています。

コード

DumpExcelHelper.cs の拡張メソッドとしてToExcelFileが定義されています。
呼び出し方は以下になります。

dataGridView1.ToExcelFile(saveFileDialog1.FileName);

DumpExcelHelper 処理内容

DataGridViewのDataGridViewRowの値を
シリアライズするクラスを用意します。
タイトル行生成とシリアライズの処理を記述します。


public void WriteTitle(ref ExcelSerializerWriter writer, DataGridViewRow value, ExcelSerializerOptions options, string name)
{
    var serializer = options.GetRequiredSerializer<string>();
    var cells = value.Cells.OfType<DataGridViewCell>()
        .OrderBy(c => c.OwningColumn.DisplayIndex);
    foreach (var cell in cells)
    {
        serializer.Serialize(ref writer, cell.OwningColumn.HeaderText, options);
    }
}

public void Serialize(ref ExcelSerializerWriter writer, DataGridViewRow value, ExcelSerializerOptions options)
{
    var serializer = options.GetRequiredSerializer<object>();
    var cells = value.Cells.OfType<DataGridViewCell>()
        .OrderBy(c => c.OwningColumn.DisplayIndex);
    foreach (var cell in cells)
    {
        serializer.Serialize(ref writer, cell.Value, options);
    }
}

クラスをプロバイダに登録します。

readonly IExcelSerializerProvider _dataGridViewExcelProvider
    = ExcelSerializerProvider.Create(
        new[] { new DataGridViewExcelSerializer() },
        new[] { ExcelSerializerProvider.Default });

準備が整ったのでメインの出力処理です。

シリアライザの設定クラスを用意して、ToFileメソッドを呼ぶとファイルが作成されます。
(フォルダ作成・削除の権限が必要です。内部で作業フォルダとファイルのZIP圧縮を行うため)

なお、今回はエクセルの1行目にタイトル行を表示したいのでHeaderTextを抽出します。

var newConfig = ExcelSerializerOptions.Default with
{
    Provider = _dataGridViewExcelProvider,
    CultureInfo = CultureInfo.CurrentCulture,
    HasHeaderRecord = hasHeaderRecord,
    HeaderTitles = headerTitles ?? Array.Empty<string>(),
    AutoFitColumns = autoFitColumns,
    NumberFormat = "#,##0.000;[Red]\\-#,##0.000",
};
ExcelSerializer.ToFile(value, fileName, newConfig);

C#側のデータ型に応じて、エクセルのほうも文字、数値、日付に対応します。
例えば、文字列型の場合は、エクセルでも文字扱いになりますので、前0があっても安心です。

image

(付録)DataGridViewのデータ取得処理の概要

foreach (var row in dataGridView1.Rows.Cast<DataGridViewRow>())
{
    foreach (var c in row.Cells.OfType<DataGridViewCell>())
    {
        Debug.Write($"{c.Value},");
    }
    Debug.WriteLine("");
}

シリアライザについて

IEnumerableから型に応じた値を取得する処理は
CysharpさんのWebSerializerの方式を使用しています。

拡張性もあり高速に動作する素晴らしい設計です。

1
2
2

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
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?