SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

特集記事

オートメーション機能を利用しないExcel形式でのWeb帳票印刷

Excel 2003のXML形式ファイルを利用した帳票ソリューション


  • X ポスト
  • このエントリーをはてなブックマークに追加

Excel 2003のXML形式で保存したファイルを活用する帳票ソリューションの構築サンプルを紹介します。この手法では、Excelのオートメーション機能を利用する必要がないため、実装の手間を軽減することができます。

  • X ポスト
  • このエントリーをはてなブックマークに追加

はじめに

 社内で利用する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ファイルと同じものに見えると思います。

サンプルExcelファイル(「sample.xml」)
サンプルExcelファイル(「sample.xml」)

 同じファイルをメモ帳で開けば、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つのファイル内に記述しています。

test.aspx
<%@ 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クラスとして読み込んでいます。

XMLファイルの読み込み
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ファイル自身が自動的に作成するテキストデータもあるため、そういったデータを誤って置き換えてしまうことが無いように、データのキー項目を注意して決定する必要があります。この点に注意して、ぜひいろいろな応用例を考えてみてください。

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
特集記事連載記事一覧

もっと読む

この記事の著者

小野 修司(オノ シュウジ)

MVP for Visual Developer - Visual C#あおい情報システム株式会社勤務。.NETに関する話題を扱う「どっとねっとふぁん」を運営。 

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/194 2008/08/26 14:01

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング