「ClosedXML - Excelファイルの操作」の版間の差分

ナビゲーションに移動 検索に移動
688行目: 688行目:
       {
       {
           Console.WriteLine($"エラーが発生: {ex.Message}");
           Console.WriteLine($"エラーが発生: {ex.Message}");
      }
    }
}
</syntaxhighlight>
<br><br>
== 大量データの高速処理 ==
以下の例では、100万行のデータを生成して、Excelファイルに高速で書き込んでいる。<br>
<br>
* Enumerable.RangeとLINQを使用して大量のデータを効率的に生成する。
* InsertDataメソッドを使用して、データを一括で挿入する。<br>これは、個別のセルに値を設定するよりも高速である。
<br>
大量のデータを扱う場合は、MemoryStreamのサイズが大きくなる可能性がある。<br>
そのような場合は、データを分割して処理、あるいは、ストリーミング方式でファイルに書き込む方法を検討する必要がある。<br>
<br>
<u>※注意</u><br>
<u>Closed XMLには直接的な非同期メソッドが存在しないため、これを回避するための1つの方法である。</u><br>
<u>Closed XMLの将来のバージョンで非同期メソッドが提供された場合は、それを使用するように更新することを推奨する。</u><br>
<br>
<syntaxhighlight lang="c#">
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using ClosedXML.Excel;
class Program
{
    static async Task Main(string[] args)
    {
      Console.WriteLine("大量データの完全非同期高速処理を開始...");
      var stopwatch = Stopwatch.StartNew();
      try
      {
          await ProcessLargeDataAsync();
          stopwatch.Stop();
          Console.WriteLine($"大量データの処理が完了  処理時間: {stopwatch.ElapsedMilliseconds}ms");
      }
      catch (Exception ex)
      {
          Console.WriteLine($"エラーが発生しました: {ex.Message}");
      }
    }
    static async Task ProcessLargeDataAsync()
    {
      var workbook = await Task.Run(() =>
      {
          var wb = new XLWorkbook();
          var worksheet = wb.Worksheets.Add("大量データ");
          // 100万行のデータを生成
          const int rowCount = 1_000_000;
          var data = Enumerable.Range(1, rowCount)
                              .Select(i => new { ID = i, Value = i * 2 })
                              .ToList();
          // データをワークシートに書き込む
          worksheet.Cell(1, 1).Value = "ID";
          worksheet.Cell(1, 2).Value = "Value";
          worksheet.Cell(2, 1).InsertData(data);
          // 合計を計算
          worksheet.Cell(rowCount + 2, 1).Value = "合計";
          worksheet.Cell(rowCount + 2, 2).FormulaA1 = $"=SUM(B2:B{rowCount + 1})";
          return wb;
      });
      // ファイルを非同期で保存
      await SaveWorkbookAsync(workbook, "大量データ処理.xlsx");
    }
    static async Task SaveWorkbookAsync(XLWorkbook workbook, string filePath)
    {
      using (var memoryStream = new MemoryStream())
      {
          workbook.SaveAs(memoryStream);
          memoryStream.Position = 0;
          using (var fileStream = new FileStream(filePath, FileMode.Create, FileAccess.Write, FileShare.None, bufferSize: 4096, useAsync: true))
          {
            await memoryStream.CopyToAsync(fileStream);
          }
       }
       }
     }
     }

案内メニュー