Open-XML-SDK を使ってExcelファイルの中を覗いてみた
先日、Open-XML-SDKがGitHub公開されました。
【日本の開発チームより】日本のOffice開発チームが初めて手掛けたオープンソースプロジェクト「Open XML SDK」が、先週よりGitHubで公開されています。
http://t.co/IchyLZ5HFd
— 日本マイクロソフト株式会社 広報 (@mskkpr) July 3, 2014
今までOpen-XMLには触れた事がなかったのですが、仕事でもExcelドキュメントを扱う機会が 圧倒的に増えそうなのでこの機会に触ってみることにしました。
ビルド等の方法はGitHubのREADME.mdを参照すれば問題ないと思います。
ビルド手順(WindowsでVisualStudio 2013をインストール済みを想定)
- git cloneでリポジトリをコピー
- スタート > 「Visual Studio ツール」 > 「開発者コマンド プロンプト for VS2013」を管理者として実行
- powershellコマンドでpowershellモードへ
- 「Set-ExecutionPolicy Unrestricted」でPowerShell実行ポリシーを変更
- 1.で作成したリポジトリにある「BldSdk.ps1」を実行
- 5分程でバイナリファイルがbuild内に作成されます。
作成されたDLLを参照に追加すればOpen-XMLドキュメントをゴニョゴニョできます。
使ってみた
とりあえず、Excelファイルからセルの値を参照するプログラムはこんな感じ
static void Main(string[] args)
{
var fileName = (args.Length > 0) ? args[0] : string.Empty;
var sheetName =(args.Length > 1) ? args[1] : string.Empty;
#if DEBUG
fileName = @"C:\openxml-sample.xlsx";
sheetName = "シート一番目";
#endif
using (SpreadsheetDocument spreadSheet = SpreadsheetDocument.Open(fileName, true))
{
var workbookPart = spreadSheet.WorkbookPart;
if (workbookPart == null)
{
Console.WriteLine("WorkbookPart Not Found !!");
return;
}
var sheet = workbookPart.Workbook.Descendants<Sheet>().FirstOrDefault(s => s.Name == sheetName);
if (sheet == null)
{
Console.WriteLine("Sheet Not Found !!");
return;
}
var wsheetPart = workbookPart.GetPartById(sheet.Id) as WorksheetPart;
if (wsheetPart == null)
{
Console.WriteLine("WorksheetPart Not Found !!");
return;
}
var ws = wsheetPart.Worksheet;
foreach (var row in ws.Descendants<Row>())
{
foreach (Cell cell in row)
{
string value = string.Empty;
switch (cell.DataType.Value)
{
case CellValues.Boolean:
case CellValues.Date:
case CellValues.Error:
case CellValues.InlineString:
case CellValues.Number:
case CellValues.String:
value = cell.InnerText;
break;
case CellValues.SharedString:
var stringTable = workbookPart.GetPartsOfType<SharedStringTablePart>().FirstOrDefault();
if (stringTable != null)
{
value = stringTable.SharedStringTable.ElementAt(int.Parse(cell.InnerText)).InnerText;
}
break;
default:
break;
}
Console.WriteLine(string.Format("Adress {0}, Value {1}", cell.CellReference.Value, value));
}
}
}
Console.WriteLine("終了するには何かキーを入力してください。");
Console.ReadKey();
}
}
読み込むExcelはこのような物を読み込ませます。

この状態で実行すると以下のような結果になります。
Adress A1, Value 1行目1列目ギョウメレツメ Adress B1, Value 1行目2列目ギョウメレツメ Adress A2, Value 2行目1列目ギョウメレツメ 終了するには何かキーを入力してください。
結果で出ている通り"読み"もXMLデータに含まれているようです。
入力したデータだけ取り出すには先頭子要素のInnerTextを参照すると取り出すことができそうです。
stringTable.SharedStringTable.ElementAt(int.Parse(cell.InnerText)).FirstChild.InnerText;
この辺りはOpen-XMLのドキュメント仕様になるのですが、以下のサイトを参考にすると理解しやすかったです。
XMLを取り込んだ最新Officeフォーマットとは(前編):Officeファイルの成り立ちと最新形、そして標準化 (1/2) - @IT
感想
できることは多いのかもしれないですが、XML構造をしっかり理解していないといにくい印象を受けました。
もう少しVBAっぽくアクセスできたら良いと思うのですが、そこまでするには多くの作りこみが必要でしょう。
なお、Open XMLをラップするClosedXMLなるプロジェクトがあるようです。
こちらの方がスマートに書けるそうです。
ClosedXML
https://closedxml.codeplex.com/