HTML 使って Excel を出力してみる

ってことで、色々調べてみました。

あんまり日本語の文献が無かったので四苦八苦したのは内緒。

結論としては、かなり柔軟に Excel を出力出来ることが判明。

ってことで、以下本文。


普通は、ExcelSpreadSheet とか使ってゴリゴリ書いて行くと思う。

いや、普通かどうかは知らないけど。

でも、弊社では今回は Excel なレスポンスヘッダを出力して、ストリームから吐き出す方法を採用。

んで、その Excel の中身ってのが実はただの HTML だったりする。

勿論、この方法で作れるのはただのテキストデータな HTML なので、iWork な Numbers では当然のように開けない。

が、まぁ、大半のユーザは Microsoft Office スイーツな Excel を使っていると思うので、まぁ、良いかってことで。

手法としては、ひたすらデカい table タグを構築して Excel のブックやらワークシートやらを再現するってこと。

んで、これが結構優れたもので、MSOffice 専用の Style Sheet とか特殊な記法の XML とかを部分挿入することで、完璧に (?) Excel の機能を再現出来るっぽい。

例えば、mso- で始まるスタイルシートを例に取ると、

mso-number-format: '\0022\\\0022\#\,\#\#0\;\0022\\\0022\\-\#\,\#\#0';

ってのは、金額形式での出力に対応してる。

とか、

br {
  mso-data-placement: same-cell;
}

ってのは、改行タグ (br) がある場合に、Windows 版の Excel で言うところの Alt + Enter な改行を実現出来たりとか。

相当細かく用意されてるっぽい。

んで、XML の方は

<!--[if gte mso 9]>
<xml>
  <x:ExcelWorkbook>
    <x:ExcelWorksheets>
      <x:ExcelWorksheet>
        <x:Name>シート名</x:Name>
        <x:WorksheetOptions>
          <x:DefaultRowHeight>270</x:DefaultRowHeight>
          <x:FitToPage/>
          <x:FitToPage/>
          <x:Print>
            <x:FitHeight>0</x:FitHeight>
            <x:ValidPrinterInfo/>
            <x:PaperSizeIndex>9</x:PaperSizeIndex>
            <x:HorizontalResolution>600</x:HorizontalResolution>
            <x:VerticalResolution>600</x:VerticalResolution>
          </x:Print>
          <x:Selected/>
          <x:DoNotDisplayGridlines/>
          <x:ProtectContents>False</x:ProtectContents>
          <x:ProtectObjects>False</x:ProtectObjects>
          <x:ProtectScenarios>False</x:ProtectScenarios>
        </x:WorksheetOptions>
      </x:ExcelWorksheet>
    </x:ExcelWorksheets>
    <x:ProtectStructure>False</x:ProtectStructure>
    <x:ProtectWindows>False</x:ProtectWindows>
  </x:ExcelWorkbook>
</xml>
<![endif]-->

こんな感じで定義してあげるとシート名とか縦横の幅とかシートの保護とかグリッドの表示とかを制御出来たりするらしい。

あ、もちろん、html タグの xmlns でネームスペースを指定したげないと、x: なネームスペースの解釈が出来ないから駄目だけどね。

実際に Excel を html で保存して、ソース読むとかなり面白い。

それこそ根性入れれば、マクロとかも組み込めるんじゃないかな?わかんないけど。

とりあえず何でも出来るってことは分かったんだけど、実際にプロダクションレベルで使えるかどうかってのは別問題なんだけどね。

セキュリティ的に云々ってのも勿論そうだし、そもそも Excel のバージョン依存が相当激しいと思うので、その辺を吸収出来れば素敵なんだろうね。

ライブラリとか作れると格好良いんだろうけど…。

まぁ、それは時間あるとき (なんて在るのか!?) にでもチョコチョコ書いてみるか。