はじめに
こんにち、Excel は、データ分析、帳票、管理票、報告書、仕様書、テスト実行結果スクリーンショットの貼付台紙等々、Windows マシン上で行われるありとあらゆる業務のために使用されています。
そのため、パッケージソフトウェアを開発する人は誰しも、遅かれ早かれ Excel ブックからの読み取り・Excel ブックへの書き込みを実装することを迫られる場面に出会います。
そんな日が来たときのために、Excel ブックをプログラムから読み書きする方法について知っておきましょう。
読み書きする方法(他力)
まずは他力、すなわちライブラリを使用する方法を検討するのが妥当です。
書き始めるにあたって念のため、と思って Qiita を「OOXML」(Excel 2007 以降の .xlsx 形式ファイルのフォーマット)で検索してみたところ、……あっ……。
ありました。
- サーバサイドでExcelブックを生成するいくつかの方法(Excel Advent Calendar 2014 1日目)
http://qiita.com/matarillo/items/549493f6bb7e36c99443
Java の POI をはじめ、主要な言語で利用できるライブラリが紹介されています。
POI についてひと言
POI は仕事で少し使ってみましたが、かなり直感的に使えて、おまけに xls 形式と xlsx 形式とで共通のインタフェースも用意されていたりしてかなり便利でした。
開発も、2016 年時点でもなかなか活発に行われているようです。
- History of Changes - The Apache POI Project
http://poi.apache.org/changes.html
ライセンスも Apache ライセンスなので商用製品への組み込みも容易ですし、もちろんソースコードを入手して実装を調べることも可能です。
Java や、Java ライブラリを利用可能な環境で開発している場合は、まず試してみる価値のあるライブラリだと思います。
読み書きする方法(自力)
さて、このままでは、この投稿が他の Advent Calendar の投稿を紹介しただけで終わってしまいます。
それではあんまりなので、「POI 使ってみたんだけど、やりたかったあれができない!」とか、「ユーザから書き込んだ結果がおかしいって問い合わせが来たんだけど、ライブラリのコードを読んでもよくわからない!」みたいなときのために、Excel ブックの仕様に迫ってみます。
また、ライブラリを使うにせよ、どうしても API がブック側の仕様に引きずられて直感的でない部分は出てくるので、仕様を知っているに越したことはありません。(あるいは、うまくいかないときに仕様書を読んでみると「そういうことか!」みたいなことがあります)
.xls 形式(~ Excel 2003)のブック
今どき .xls 形式、という気もしますが、ギョームの世界では、昔作られた .xls ファイルが今も流通していたりするものです。
なので、まずは .xls 形式について説明します。
概要
そしてまたかという感じなのですが、とてもよい具合に概要をまとめてくれているページがあります。
- Excel 97-2003 ブック (*.xls) 形式概要 - OpenBook
http://mitsutakauomi.com/?p=193
これを読んだらだいたいわかると思います。
仕様書
ただ、先ほどのページは仕様書へのリンクが切れています。
そう、.xls 形式のブックには BIFF(Binary Interchange File Format)という仕様があり、Microsoft がそれを公開してくれています。
以下のページです。
- [MS-XLS]: Excel Binary File Format (.xls) Structure
http://msdn.microsoft.com/en-us/library/cc313154(v=office.12).aspx
ページ左側のリンクから Web 上で仕様を閲覧することもできますし、「Click here to view this version of the [MS-XLS] PDF.」というリンクをクリックすることで PDF 形式でダウンロードすることもできます。
1185 ページあるので、気合で通読してください。
……というのはさすがに冗談で、実際にはライブラリで発生したエラーや、(エラーは発生せず、黙ってデータが書き換えられてしまうといった場合)ライブラリのログやコードを読むなりデバッグするなりしてみて怪しい箇所に書いてあるキーワード(クラス名、変数名、コメント等)を手がかりに、仕様を検索して、見つかった項目を起点に掘り進んでいくことになるかと思います。
PDF だと検索しやすいので、ダウンロードするのがおすすめです。(といっても 40 MB あるので、検索するにももっさりしますが……)
ビューア
BIFF は、その名の通りバイナリ形式です。
つまり、仕様を理解したら、今度は .xls ファイルをバイナリエディタで開いて、バイナリを読む必要があります。
しんどすぎる!
というわけで、バイナリファイルをパースして(そこそこのレベルまで)構造化データとして人間が読めるようにしてくれる「OffVis」というツールを Microsoft が公開してくれています。
以下のページ最下部の「Office ビジュアライザー ツール (英語)」というリンクからダウンロードできます。
- Office バイナリ ファイル形式の理解
http://msdn.microsoft.com/ja-jp/library/office/gg615407%28v=office.14%29.aspx
便利ですね。
簡単な使用方法もこのページに書いてあるので、参照してください。
Tips : .xlsx 形式(OOXML)に変換してみる
とはいえ、それでもやっぱり、バイナリを読むのはしんどいものです。
問題のありそうなファイルを調べようというとき、OffVis を使ってできるのはある要素の位置を特定することまでで、詳細な値については、やはり地道に 16 進数を読む必要があります。
ふだん Java とかを使っている人は、たぶんバイナリを読むのに慣れていないことが多いので、つらいです。
ところで、ふだん Java とかを使っている人は、XML を読むのには結構慣れていたりします。
そこで、バイナリを読むのはやめて、XML に変換してしましょう。
そんなことができるのか?
できるといえば、できます。
このあと紹介する .xlsx 形式は、Excel 2007 以降で標準となった形式で、バイナリではなく、XML(OOXML - Office Open XML)として仕様が定められています。
つまり、Excel 2007 以降を使用して .xls ファイルを .xlsx ファイルとして保存し直すことで、OOXML の仕様において読むことが可能になります。
もちろん BIFF と OOXML とで仕様の各項目が一対一の対応関係を保っているわけではないですし、あまりお行儀のよくないファイルの場合、そのファイルの特徴的な箇所が Excel で保存することによって失われる可能性もあります。
そうした場合、保存しなおした OOXML を調べても、問題の原因は見つかりません。
とはいえ、試してみる分にはタダなので、「バイナリ読む前に OOXML にして読んでみる」というのは十分アリだと思います。バイナリよりは XML の方が人間にやさしいというのは否定しがたい事実です。
実際、私自身も OOXML にしたことでファイルの問題点がクリアになり、バイナリでも相当する箇所を調べることで、無事問題の原因を突き止めたことがあります。
余談 : 仕様書通りでないこともある
前述の通り、BIFF には Microsoft 謹製の仕様書が公開されているわけですが、さすがに長い歴史を持ったソフトだけあって、世間には仕様書の記述に合致しない .xls ファイルがちょいちょい流通しています。
そのようなファイルであっても Excel で開くと普通に開けたりするので、Microsoft が持っている秘伝のソースに入っている、特殊ケースに対応するための数々の回避コードが完全に仕様化されているというわけでは(もちろんというべきか)ないようです。
そういったケースにどう対応するかは、パッケージソフトウェアベンダーとしてのスタンスや契約の問題にもなってくると思いますが、時には「Excel で読み書きできるものは読み書きできるように(仕様書の記述にも違反しない範囲で)どうにかする」という厳しい道のりを歩むことになるかもしれません。(実際、やったことがあります……)
.xlsx 形式(2007 ~)のブック
というわけで、今度は Excel 2007 以降で標準の保存形式となった .xlsx 形式について説明します。
概要
概要については、やはり先ほどのサイトを参照させてもらうことにしましょう。
- Excel ブック (*.xlsx) 形式概要 - OpenBook
http://mitsutakauomi.com/?p=362
これを読んだら、だいたいわかります。
仕様
今度は先ほどのページからも正しくリンクされていますが、仕様書が ECMA(!)のページからダウンロードできます。
- Standard ECMA-376 Office Open XML File Formats
http://www.ecma-international.org/publications/standards/Ecma-376.htm
BIFF の仕様書は 1000 ページ余りありましたが、OOXML の仕様書はというと、1st edition の Part 1 ~ Part 5 まででおよそ 5500 ページあります。
……。
……と、とはいえ、OOXML には Word や PowerPoint の仕様も含まれるので、Excel に関係のある部分は多めに見積もっても半分以下といったところでしょう。
2000 ページくらいでしょうか。
これも全部通して読むのはしんどすぎますが、やはり関係のありそうな箇所をキーワードで検索して読む、という方法が取れます。
詳細な仕様が書かれているのは Part 4 なので、検索するとしたら Part 4 になると思いますが、概要を掴みたい場合はまず Part 1 の該当項目を読むとよいです。(※ Part は 1st Edition の場合)
コメントとか、セルの属性として定義されているのかと思いきや、シートとは別のファイルに定義されていたり、コメントの枠の描画はまた別の VML という形式で行っていたりと思いのほかアクロバティックで、Part 1 を読んで各ファイル間の関係を頭に入れてないと、いきなり Part 4 で仕様の詳細を見てもよくわからず、結構しんどかったりします。
なお、OOXML については日本語の書籍も出版されています。
私は以下の本を買ったのですが、シンプルで要点がおさえられていて、ECMA の仕様書だけを頼りにするのと比べたら、入門フェーズをだいぶショートカットできたと思います。オススメです。
- 入門Office Open XML
https://www.amazon.co.jp/dp/4797338725/
※残念ながら品切れです……。古本で定価を大幅に超える価格を出して買うべき、とまでは言えないように思います。
まとめ
Excel ブックを読み書きする方法について、
- 他力(ライブラリを使用する方法)
- 自力(仕様書を読んでどうにかする方法)
- .xls 形式(~ Excel 2003)
- .xlsx 形式(Excel 2007 ~)
のそれぞれをご紹介しました。
最後に、最近は Trello をヒットさせた Fog Creek Software の CEO にして、かつて Microsoft で Excel を作っていたこともある、 Joel Spolsky のブログをご紹介しておきましょう。
- Why are the Microsoft Office file formats so complicated? (And some workarounds)
http://www.joelonsoftware.com/items/2008/02/19.html
Office ドキュメントと格闘することに対する workarounds として、以下のような方法が提案されています。
-
Let Office do the heavy work for you
(超要約)Office のファイルを自前で読み書きしようみたいなことは考えずに、COM を使って Office 自身にやらせたらよい。 -
Use a simpler format for writing files
(超要約)そもそも Office のファイルを自動で読み書きしようみたいなことは考えずに、CSV なり HTML なり使ったらよい。
仕様書の巨大さにも負けず、幸せな Excel ライフをお過ごしください。