ASP.NETでExcelシート(XMLスプレッドシート)を生成する
昔と違ってオートメーションで苦労することは無くなった。
今であればOpenXML APIを使う、LINQ to XMLを使う、XPath+XSLを使う、等、方法としてはいろいろな選択しがあると思うが、一番簡単なのは以下の方法。
1. Excel(2003以降)で実際に使用するワークシートを作る(これを雛形にする)
2. XMLスプレッドシート(Excel 2007ではXMLスプレッドシート 2003)形式で保存する※
3. 保存したXMLスプレッドシートをテキストエディタ等で開く
4. ASP.NETのビューページ(Download.aspx)を生成してコンテンツ部分にXMLスプレッドシートを貼り付ける
- Download.aspxの冒頭
これでOK。ビューをレンダリングすればXMLスプレッドシートのダウンロードが開始される。
- AddressControler.cs
public ActionResult Download() { return View("Download"); }
ダウンロード時にExcelを起動したいのならビュー側でMIMEを指定すれば良い。(コントローラ側で指定しても何故か上手くいかない。ビューの初期化でヘッダを設定しているのか?)
<%@ Page Language="C#" ContentType="application/vnd.ms-excel" 〜
また、このXMLスプレッドシートをテンプレートとして、特定の行(Row)やセル(Cell)を置き換えることで、ダイナミックにExcel帳票を作成することもできる。
- AddressControler.cs
public ActionResult Download() { //LINQ to SQLでAddressオブジェクトのリストを作る var addresses = service.FindAllAddresses().ToList(); return View("Download", addresses); }
- Download.aspx
<%@ Page Language="C#" ContentType="application/vnd.ms-excel" Inherits="System.Web.Mvc.ViewPage<IEnumerable<AddressBook.Models.Address>>" %> 〜 <Worksheet ss:Name="Sheet1"> <!-- 行数をモデルの行数+5に設定(5はヘッダ行数) --> <Table ss:ExpandedColumnCount="6" ss:ExpandedRowCount="<%= Model.Count()+5 %>" x:FullColumns="1" 〜 <!-- 行データをモデルオブジェクトのリストで置き換える --> <% foreach (var item in Model) { %> <Row ss:AutoFitHeight="0"> <Cell><Data ss:Type="String"><%=item.Name.TrimEnd()%></Data></Cell> <Cell><Data ss:Type="String"><%=item.Address.TrimEnd()%></Data></Cell> <Cell><Data ss:Type="String"><%=item.Email.TrimEnd()%></Data></Cell> <Cell><Data ss:Type="String"><%=item.Gender.TrimEnd()%></Data></Cell> <Cell><Data ss:Type="String"><%=item.Married.TrimEnd()%></Data></Cell> <Cell><Data ss:Type="String"><%=item.UpdDate.ToString("s").TrimEnd()%></Data></Cell> </Row> <% } %>
ASP.NET MVCのジェネリクスによって強く型付けされたViewPageクラスは、上のようにモデルのプロパティを直接扱えるので便利だ。
※OpenXMLがISO標準に認定されたこともあり、XMLスプレッドシート2003の今後には不安が残るのがこの方法の弱点だ。その場合は大人しくOpenXMLを使うべきなんだろうが、JSP同様、コンテンツをビューの雛形として使うのは楽ちんなんだよなぁ。(OpenXMLはパッケージを開けてみないと分らないしコピペもできない)