テキスト ファイルを動的に生成する

テキスト ファイルを動的に生成するサンプルをご紹介します。

samples.zip

 

sample98.ashx

   1:  <%@ webhandler language="C#" class="sample98" %>
   2:   
   3:  using System;
   4:  using System.Web;
   5:   
   6:  public class sample98 : IHttpHandler
   7:  {
   8:      public void ProcessRequest(HttpContext context)
   9:      {
  10:          context.Response.ContentType = "text/plain";
  11:          context.Response.Write("テキスト ファイル動的生成" + Environment.NewLine);
  12:          context.Response.Write(DateTime.Now + "\r\n");
  13:          context.Response.Flush();
  14:      }
  15:   
  16:      public bool IsReusable
  17:      {
  18:          get { return true; }
  19:      }
  20:  }

難しいことを考えず、テキスト ファイルを動的生成する際の決まり切った型 (パターン) だと思ってこのコードを眺めてください。

11 ~ 12 行目でテキスト文字列を出力しています。

11 行目の Environment.NewLine とは "\r\n" と同じでいずれも改行 (16 進で 0d 0a) を表します。

このサンプルの 18 行目では true を返しています。sample98 クラスのインスタンスを再利用してよいなら true で、再利用してはならないなら false を返してください。考えるのが面倒ならとりあえず false を返しておけば大丈夫だと思います。そのあたりの解説は http://mvolo.com/blogs/serverside/archive/2007/08/15/Developing-IIS7-web-server-features-with-the-.NET-framework.aspx を読んでください。

The IsReusable() indicates whether or not your handler instance can be re-used for subsequent requests. In some cases, after processing the request your handler may be in an incorrect state to process another request, especially if you have stored data about the previous request in member variables. Note that the runtime will never use the same instance of your handler to process two requests at the same time, even if its marked as reusable. If your handler does not store any per-request state in member variables and can have its ProcessRequest function called as many times as needed, make this property return true to allow reuse.

動いているのを見るなら、ここ をクリック。

 

sample99.ashx

sample98 を改造し、SQL Server データベースに格納されている情報をテキストとして返すようにしてみました。

   1:  <%@ webhandler language="C#" class="sample99" %>
   2:   
   3:  using System;
   4:  using System.Web;
   5:  using System.Data;
   6:  using System.Data.SqlClient;
   7:   
   8:  public class sample99 : IHttpHandler
   9:  {
  10:      public void ProcessRequest(HttpContext context)
  11:      {
  12:          context.Response.ContentType = "text/plain";
  13:          DataTable dt = GetTable();
  14:          CreateText(context, dt);
  15:          context.Response.Flush();
  16:      }
  17:   
  18:      public bool IsReusable
  19:      {
  20:          get { return true; }
  21:      }
  22:   
  23:      private DataTable GetTable()
  24:      {
  25:          string CONNECTION_STR = "Data Source=mssql2008; Integrated Security=True; database=DB_wendies_humberger; ";
  26:          string QUERY = "select * from dbo.employee";
  27:          var con = new SqlConnection(CONNECTION_STR);
  28:          var cmd = new SqlCommand(QUERY, con);
  29:          var adap = new SqlDataAdapter(cmd);
  30:          var dt = new DataTable();
  31:   
  32:          using (con)
  33:          {
  34:              adap.Fill(dt);
  35:          }
  36:   
  37:          return dt;
  38:      }
  39:      
  40:      private void CreateText(HttpContext context, DataTable dt)
  41:      {
  42:          int column_count = dt.Columns.Count;
  43:          foreach (DataRow row in dt.Rows)
  44:          {
  45:              string line = "";
  46:              for (int i = 0; i < column_count; i++)
  47:              {
  48:                  line = line + row[i] + "\t";
  49:              }
  50:              context.Response.Write(line + Environment.NewLine);
  51:          }
  52:      }
  53:  }

5 行目でインポートしている System.Data 名前空間にはデータベース処理用の便利部品が詰まっています。

6 行目でインポートしている System.Data.SqlClient 名前空間には MS SQL Server 処理用の便利部品が詰まっています。

25 行目はデータベース接続情報です。お使いの環境に合わせて、都度適切に変更してください。

26 行目はデータを取り出す SQL SELECT 文。

27 行目で、MS SQL Server 接続用のオブジェクトを作っています。

28 行目で、クエリーを投げるためのオブジェクトを作っています。

29 行目は、手抜きするための楽々部品 (DataAdapter) を作っています。

30 行目では、データ受け取り用の器 (DataTable) を作っています。

34 行目では SELECT の結果を DataTable に注ぎ込んでいます。SqlDataAdapter の Fill() は自動的に DB 接続の Open をやってくれる (実は Close もやってくれる) ので、34 行目の直前に con.Open() と記述する必要はありません。34 行目の直後に con.Close() と記述する必要もありません。

42 行目では SELECT の結果得られた列数を取り出しています。

50 行目でテキストを出力しています。

動いているのを見るなら、ここ をクリック。

 

参考になるページ

@ WebHandler

IHttpHandler インターフェイス (System.Web)

Environment.NewLine プロパティ (System)

HttpResponse.ContentType プロパティ (System.Web)

System.Data 名前空間 ()

System.Data.SqlClient 名前空間 ()

SqlDataAdapter.Fill メソッド (System.Data.SqlClient)