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/