はじめに
社内で利用するWebアプリケーションにおいては、帳票印刷を実現する方法としてExcelファイルが利用されることがあります。このとき普通は、Excelが持つオートメーション機能を利用して実装するため、Excelをサーバ上にインストールして操作するか、Internet Explorer上でスクリプトを利用してExcelファイルを操作する方法が採られることが多いようです。
この記事ではExcel 2003のファイルをXML形式で保存し、そのファイルを利用して帳票印刷を実現する方法を紹介します。
対象読者
.NET Frameworkを用いてWebアプリケーションを開発している方。
必要な環境
- ASP.NETが実行できるWindows XP、またはWindows 2003 Server。
- クライアント側のマシンにExcel 2003がインストールされていること。
XML形式で保存したExcelファイルの確認
Excel 2003がインストールされているマシンで、サンプルファイルに含まれる「sample.xml」をダブルクリックしてください。XMLファイルであるにもかかわらず、通常のExcelファイルと同じものに見えると思います。
同じファイルをメモ帳で開けば、XML形式の単なるテキストファイルであることがわかります。しかし、このようにExcelで開けば、シートの保護といった設定もきちんと保持されているExcelファイルとして利用できます。このExcelファイルでは、以下の項目を設定しています。
項目 | 意味 |
user | 入力される顧客名で置き換えられます。縮小して全体を表示する設定にしています。 |
meisai1 | 入力される品名で置き換えられます(meisai2、meisai3も同じ)。 |
100 | 入力される数量で置き換えられます。書式指定は「#,###」です(200、300も同じ)。 |
110 | 入力される単価で置き換えられます。書式指定は「#,###」です(220、330も同じ)。 |
111 | 入力される金額で置き換えられます。書式指定は「#,###」です(222、333も同じ)。 |
請求金額 | 金額の合計額を表示します。 |
これらの設定は、シートの保護をはずせば確認できます。
サンプルアプリケーションの実行
サンプルファイルの「test.aspx」と「sample.xml」を「C:\Inetpub\wwwroot」フォルダにコピーし、http://localhost/test.aspxにアクセスしてください。
上記の画面が表示されたらそれぞれの入力欄に適当な値を入力してください。サンプルアプリケーションでは数量、単価、金額の項目には必ず半角の数字を入力する必要があります。また、数量と単価から金額を計算するようにはなっていませんので、入力したままの数字が表示されます。ここでは以下のように入力してみました。
[印刷]ボタンをクリックすると、ファイルのダウンロードウィンドウが表示されます。ここで[開く]ボタンをクリックすると、Excelが起動して次の画面が表示されます。
サンプルアプリケーションのソース
サンプルアプリケーションは処理の記述を単純化するために、エラー処理などを省き、またコードもユーザインタフェース部分も1つのファイル内に記述しています。
<%@ Page Language="C#" %> <%@ Import NameSpace="System.Xml" %> <html> <head> <script runat="server"> // 印刷ボタンクリック時の動作 void button_Click(object sender, EventArgs e) { XmlDocument doc = new XmlDocument(); doc.Load(Server.MapPath("sample.xml")); XmlNodeList datalist = doc.SelectNodes("descendant::text()"); foreach(XmlNode data in datalist) { switch(data.Value) { case "user": data.Value=user.Text; break; case "meisai1": data.Value=meisai1.Text; break; case "100": data.Value=suryo1.Text==""?"0":suryo1.Text; break; case "110": data.Value=tanka1.Text==""?"0":tanka1.Text; break; case "111": data.Value=kingaku1.Text==""?"0":kingaku1.Text; break; case "meisai2": data.Value=meisai2.Text; break; case "200": data.Value=suryo2.Text==""?"0":suryo2.Text; break; case "220": data.Value=tanka2.Text==""?"0":tanka2.Text; break; case "222": data.Value=kingaku2.Text==""?"0":kingaku2.Text; break; case "meisai3": data.Value=meisai3.Text; break; case "300": data.Value=suryo3.Text==""?"0":suryo3.Text; break; case "330": data.Value=tanka3.Text==""?"0":tanka3.Text; break; case "333": data.Value=kingaku3.Text==""?"0":kingaku3.Text; break; } } Response.ContentType="application/ms-excel"; Response.AddHeader( "content-disposition","attachment; filename=sample.xls"); doc.Save(Response.OutputStream); Response.End(); } </script> </head> <body> <form runat="server"> 顧客名:<asp:textbox id="user" runat="server"/><br><br> <table border="1"> <tr><td>品名</td><td>数量</td><td>単価</td><td>金額</td></tr> <tr><td><asp:textbox id="meisai1" runat="server"/></td> <td><asp:textbox id="suryo1" runat="server"/></td> <td><asp:textbox id="tanka1" runat="server"/></td> <td><asp:textbox id="kingaku1" runat="server"/></td></tr> <tr><td><asp:textbox id="meisai2" runat="server"/></td> <td><asp:textbox id="suryo2" runat="server"/></td> <td><asp:textbox id="tanka2" runat="server"/></td> <td><asp:textbox id="kingaku2" runat="server"/></td></tr> <tr><td><asp:textbox id="meisai3" runat="server"/></td> <td><asp:textbox id="suryo3" runat="server"/></td> <td><asp:textbox id="tanka3" runat="server"/></td> <td><asp:textbox id="kingaku3" runat="server"/></td></tr> </table> <br> <asp:button id="Button1" Text = "印刷" runat="server" OnClick="button_Click" /> </form> </body> </html>
サンプルアプリケーションの動作の解説
サンプルアプリケーションでは、[印刷]ボタンがクリックされたときに、まず「sample.xml」ファイルをXmlDocument
クラスとして読み込んでいます。
XmlDocument doc = new XmlDocument(); doc.Load(Server.MapPath("sample.xml"));
そして、XPath式を使ってXMLファイルの中の全てのテキストデータをとりだします。
XmlNodeList datalist = doc.SelectNodes("descendant::Data/text()");
このテキストデータの値をチェックして、入力されたデータで置き換えていきます。数値データ(例えば「100」)に対しては、入力されたデータが空の場合は「0」に置き換えている点に注意してください。
// テキストデータを一つづつ取り出してチェックする foreach(XmlNode data in datalist) { switch(data.Value) { // "user"を入力された顧客名に置き換える case "user": data.Value=user.Text; break; // "meisai1"を入力された品名に置き換える case "meisai1": data.Value=meisai1.Text; break; // "100"を入力された数量に置き換える case "100": data.Value=suryo1.Text==""?"0":suryo1.Text; break; ...
最後にファイルをダウンロードします。ファイルのダウンロード時には、ダウンロードするデータのMIME Typeを指定する必要があります。また、ファイル名を指定して、XmlDocumentをSaveしています。
// Excel形式を指定 Response.ContentType="application/ms-excel"; Response.AddHeader( "content-disposition","attachment; filename=sample.xls"); // XmlDocumentをOutputStreamに書き出す doc.Save(Response.OutputStream); // Responseを閉じる Response.End();
まとめ
ここで紹介した方法の最大の特徴は「Excelのオートメーション機能を利用する必要がない」という点です。.NETアプリケーションからExcelの操作を行った場合、Excelを正常に終了させるためには細かい注意が必要で、掲示板やメーリングリストでよく取り上げられる話題になっています。こういった注意を払わずに済み、また処理も軽いというのがこの方法の利点といえるでしょう。
ただし、この方法をとる上で注意しなければいけない点が一点だけあります。この方法ではXMLファイル内のテキストデータの文字列を入力されたデータで置き換えています。このXMLファイル内のテキストデータにはExcelファイル自身が自動的に作成するテキストデータもあるため、そういったデータを誤って置き換えてしまうことが無いように、データのキー項目を注意して決定する必要があります。この点に注意して、ぜひいろいろな応用例を考えてみてください。