アトム電器 三軒家店(有限会社 おかもとでんか)のホームページ。大阪市大正区にある町の電気屋さん。家電製品の販売、エアコン、電気工事、パソコンからリフォーム、オール電化など電気のことならなんでもお任せ下さい!アトム電器三軒家店

NPOIでExcel(97-2003)ファイルを操作する

C# Excel開発

ExcelがインストールされていないパソコンでもExcelの操作が可能なライブラリのひとつであるNPOI使い方の覚え書き。ClosedXMLというMicrosoft謹製のライブラリもあるけれどこちらは2007以降(xlsx)のみが対応しているのと、xlsからxlsxに変換したxlsxをClosedXMLで操作した後上書きすると、レイアウトが崩れる現象がでて使い物にならなかった。

  1. NPOIサイトから、downloadsボタンからダウンロードサイトに行けるのでそこからダウンロードします。
    NPOIのダウンロード

  2. Visual Studio に参照設定を追加します。ダウンロードしたNPOIファイルを解凍してできる開発しているアプリの.netのバージョンに合わせて「dotnet2」フォルダーか「dotnet4」フォルダーの「NPOI.OOXML.dll」、「NPOI.OpenXmlFormats.dll」、「NPOI.OpenXml4Net.dll」。「NPOI.dll」、「ICSharpCode.SharpZipLib.dll」を指定して追加します。
    Visual Studio 2015への参照設定

  3. サンプルコード用に準備したExcelファイルの内容。単純に値を合算する数式が設定されているのと、合算セルにセル名「SUMCELL」を指定しているだけのExcelファイル(97-2003形式)。
    Visual Studio 2015への参照設定

サンプルコード

サンプル用Excelファイルを使った基本的な処理。

private void Button_Click(object sender, RoutedEventArgs e) {
	string xlsPath = @"c:¥a¥test.xls";
	// 既存のxlsブックを開く
	IWorkbook wb = WorkbookFactory.Create(xlsPath);
	// 既存のxlsシートを取得する
	ISheet ws = wb.GetSheet("Sheet1");

	// A1形式でセル指定
	CellReference cr = new CellReference("A1");
	IRow row;
	ICell cell = null;
	for (int rowIndex = cr.Row; rowIndex<10;  rowIndex++) {
	row = ws.GetRow(rowIndex);
	cell = row.GetCell(cr.Col);
	cell.SetCellValue(100 + rowIndex);    // セルに値をセット
	}


	// セル名でセル指定
	IName name = wb.GetName("SUMCELL");
	cr = new CellReference(name.RefersToFormula);
	row = ws.GetRow(cr.Row);
	cell = row.GetCell(cr.Col);

	Console.WriteLine("{0:#,0}", cell.NumericCellValue);

	// 数式を計算させる
	wb.GetCreationHelper().CreateFormulaEvaluator().EvaluateAll();

	Console.WriteLine("{0:#,0}", cell.NumericCellValue);

	// 上書き保存
	using (System.IO.FileStream f = new System.IO.FileStream(xlsPath, System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.Write)) {
		wb.Write(f);
		f.Close();
	}
}
  • セル名指定の場合は、IWorkbookGetNameメソッドよりINameオブジェクトを取得して、そこからRefersToFormulaプロパティにてCellReferenceオブジェクトを取得する必要がある。
  • 保存するSaveメソッドなどは存在しないので、上書き保存・新規保存ともに、保存する場合は保存先のFileStreamオブジェクトを作成して、それを引数に取ったIWorkbookオブジェクトのWriteメソッドを実行する必要がある。
  • 数式の計算は自動では行われないので、値をセットした後に自動計算を実行するEvaluteAllメソッドなどを実行する必要がある。