最近のトラックバック

2017年10月
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31        

Google AdSense2

ASP.NETサンプル

ASP.NET(C#)でIEのファイルダウンロードダイアログボタンをカスタマイズ(その3)

IEによるファイルダウンロードダイアログボタンのカスタマイズ続々編です。
今回はIE8限定技です。



前回前々回では、 は、metaタグでDownloadOptionsを指定して、ファイルダウンロードダイアログの「開く」「保存」ボタンの表示/非表示の制御を行った。
今回はIE8限定となるが、HTMLヘッダー内でファイルダウンロードダイアログの「開く」ボタンの表示/非表示を制御する技です。

ポイントはファイルダウンロード処理内で以下のヘッダー情報を挿入するだけ。
-- 「開く」ボタンを非表示
Response.AddHeader("X-Download-Options", "noopen");
-- 通常のボタン構成で表示
Response.AddHeader("X-Download-Options", "nomal");


■X-Download-Options="noopen"

■X-Download-Options="nomal"

参考ページ:
2008/7/2 - Internet Explorer 8 のセキュリティ : 総合的な保護

この技だと 前回前々回 と異なり、サーバサイドで処理が完結する。
反面、「IE8以上」・「保存ボタンの非表示が出来ない」等の限定条件がある。


実行結果の確認






ASP.NET(C#)でIEのファイルダウンロードダイアログボタンをカスタマイズ(その2)

以前紹介したASP.NET(C#)でIEのファイルダウンロードダイアログのボタンをカスタマイズの続編です。
内容はASP.NETオンリー処理を、ボタンクリックイベント時にJavaScript経由でファイルダウンロードダイアグをカスタマイズするように変更しただけだけど...

※2010/03/15に続々編(IE8限定技)を追加
ASP.NET(C#)でIEのファイルダウンロードダイアログボタンをカスタマイズ(その3)



IEのファイルダウンロードダイアログには「開く」「保存」「キャンセル」ボタンがあるが、metaタグでDownloadOptionsを指定すると「開く」「保存」ボタンを非表示に設定できる。
詳細は前回を参照。



前回から、、ボタンクリックイベント時にJavaScript経由で<meta name="DownloadOptions" />のcontent属性の設定するように変更しています。

実行結果の確認




IE8プロセス間のセッション共有問題と共有解除

Internet Explorer 8(IE8)のプロセス間のセッション共有問題と解決策ついて書いてみた。



以下ページからIE8では別プロセスでもセッション共有する仕様変更があることを知った。

IE 8 では別プロセスのウィンドウでもセッションを共有するらしい: あるSEのつぶやき
[Browser]IEのウィンドウごとのセッション共有・非共有

以前IE6限定のASP.NETアプリを作った際に1つのプロセスで2画面以上起動するとセッション共有する問題にぶつかり、 解決案として別プロセスを起動することを提案したことがあったが、この方法が使えなくなってしまった。

というわけでIE8でセッションを共有させない方法を調べてみた。



ひとまずIE8は置いておき、各種ブラウザでプロセス間セッション共有を調べてみた。

ブラウザ+バージョン プロセス間セッション共有 備考
IE6 共有しない -
IE7 共有しない -
IE8 共有する -
Firefox 3.5.4 共有する プロセスの複数起動は不可能?
Opera 10.01 共有する プロセスの複数起動は不可能?
Google Chrome 3.0.19 共有する -
※簡易調査のため間違いや情報不足があるかも知れません。


※以下ページで動作確認しています。
セッション共有確認 - Oncemail Sample Code



IE8のメニューからセッション共有を解除する方法について記述する。

■手順
(1)IE8を起動後、Altキーを押しメインメニューを表示する。
(2)「ファイル」→「新規セッション」をメニューを選択し、新しいウィンドウを起動。
(3)アドレスバーに該当URLを入力。


※以下ページで動作確認できます。
セッション共有確認 - Oncemail Sample Code


ショートカットファイルからセッション共有を解除する方法について記述する。

■手順
(1)適当な場所にショートカットファイルを作成する。
(2)ショートカットファイルのプロパティで「リンク先」に以下の設定を行う。
"C:\Program Files\Internet Explorer\iexplore.exe" -nomerge <URL [例]ttp://yahoo.co.jp>
(3)以後セッション共有させたくないサイトを閲覧する場合は上記ショートカット経由でIE8を起動する。


※以下ページで動作確認できます。
セッション共有確認 - Oncemail Sample Code




ASP.NET(C#)でIEのファイルダウンロードダイアログボタンをカスタマイズ

ASP.NET(C#)でIEのファイルダウンロードダイアログのボタンをカスタマイズしてみた。

※2010/02/03 続編(本サンプルの一部をJavaScript化)を追加
ASP.NET(C#)でIEのファイルダウンロードダイアログボタンをカスタマイズ(その2)
※2010/03/15 続々編(IE8限定技)を追加
ASP.NET(C#)でIEのファイルダウンロードダイアログボタンをカスタマイズ(その3)



IEのファイルダウンロードダイアログには「開く」「保存」「キャンセル」ボタンがあるが、以下のmetaタグを用意すると「開く」「保存」ボタンを非表示にできる。

※Windows XP SP2 付属のIE6以降のバージョンで対応。
参考: content Property (META, HTMLMetaElement Constructor) - MSDN ライブラリ


■content=""

■content="noopen"

■content="nosave"

他ブラウザで対応していないため用途は限定されるが、社内ネットワークでIEを標準ブラウザとしている等の限定条件が重なれば「ファイルを開かせたくない」「ファイルを保存されたくない」等の要望はあるはずだ。



上記機能とASP.NETを連携してファイルダウンロードダイアログのボタンを制御するサンプル。

実行結果及びASP.NETソースコードの確認




ASP.NET(C#)でIEにOfficeドキュメントを表示

ASP.NET(C#)でIEにOfficeドキュメントを表示するサンプルを作成してみた。

【注意】
※本内容ではGoogleドキュメント等のWebアプリケーションの利用は考慮していません。
※本内容はクライアントPCにIEとMicrosoft Officeがインストールされていることを前提に書いています。
※クライアントPCにインストールされているMicrosoft Officeのバージョンによってデフォルトの挙動が異なります。挙動の違いはブラウザ上にExcel・Word・PowerPointドキュメントを表示/非表示する設定を調べてみたを参照してください。
※本内容はIEを取り扱っていますが、IE Tab :: Firefox Add-onsを組み込んだFirefoxでも同様な結果になることを確認しています。
※CSVやPDF等の他形式のバイナリファイルをブラウザ表示する方法についてはASP.NET(C#)でバイナリファイルをブラウザ表示を参照してください。



メインソースコードは以下の通り

// Response情報クリア
Response.ClearContent();
// HTTPヘッダー情報設定
Response.ContentType = {ここにMIMEを設定 };
// ファイル書込
Response.WriteFile(sFilePath);
// レスポンス終了
Response.End();


MIMEの一例を挙げると以下の通り。
Officeアプリケーション 一般的なファイル拡張子 MIMEタイプ
Microsoft Word .doc,.docx application/msword
Microsoft Excel .xls,.xlsx application/msword
Microsoft Power Point .ppt,.pptx application/vnd.ms-powerpoint

※他にx-application/~、applicathion/~等のMIMEがあります。
※CSVやPDF等の他形式のバイナリファイルをブラウザ表示する方法についてはASP.NET(C#)でバイナリファイルをブラウザ表示を参照してください。


IEにOfficeドキュメントを表示するサンプルソースを記述する。
なお使い勝手の関係で処理を「Officeドキュメントを開くページ(BinaryFile2Open.aspx)」「Officeドキュメントを表示する画面ページ(BinaryFile2.aspx)」の2ページに分割している。

※クライアントPCにインストールされているMicrosoft Officeのバージョンによってデフォルトの挙動が異なります。挙動の違いはブラウザ上にExcel・Word・PowerPointドキュメントを表示/非表示する設定を調べてみたを参照してください。

BinaryFile2Open.aspx
実行結果及びASP.NETソースコードの確認


<%@ Page Language="C#" Title="IEでOfficeドキュメントを開く" AutoEventWireup="true" %>
 :
 :
<asp:Content ID="ct" ContentPlaceHolderID="cpf1" runat="server">
<script type="text/javascript">
    /// <summary>
    /// [javascript]ダウンロードページを新規ウィンドウで開く
    /// </summary>
    /// <param name="sUrl">ダウンロードページのURL</param>
    function OpenWindow(sUrl)
    {
        window.open(sUrl, "", "");
    }
    /// <summary>
    /// [javascript]ダウンロードページをiframeタグ内で開く
    /// </summary>
    /// <param name="sUrl">ダウンロードページのURL</param>
    function InsertIFrame(sUrl)
    {
        document.getElementById('ifDownloadPage').contentWindow.location.href = sUrl;
    }
</script>
<script runat="server">
    /// <summary>
    /// Word97-2003ファイルを開く
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void btnDoc_Click(object sender, EventArgs e)
    {
        fnBinaryFileOpen("doc");
    }
    /// <summary>
    /// Word2007ファイルを開く
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void btnDocx_Click(object sender, EventArgs e)
    {
        fnBinaryFileOpen("docx");
    }
    /// <summary>
    /// Excel97-2003ファイルを開く
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void btnXls_Click(object sender, EventArgs e)
    {
        fnBinaryFileOpen("xls");
    }
    /// <summary>
    /// Excel2007ファイルを開く
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void btnXlsx_Click(object sender, EventArgs e)
    {
        fnBinaryFileOpen("xlsx");
    }
    /// <summary>
    /// PowerPoint97-2003ファイルを開く
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void btnPpt_Click(object sender, EventArgs e)
    {
        fnBinaryFileOpen("ppt");
    }
    /// <summary>
    /// PowerPoint2007ファイルを開く
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void btnPptx_Click(object sender, EventArgs e)
    {
        fnBinaryFileOpen("pptx");
    }
    /// <summary>
    /// ファイルを開く
    /// </summary>
    /// <param name="sFileName"></param>
    /// <param name="sMIME"></param>
    public void fnBinaryFileOpen(string sFileType)
    {
        // 指定形式でJavaScript登録
        string sScript = "<script type='text/javascript'>";
        if (rblOpenPlace.SelectedValue == "window")
        {
            sScript += string.Format(
                "OpenWindow('BinaryFile2.aspx?FileType={0}&time={1:HHmmss}');",
                sFileType, DateTime.Now);
        }
        else
        {
            sScript += string.Format(
                "InsertIFrame('BinaryFile2.aspx?FileType={0}&time={1:HHmmss}');",
                sFileType, DateTime.Now);
        }
        sScript += "<" + "/script>";
        // JavaScript登録
        ClientScript.RegisterStartupScript(GetType(), "fnBinaryFileOpen", sScript);
    }
</script>
<h1>IEでOfficeドキュメントを開く</h1>
<!-- コンテンツ説明 -->
<div class="contents_info">
    ASP.NETからIEIEでWord/Excel/PowerPoint等のOfficeファイルを開くサンプルです。<br />
    <br />
    ※クライアントPCにIEとOffice2000~2007がインストールされている場合に限ります。<br />
    ※OfficXP(Office2002)以前のバージョンのOfficeでは~2007ファイルは開けません。<br />
    ※Offic2007ではブラウザ内にドキュメントが表示されず、外部にOfficeアプリケーションが開くことがあります。<br />
    この現象は以下を参照してください。<br />
    <a href="http://niyodiary.cocolog-nifty.com/blog/2009/08/excelwordpowerp.html">ブラウザ上にExcel・Word・PowerPointドキュメントを表示/非表示する設定を調べてみた - niyoな日記</a><br />
</div>
<!-- コンテンツ -->
<asp:RadioButtonList id="rblOpenPlace" runat="server" RepeatDirection="Horizontal">
    <asp:ListItem Text="iframeで開く" Value="ifame" Selected="True" />
    <asp:ListItem Text="新規ウィンドウで開く" Value="window" />
</asp:RadioButtonList>
<asp:Button ID="btnDoc" runat="server" Text="Word97-2003ファイルを開く"  onclick="btnDoc_Click" /><br />
<asp:Button ID="btnDocx" runat="server" Text="Word2007ファイルを開く"  onclick="btnDocx_Click" /><br />
<asp:Button ID="btnXls" runat="server" Text="Excel97-2003ファイルのを開く"  onclick="btnXls_Click" /><br />
<asp:Button ID="btnXlsx" runat="server" Text="Excel2007ファイルを開く" onclick="btnXlsx_Click" /><br />
<asp:Button ID="btnPpt" runat="server" Text="PowerPoint97-2003ファイルを開く" onclick="btnPpt_Click" /><br />
<asp:Button ID="btnPptx" runat="server" Text="PowerPoint2007ファイルを開く" onclick="btnPptx_Click" /><br />
<br />
<iframe id="ifDownloadPage" style=" width:100%; height: 400px;"></iframe>
 :
 :

BinaryFile2.aspx


<%@ Page Language="C#" Title="Officeドキュメント表示" AutoEventWireup="true" %>
<%@ Import Namespace="System.IO" %>
<script runat="server">
    /// <summary>
    /// ページロード
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void Page_Load(object sender, EventArgs e)
    {
        string sFileType;   // ファイルタイプを取得
        string sFileName;   // ファイル名
        string sFilePath;   // ファイルパス
        string sMIME;       // MIME
        //-----------------------------------------------------------------------------------------
        // クエリ引数からファイルタイプ取得
        //-----------------------------------------------------------------------------------------
        sFileType = Request.QueryString["FileType"];
        //-----------------------------------------------------------------------------------------
        // ファイルタイプからファイル名とMIMEを設定
        //-----------------------------------------------------------------------------------------
        switch (sFileType)
        {
            case "doc":
                sFileName = "Word2003ファイル.doc";
                sMIME = "application/msword";
                break;
            case "docx":
                sFileName = "Word2007ファイル.docx";
                sMIME = "application/msword";
                break;
            case "xls":
                sFileName = "Excel2003ファイル.xls";
                sMIME = "application/vnd.ms-excel";
                break;
            case "xlsx":
                sFileName = "Excel2007ファイル.xlsx";
                sMIME = "application/vnd.ms-excel";
                break;
            case "ppt":
                sFileName = "PowerPoint2003ファイル.ppt";
                sMIME = "application/vnd.ms-powerpoint";
                break;
            case "pptx":
                sFileName = "PowerPoint2007ファイル.pptx";
                sMIME = "application/vnd.ms-powerpoint";
                break;
            default:
                sFileName = "Word2003ファイル.doc";
                sMIME = "application/msword";
                break;
        }
        //-----------------------------------------------------------------------------------------
        // 物理ファイルパス取得
        //-----------------------------------------------------------------------------------------
        sFilePath = MapPath(string.Format(@"./File/{0}", sFileName));
        //-----------------------------------------------------------------------------------------
        // バイナリファイルを開く処理
        //-----------------------------------------------------------------------------------------
        // Response情報クリア
        Response.ClearHeaders();
        Response.ClearContent();
        // バッファリング
        Response.Buffer = true;
        // HTTPヘッダー情報設定
        Response.ContentType = sMIME;
        // ファイル書込
        Response.WriteFile(sFilePath);
        // フラッシュ
        Response.Flush();
        // レスポンス終了
        Response.End();
    }
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
    <title>バイナリファイル表示</title>
</head>
<body>
<form id="form1" runat="server">
</form>
</body>
</html>




ASP.NET(C#)でバイナリファイルをブラウザ表示

バイナリファイルをブラウザ表示するサンプルを作成してみた。



メインソースコードは以下の通り

// Response情報クリア
Response.ClearContent();
// HTTPヘッダー情報設定
Response.ContentType = {ここにMIMEを設定 };
// ファイル書込
Response.WriteFile(sFilePath);
// レスポンス終了
Response.End();


MIMEの一例を挙げると次の通り。
ファイル形式 一般的な拡張子 MIMEタイプ
テキストファイル .txt text/plain
HTML .htm,.html text/html
CSVファイル .csv text/comma-separated-values
TSVファイル .txt, .tsv text/tab-separated-values
XMLファイル .xml text/xml
PDFファイル .pdf application/pdf
ビットマップファイル .bmp image/bmp
GIFファイル .gif image/gif
JPEGファイル .jpg image/jpeg
PNGファイル .png image/png

参考:
MIMEタイプ一覧

なおIE限定だがExcelなどのOfficeドキュメントもブラウザ表示できる。
クライアントPCの設定やソースコード等は以下の記事に記述している。
ブラウザ上にExcel・Word・PowerPointドキュメントを表示/非表示する設定を調べてみた
ASP.NET(C#)でIEにOfficeドキュメントを表示


バイナリファイルをブラウザ表示するサンプルソースを記述する。
なお使い勝手の関係で処理を「バイナリファイルを開くページ(BinaryFile1Open.aspx)」「バイナリファイルを表示する画面ページ(BinaryFile1.aspx)」の2ページに分割している。

BinaryFile1Open.aspx
実行結果及びASP.NETソースコードの確認

<%@ Page Language="C#" Title="ブラウザでバイナリファイルを開く" AutoEventWireup="true" %>
 :
 :
<script type="text/javascript">
    /// <summary>
    /// [javascript]ダウンロードページを新規ウィンドウで開く
    /// </summary>
    /// <param name="sUrl">ダウンロードページのURL</param>
    function OpenWindow(sUrl)
    {
        window.open(sUrl, "", "");
    }
    /// <summary>
    /// [javascript]ダウンロードページをiframeタグ内で開く
    /// </summary>
    /// <param name="sUrl">ダウンロードページのURL</param>
    function InsertIFrame(sUrl)
    {
        document.getElementById('ifDownloadPage').contentWindow.location.href = sUrl;
    }
</script>
<script runat="server">
    /// <summary>
    /// テキストファイルを開く
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void btnTxt_Click(object sender, EventArgs e)
    {
        fnBinaryFileOpen("txt");
    }
    /// <summary>
    /// HTMLファイルを開く
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void btnHtm_Click(object sender, EventArgs e)
    {
        fnBinaryFileOpen("htm");
    }
    /// <summary>
    /// CSVファイルを開く
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void btnCsv_Click(object sender, EventArgs e)
    {
        fnBinaryFileOpen("csv");
    }
    /// <summary>
    /// TSVファイルを開く
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void btnTsv_Click(object sender, EventArgs e)
    {
        fnBinaryFileOpen("tsv");
    }
    /// <summary>
    /// XMLファイルを開く
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void btnXml_Click(object sender, EventArgs e)
    {
        fnBinaryFileOpen("xml");
    }
    /// <summary>
    /// PDFファイルを開く
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void btnPdf_Click(object sender, EventArgs e)
    {
        fnBinaryFileOpen("pdf");
    }
    /// <summary>
    /// ビットマップファイルを開く
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void btnBmp_Click(object sender, EventArgs e)
    {
        fnBinaryFileOpen("bmp");
    }
    /// <summary>
    /// GIFファイルを開く
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void btnGif_Click(object sender, EventArgs e)
    {
        fnBinaryFileOpen("gif");
    }
    /// <summary>
    /// JPEGファイルを開く
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void btnJpg_Click(object sender, EventArgs e)
    {
        fnBinaryFileOpen("jpg");
    }
    /// <summary>
    /// PNGファイルを開く
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void btnPng_Click(object sender, EventArgs e)
    {
        fnBinaryFileOpen("png");
    }
    /// <summary>
    /// スタイルシートファイルを開く
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void btnCss_Click(object sender, EventArgs e)
    {
        fnBinaryFileOpen("css");
    }
    /// <summary>
    /// ファイルを開く
    /// </summary>
    /// <param name="sFileName"></param>
    /// <param name="sMIME"></param>
    public void fnBinaryFileOpen(string sFileType)
    {
        // 指定形式でJavaScript登録
        string sScript = "<script type='text/javascript'>";
        if (rblOpenPlace.SelectedValue == "window")
        {
            sScript += string.Format(
                "OpenWindow('BinaryFile1.aspx?FileType={0}&time={1:HHmmss}');",
                sFileType, DateTime.Now);
        }
        else
        {
            sScript += string.Format(
                "InsertIFrame('BinaryFile1.aspx?FileType={0}&time={1:HHmmss}');",
                sFileType, DateTime.Now);
        }
        sScript += "<" + "/script>";
        // JavaScript登録
        ClientScript.RegisterStartupScript(GetType(), "fnBinaryFileOpen", sScript);
    }
</script>
<h1>ブラウザでバイナリファイルを開く</h1>
<!-- コンテンツ説明 -->
<div class="contents_info">
    ASP.NETからブラウザでTEXT/XML/PDF/JPEG等のバイナリファイルを開くサンプルです。<br />
</div>
<!-- コンテンツ -->
<asp:RadioButtonList id="rblOpenPlace" runat="server" RepeatDirection="Horizontal">
    <asp:ListItem Text="iframeで開く" Value="ifame" Selected="True" />
    <asp:ListItem Text="新規ウィンドウで開く" Value="window" />
</asp:RadioButtonList>
<asp:Button ID="btnTxt" runat="server" Text="テキストファイルを開く"  onclick="btnTxt_Click" /><br />
<asp:Button ID="btnHtm" runat="server" Text="HTMLファイルを開く"  onclick="btnHtm_Click" /><br />
<asp:Button ID="btnXml" runat="server" Text="Xmlファイルのを開く"  onclick="btnXml_Click" /><br />
<asp:Button ID="btnCsv" runat="server" Text="CSVファイルを開く" onclick="btnCsv_Click" /><br />
<asp:Button ID="btnTsv" runat="server" Text="TSVファイルを開く" onclick="btnTsv_Click" /><br />
<asp:Button ID="btnPdf" runat="server" Text="PDFファイルを開く"  onclick="btnPdf_Click" /><br />
<asp:Button ID="btnBmp" runat="server" Text="ビットマップファイルを開く" onclick="btnBmp_Click" /><br />
<asp:Button ID="btnGif" runat="server" Text="GIFファイルを開く"  onclick="btnGif_Click" /><br />
<asp:Button ID="btnJpg" runat="server" Text="JPEGファイルを開く" onclick="btnJpg_Click" /><br />
<asp:Button ID="btnPng" runat="server" Text="PNGファイルを開く" onclick="btnPng_Click" /><br />
<asp:Button ID="btnCss" runat="server" Text="スタイルシート(CSS)ファイルを開く" onclick="btnCss_Click" /><br />
<br />
<iframe id="ifDownloadPage" style=" width:100%; height: 400px;"></iframe>
 :
 :

BinaryFile1.aspx

<%@ Page Language="C#" Title="バイナリファイル表示" AutoEventWireup="true" %>
<%@ Import Namespace="System.IO" %>
<script runat="server">
    /// <summary>
    /// ページロード
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void Page_Load(object sender, EventArgs e)
    {
        string sFileType;   // ファイルタイプを取得
        string sFileName;   // ファイル名
        string sFilePath;   // ファイルパス
        string sMIME;       // MIME
        //-----------------------------------------------------------------------------------------
        // クエリ引数からファイルタイプ取得
        //-----------------------------------------------------------------------------------------
        sFileType = Request.QueryString["FileType"];
        //-----------------------------------------------------------------------------------------
        // ファイルタイプからファイル名とMIMEを設定
        //-----------------------------------------------------------------------------------------
        switch (sFileType)
        {
            case "txt":
                sFileName = "テキストファイル.txt";
                sMIME = "text/plain";
                break;
            case "htm":
                sFileName = "HTMLファイル.htm";
                sMIME = "text/html";
                break;
            case "csv":
                sFileName = "CSVファイル.csv";
                sMIME = "text/plain";
                break;
            case "tsv":
                sFileName = "TSVファイル.txt";
                sMIME = "text/plain";
                break;
            case "xml":
                sFileName = "XMLファイル.xml";
                sMIME = "text/xml";
                break;
            case "pdf":
                sFileName = "PDFファイル.pdf";
                sMIME = "application/pdf";
                break;
            case "bmp":
                sFileName = "ビットマップファイル.bmp";
                sMIME = "image/bmp";
                break;
            case "gif":
                sFileName = "GIFファイル.gif";
                sMIME = "image/gif";
                break;
            case "jpg":
                sFileName = "JPEGファイル.jpg";
                sMIME = "image/jpeg";
                break;
            case "png":
                sFileName = "PNGファイル.png";
                sMIME = "image/png";
                break;
            case "css":
                sFileName = "スタイルシートファイル.css";
                sMIME = "text/plain";
                break;
            default:
                sFileName = "テキストファイル.txt";
                sMIME = "text/plain";
                break;
        }
        //-----------------------------------------------------------------------------------------
        // 物理ファイルパス取得
        //-----------------------------------------------------------------------------------------
        sFilePath = MapPath(string.Format(@"./File/{0}", sFileName));
        //-----------------------------------------------------------------------------------------
        // バイナリファイルを開く処理
        //-----------------------------------------------------------------------------------------
        // Response情報クリア
        Response.ClearHeaders();
        Response.ClearContent();
        // バッファリング
        Response.Buffer = true;
        // HTTPヘッダー情報設定
        Response.ContentType = sMIME;
        // ファイル書込
        Response.WriteFile(sFilePath);
        // フラッシュ
        Response.Flush();
        // レスポンス終了
        Response.End();
    }
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
    <title>バイナリファイル表示</title>
</head>
<body>
<form id="form1" runat="server">
</form>
</body>
</html>





ASP.NET(C#)でファイルダウンロードしながら画面更新

ASP.NET(C#)でファイルダウンロードしながら画面更新を行うサンプルコードを作成してみた。



ネットでASP.NETでファイルダウンロードを調べると以下のようなサンプルコードが多く存在する。
しかし、このソースコードではファイルダウンロードと同時に画面更新はできない。


/// <summary>
/// ファイルダウンロードボタンクリック
/// </summary>
void btnDownloadFile_Click(object senddr, EventArg arg)
{
    //---------------------------------------------------------------------------------------------
    // テキストファイルをダウンロード
    //---------------------------------------------------------------------------------------------
    // ファイルパス設定
    string sFilePath = @"c:\temp.txt"";
    // HTTPヘッダー情報設定
    Response.AddHeader;
    // コンテンツタイプを設定
    Response.ContentType = "text/plain";
    // ファイル書込(データによりResponse.WriteFile()、Response.Write()、Response.BinaryWrite()を使い分ける。)
    Response.WriteFile(sFilePath);
    // レスポンス終了
    Response.End();
}


HTTPプロトコルの規約では1つのリクエスト(サーバ受信)に対し1つのレスポンス(サーバ応答)が基本である。
上記コードではファイルダウンロードにレスポンスを食いつぶしているが、画面更新を行うためにも別途レスポンスが必要である。
しかしボタンクリック等のポストバックでは1つのリクエストを2つのレスポンスに分割することはできない。

解決方法は、2つのリクエストを発行し、2つのリクエストを作ればよい。

具体的には以下の通り。
(A)ダウンロード呼び出しページとダウンロードページの2ページに分割する。
(B)ダウンロード呼び出しページのサーバ処理で「ダウンロードページを呼び出すクライアントスクリプト」をClientScript.RegisterStartupScript()等を使って登録する。
(C)ポストバック後に(B)のクライアントスクリプト経由でダウンロードページをリクエストする。

「ダウンロードページを呼び出すクライアントスクリプト」には以下の2つの方針がある。
①ダウンロードページを新しいウィンドウで開く。
②隠しiframeタグ内でダウンロードページを参照する。

しかし①②にも以下の長所・短所がある。
①は複数ファイルの同時ダウンロードが可能だが、ブラウザの種類・バージョンによって新しく開いたウィンドウが残ってしまう。
またブラウザの種類・バージョンによってはポップアップブロックされてしまうためダウンロードまでの操作が手間取る
②はウィンドウは表示されずセキュリティ規制もないが、複数ファイルの同時ダウンロードが出来ない。


以下のソースコードは「ダウンロード呼び出しページ(DownloadFileAndRefresh.aspx)」から「ダウンロードページ(DownloadPage.aspx)」を呼び出し、テキストファイルをダウンロードするサンプルである。
上述の「①ダウンロードページを新しいウィンドウで開く」「②隠しiframeタグ内でダウンロードページを参照する」の2つの方法で ダウンロードを行っている。

◆ダウンロード呼び出しページ(DownloadFileAndRefresh.aspx)
実行結果及びASP.NETソースコードの確認

<%@ Page Language="C#" Title="ファイルダウンロード&画面更新" AutoEventWireup="true" %>
<%@ Import Namespace="System.IO" %>
  :
  :
<script type="text/javascript">
    /// <summary>
    /// [javascript]ダウンロードページを新規ウィンドウで開く
    /// </summary>
    /// <param name="sUrl">ダウンロードページのURL</param>
    function OpenWindowDownloadPage(sUrl)
    {
        window.open(sUrl, "", "");
    }
    /// <summary>
    /// [javascript]ダウンロードページをiframeタグ内で開く
    /// </summary>
    /// <param name="sUrl">ダウンロードページのURL</param>
    function InsertIFrameDownloadPage(sUrl)
    {
        document.getElementById('ifDownloadPage').contentWindow.location.href = sUrl;
    }
</script>
<script type="text/C#" runat="server">
    /// <summary>
    /// 「例1 ダウンロードページを新規ウィンドウで開く」ボタンクリック
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void btnOpenWindowDownloadPage_Click(object sender, EventArgs e)
    {
        //-----------------------------------------------------------------------------------------
        // ファイルダウンロード
        // ダウンロードページを新規ウィンドウで開く
        //-----------------------------------------------------------------------------------------
        // コンテンツ文字列作成
        string sTextContents = string.Format("{0:HH:mm:ss}に「例1」ボタンをクリック", DateTime.Now);
        // コンテンツ文字列作成をURLエンコード
        sTextContents = HttpUtility.UrlEncode(sTextContents);
        // JavaScript作成
        string sScript = string.Format(
            "<script type='text/javascript'>OpenWindowDownloadPage('DownloadPage.aspx?text={0}&time={1:HHmmss}');<" + "/script>",
            sTextContents, DateTime.Now);
        // JavaScript登録
        ClientScript.RegisterStartupScript(GetType(), "ex1", sScript);
        //-----------------------------------------------------------------------------------------
        // ダウンロード時間をラベルに表示
        //-----------------------------------------------------------------------------------------
        lblDownloadTime.Text = DateTime.Now.ToString("HH:mm:ssに「例1ボタンからダウンロード」");
    }
    /// <summary>
    /// 「例2 隠しiframeタグ内にダウンロードページを開く」ボタンクリック
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void btnInsertIFrameDownloadPage_Click(object sender, EventArgs e)
    {
        //-----------------------------------------------------------------------------------------
        // ファイルダウンロード
        // 例2 隠しiframeタグ内にダウンロードページを開く
        //-----------------------------------------------------------------------------------------
        // コンテンツ文字列作成
        string sTextContents = string.Format("{0:HH:mm:ss}に「例2」ボタンをクリック", DateTime.Now);
        // コンテンツ文字列作成をURLエンコード
        sTextContents = HttpUtility.UrlEncode(sTextContents);
        // JavaScript作成
        string sScript = string.Format(
            "<script type='text/javascript'>InsertIFrameDownloadPage('DownloadPage.aspx?text={0}&time={1:HHmmss}');<" + "/script>",
            sTextContents, DateTime.Now);
        // JavaScript登録
        ClientScript.RegisterStartupScript(GetType(), "ex2", sScript);
        //-----------------------------------------------------------------------------------------
        // ダウンロード時間をラベルに表示
        //-----------------------------------------------------------------------------------------
        lblDownloadTime.Text = DateTime.Now.ToString("HH:mm:ssに「例2ボタンからダウンロード」");
    }
</script>
<h1>ファイルダウンロード&画面更新</h1>
<!-- コンテンツ説明 -->
<div class="contents_info">
    ASP.NETからファイルをダウンロードしながら画面を更新するサンプルです。<br />
</div>
<!-- コンテンツ -->
<asp:Button ID="btnOpenWindowDownloadPage" runat="server" 
        Text="例1 ダウンロードページを新規ウィンドウで開く" onclick="btnOpenWindowDownloadPage_Click" /><br />
<asp:Button ID="btnInsertIFrameDownloadPage" runat="server" 
        Text="例2 隠しiframeタグ内にダウンロードページを開く" 
        onclick="btnInsertIFrameDownloadPage_Click" /><br />
<br />
<asp:Label ID="lblDownloadTime" runat="server" />
<br />
<!-- 隠しiframe -->
<iframe id="ifDownloadPage" style="visibility:hidden"></iframe>
<br />
  :
  :


◆ダウンロードページ(DownloadPage.aspx)

<%@ Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
    /// <summary>
    /// ページロード
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    protected void Page_Load(object sender, EventArgs e)
    {
        string sDownLoadFileContents = "";  // ダウンロードファイルの内容
        //-----------------------------------------------------------------------------------------
        // コンテンツ取得
        // ※今回はQueryString経由でダウンロードファイルの内容を取得しているが、他に、
        //  以下の様な設定が考えられる。
        //  ①QueryStringにデータベースの主キーを設定、ダウンロードページ内で主キーを
        //   基にコンテンツ取得
        //  ②セッション経由でコンテンツ取得
        //-----------------------------------------------------------------------------------------
        if (Request.QueryString["text"] != null)
        {
            sDownLoadFileContents = HttpUtility.UrlDecode(Request.QueryString["text"]);
        }
        //-----------------------------------------------------------------------------------------
        // ダウンロード処理
        //-----------------------------------------------------------------------------------------
        // Response情報クリア
        Response.ClearContent();
        // バッファリング
        Response.Buffer = true;
        // HTTPヘッダー情報設定
        Response.AddHeader("Content-Disposition", "attachment;filename=download.txt");
        Response.ContentType = "text/plain";
        // コンテンツデータ書込
        Response.Write(sDownLoadFileContents);
        // フラッシュ
        Response.Flush();
        // レスポンス終了
        Response.End();
    }
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>ダウンロードページ</title>
</head>
<body>
<form id="form1" runat="server">
</form>
</body>
</html>



  • ASP.NET(C#)でファイルダウンロード
  • ASP.NET(C#)でIEにOfficeドキュメントを表示
  • ASP.NET(C#)でIEのファイルダウンロードダイアログボタンをカスタマイズ
  • ASP.NET(C#)でバイナリファイルをブラウザ表示

  • ASP.NET(C#)でファイルダウンロード

    ASP.NET(C#)でファイルダウンロードのサンプルコードを作成してみた。



    ダウンロード処理のメインソースは以下の通り
    
    // Response情報クリア
    Response.ClearContent();
    // HTTPヘッダー情報設定
    Response.AddHeader("Content-Disposition", "attachment;filename=①ファイル名");
    Response.ContentType = ②MIME;
    // ファイル書込(データによりResponse.WriteFile()、Response.Write()、Response.BinaryWrite()を使い分ける。)
    Response.WriteFile(sFilePath);
    // レスポンス終了
    Response.End();
    
    

    上記ソースのうち「①ファイル名」と「②MIME」に関しては注意が必要である。

    ■①ファイル名について
    ファイル名に日本語が含まれる場合、IEとIE以外のブラウザで挙動が異なるため注意する必要がある。
    日本語を含むファイル名はIE以外のブラウザの場合は問題ないが、IEの場合ファイルダウンロードダイアログで文字化けを起こす。
    このためブラウザがIEの場合、URLエンコードをする必要がある。
    
    HttpUtility.UrlEncode(sFileName)
    
    

    ■②MIME
    Response.ContentTypeにはファイル形式毎にコンテンツタイプを指定する必要がある。

    拡張子とMIMEタイプ - とほほのWWW入門では、 MIMEを以下のように説明している。
    Webの世界では拡張子という概念と、もうひとつ『MIMEタイプ』という概念があります。MIMEタイプとは「タイプ名/サブタイプ名」の形式の文字列で、WEBサーバーとWEBブラウザの間はこのMIMEタイプを用いてデータの形式を指定しています。

    MIMEの一例を挙げると次の通り。
    ファイル形式 一般的な拡張子 MIMEタイプ
    テキストファイル .txt text/plain
    HTML .htm,.html text/html
    CSVファイル .csv text/comma-separated-values
    TSVファイル .txt, .tsv text/tab-separated-values
    XMLファイル .xml text/xml
    Microsoft Wordファイル .doc, .docx application/msword
    Microsoft Excelファイル .xls, xlsx application/msexcel
    Microsoft PowerPointファイル .ppt, pptx application/mspowerpoint
    PDFファイル .pdf application/pdf
    ビットマップファイル .bmp image/bmp
    GIFファイル .gif image/gif
    JPEGファイル .jpg image/jpeg
    PNGファイル.png .png image/png
    ZIPファイル .zip application/zip
    LZHファイル .lzh application/lha
    スタイルシートファイル .css text/css
    JavaScriptファイル .js text/javascript
    VBScriptファイル .vbs text/vbscript
    実行ファイル .exe application/octet-stream

    参考:MIMEタイプ一覧


    ファイルダウンロードのサンプルソースを記述する。

    実行結果及びASP.NETソースコードの確認
    
     :
     :
    <script runat="server">
        /// <summary>
        /// テキストファイルダウンロード
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void btnTxt_Click(object sender, EventArgs e)
        {
            fnDownloadFile("テキストファイル.txt", "text/plain");
        }
        /// <summary>
        /// HTMLファイルダウンロード
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void btnHtm_Click(object sender, EventArgs e)
        {
            fnDownloadFile("HTMLファイル.htm", "text/html");
        }
        /// <summary>
        /// CSVファイルダウンロード
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void btnCsv_Click(object sender, EventArgs e)
        {
            fnDownloadFile("CSVファイル.csv", "text/comma-separated-values");
        }
        /// <summary>
        /// TSVファイルダウンロード
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void btnTsv_Click(object sender, EventArgs e)
        {
            fnDownloadFile("TSVファイル.txt", "text/tab-separated-values");
        }
        /// <summary>
        /// XMLファイルダウンロード
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void btnXml_Click(object sender, EventArgs e)
        {
            fnDownloadFile("XMLファイル.xml", "text/xml");
        }
        /// <summary>
        /// Wordファイルダウンロード
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void btnDoc_Click(object sender, EventArgs e)
        {
            fnDownloadFile("Wordファイル.doc", "application/msword");
        }
        /// <summary>
        /// Excelファイルダウンロード
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void btnXls_Click(object sender, EventArgs e)
        {
            fnDownloadFile("Excelファイル.xls", "application/msexcel");
        }
        /// <summary>
        /// PowerPointファイルダウンロード
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void btnPpt_Click(object sender, EventArgs e)
        {
            fnDownloadFile("PowerPointファイル.ppt", "application/mspowerpoint");
        }
        /// <summary>
        /// PDFファイルダウンロード
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void btnPdf_Click(object sender, EventArgs e)
        {
            fnDownloadFile("PDFファイル.pdf", "application/pdf");
        }
        /// <summary>
        /// ビットマップファイルダウンロード
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void btnBmp_Click(object sender, EventArgs e)
        {
            fnDownloadFile("ビットマップファイル.bmp", "image/bmp");
        }
        /// <summary>
        /// GIFファイルダウンロード
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void btnGif_Click(object sender, EventArgs e)
        {
            fnDownloadFile("GIFファイル.gif", "image/gif");
        }
        /// <summary>
        /// JPEGファイルダウンロード
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void btnJpg_Click(object sender, EventArgs e)
        {
            fnDownloadFile("JPEGファイル.jpg", "image/jpeg");
        }
        /// <summary>
        /// PNGファイルダウンロード
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void btnPng_Click(object sender, EventArgs e)
        {
            fnDownloadFile("PNGファイル.png", "image/png");
        }
        /// <summary>
        /// ZIPファイルダウンロード
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void btnZip_Click(object sender, EventArgs e)
        {
            //fnDownloadFile("ZIPファイル.zip", "application/zip"); // MIMEを指定すると動かない場合がある
            fnDownloadFile("ZIPファイル.zip", "");
        }
        /// <summary>
        /// LZHファイルダウンロード
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void btnLzh_Click(object sender, EventArgs e)
        {
            fnDownloadFile("LZHファイル.lzh", "application/lha");
        }
        /// <summary>
        /// スタイルシートファイルダウンロード
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void btnCss_Click(object sender, EventArgs e)
        {
            fnDownloadFile("スタイルシートファイル.css", "text/css");
        }
        /// <summary>
        /// JavaScriptファイルダウンロード
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void btnJs_Click(object sender, EventArgs e)
        {
            fnDownloadFile("JavaScriptファイル.js", "text/javascript");
        }
        /// <summary>
        /// VBScriptファイルダウンロード
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void btnVbs_Click(object sender, EventArgs e)
        {
            fnDownloadFile("VBScriptファイル.vbs", "text/vbscript");
        }
        /// <summary>
        /// 実行ファイルダウンロード
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void btnExe_Click(object sender, EventArgs e)
        {
            fnDownloadFile("実行ファイル.exe", "application/octet-stream");
        }
        /// <summary>
        /// ファイルダウンロード
        /// </summary>
        /// <param name="sFileName"></param>
        /// <param name="sMIME"></param>
        public void fnDownloadFile(string sFileName, string sMIME)
        {
            string sFilePath;           // ファイルパス
            string sDownloadFileName;   // ダウンロードファイル名
            //-----------------------------------------------------------------------------------------
            // 物理ファイルパス取得
            //-----------------------------------------------------------------------------------------
            sFilePath = MapPath(string.Format(@"./File/{0}", sFileName));
            //-----------------------------------------------------------------------------------------
            // 日本語ファイル名を考慮したダウンロードファイル名作成
            //-----------------------------------------------------------------------------------------
            if (Request.Browser.Browser == "IE")
            {
                // IEの場合、ファイル名をURLエンコード
                sDownloadFileName = HttpUtility.UrlEncode(sFileName);
            }
            else
            {
                // IE以外はファイル名は無加工
                sDownloadFileName = sFileName;
            }
            //-----------------------------------------------------------------------------------------
            // ダウンロード処理
            //-----------------------------------------------------------------------------------------
            // Response情報クリア
            Response.ClearContent();
            // バッファリング
            Response.Buffer = true;
            // HTTPヘッダー情報設定
            Response.AddHeader("Content-Disposition", string.Format("attachment;filename={0}", sDownloadFileName));
            Response.ContentType = sMIME;
            // ファイル書込
            Response.WriteFile(sFilePath);
            // フラッシュ
            Response.Flush();
            // レスポンス終了
            Response.End();
        }
    </script>
    <h1>ファイルダウンロード</h1>
    <!-- コンテンツ説明 -->
    <div class="contents_info">
        ASP.NETからファイルをダウンロードするサンプルです。<br />
    </div>
    <!-- コンテンツ -->
    <asp:Button ID="btnTxt" runat="server" Text="テキストファイルダウンロード"  onclick="btnTxt_Click" /><br />
    <asp:Button ID="btnHtm" runat="server" Text="HTMLファイルダウンロード"  onclick="btnHtm_Click" /><br />
    <asp:Button ID="btnXml" runat="server" Text="Xmlファイルのダウンロード"  onclick="btnXml_Click" /><br />
    <asp:Button ID="btnCsv" runat="server" Text="CSVファイルダウンロード" onclick="btnCsv_Click" /><br />
    <asp:Button ID="btnTsv" runat="server" Text="TSVファイルダウンロード" onclick="btnTsv_Click" /><br />
    <asp:Button ID="btnDoc" runat="server" Text="Wordファイルダウンロード" onclick="btnDoc_Click" /><br />
    <asp:Button ID="btnXls" runat="server" Text="Excelファイルダウンロード" onclick="btnXls_Click" /><br />
    <asp:Button ID="btnPpt" runat="server" Text="PowerPointファイルダウンロード" onclick="btnPpt_Click" /><br />
    <asp:Button ID="btnPdf" runat="server" Text="PDFファイルダウンロード"  onclick="btnPdf_Click" /><br />
    <asp:Button ID="btnBmp" runat="server" Text="ビットマップファイルダウンロード" onclick="btnBmp_Click" /><br />
    <asp:Button ID="btnGif" runat="server" Text="GIFファイルダウンロード"  onclick="btnGif_Click" /><br />
    <asp:Button ID="btnJpg" runat="server" Text="JPEGファイルダウンロード" onclick="btnJpg_Click" /><br />
    <asp:Button ID="btnPng" runat="server" Text="PNGファイルダウンロード" onclick="btnPng_Click" /><br />
    <asp:Button ID="btnZip" runat="server" Text="ZIPファイルダウンロード" onclick="btnZip_Click" /><br />
    <asp:Button ID="btnLzh" runat="server" Text="LZHファイルダウンロード" onclick="btnLzh_Click" /><br />
    <asp:Button ID="btnCss" runat="server" Text="スタイルシート(CSS)ファイルダウンロード" onclick="btnCss_Click" /><br />
    <asp:Button ID="btnVbs" runat="server" Text="VBScriptファイルダウンロード" onclick="btnVbs_Click" /><br />
    <asp:Button ID="btnJs"  runat="server" Text="JavaScriptファイルダウンロード" onclick="btnJs_Click" /><br />
    <asp:Button ID="btnExe" runat="server" Text="実行ファイルダウンロード" onclick="btnExe_Click" /><br />
    <br />
     :
     :
    


  • ASP.NET(C#)でファイルダウンロードしながら画面更新
  • ASP.NET(C#)でバイナリファイルをブラウザ表示
  • ASP.NET(C#)でIEにOfficeドキュメントを表示
  • ASP.NET(C#)でIEのファイルダウンロードダイアログボタンをカスタマイズ

  • 拡張子とMIMEタイプ - とほほのWWW入門
  • MIMEタイプ一覧
  • 方法 : ASP.NET Web ページでブラウザの種類を検出する

  • C#でCSV・TSVファイル作成

    C#でDataTableからCSVファイルまたはTSVファイルを作成してみた。



    「データをカンマで区切り、改行で1レコード」という条件ででDataTableからCSVファイルを作るサンプルコード。

    実行結果及びASP.NETソースコードの確認
    
    
    //-------------------------------------------------------------------------------------
    // データ作成
    //-------------------------------------------------------------------------------------
    DataTable dtData = new DataTable();
    // 列作成
    dtData.Columns.Add("colInt32", typeof(Int32));
    dtData.Columns.Add("colInt64", typeof(Int64));
    dtData.Columns.Add("colDouble", typeof(Double));
    dtData.Columns.Add("colDecimal", typeof(Decimal));
    dtData.Columns.Add("colNull", typeof(Int32));
    dtData.Columns.Add("colDateTime", typeof(DateTime));
    dtData.Columns.Add("colBoolean", typeof(Boolean));
    dtData.Columns.Add("colString", typeof(String));
    // データ投入
    for (int i = 1; i <= 5; i++)
    {
        DataRow dr = dtData.NewRow();
        dr["colInt32"] = i;
        dr["colInt64"] = i * i;
        dr["colDouble"] = 1.1 * i;
        dr["colDecimal"] = 10.1 * i;
        dr["colNull"] = DBNull.Value;
        dr["colDateTime"] = new DateTime(2010, 1, i);
        dr["colBoolean"] = (i % 2 == 0) ? true : false;
        dr["colString"] = string.Format("文字列{0}", (char)('A' + i - 1));
        dtData.Rows.Add(dr);
    }
    //-----------------------------------------------------------------------------------------
    // CSVファイル作成
    //-----------------------------------------------------------------------------------------
    // 一時ファイル作成
    string sTempFilePath = Path.GetTempFileName();
    // CSVファイル書込
    using (StreamWriter sw = new StreamWriter(sTempFilePath, false, Encoding.GetEncoding("Shift-JIS")))
    {
        // 行列ループ
        for (int iRow = 0; iRow < dtData.Rows.Count; iRow++)
        {
            string sRecord = "";  // レコード
            // 1レコード作成
            for (int iCol = 0; iCol < dtData.Columns.Count; iCol++)
            {
                sRecord += string.Format("{0},", dtData.Rows[iRow][iCol]);
            }
            // 行末のカンマを削除
            sRecord = sRecord.Remove(sRecord.Length - 1, 1);
            // ファイル書込
            sw.WriteLine(sRecord);
        }
        // ファイルクローズ
        sw.Close();
    }
    

    上記ソースで作成されるCSVファイルの内容


    大概は上記サンプルでも通用することが多いが、CSVとしては以下の問題がある。
    • データにカンマ、改行を含む文字列がある場合に正しく処理できない。
    • 空文字とnull文字の判定ができない。
    • Byte配列、Byte型、SByte型等の文字列変換が困難なデータ型を文字変換すると予期せぬ文字列を返す。

    PS. DataTableに格納できる基本データ型
    • Boolean
    • Byte
    • Char
    • DateTime
    • Decimal
    • Double
    • Int16
    • Int32
    • Int64
    • SByte
    • Single
    • String
    • TimeSpan
    • UInt16
    • UInt32
    • UInt64
    • Byte[]
    参考:DataColumn.DataType プロパティ

    また使い勝手として以下が考えられる。
    • CSV(カンマ区切り)でなく、TSV(タブ区切り)を指定したい。
    • 文字コードはShift-JIS以外を指定したい。
    • 改行文字はCRLF・CR・LFのいずれかを指定したい。
    • ヘッダ行を出力有無を指定したい。
    • 最終行に改行文字が出力有無を指定したい。
    • Boolean型の出力書式は、True/Falseでなく1/0を指定したい。。
    • DateTime型の出力書式は「YYYY/MM/DD HH:mm:ss」「YYYYMMDD」等の時間書式を指定したい。


    CSVファイルはRFC 4180で国際規格化されている。
    しかしRFC 4180は現行仕様の追認形式をとっているため仕様が厳格な規格ではない。

    Comma-Separated Values - Wikipediaを参考にRFC 4180をまとめると以下の通り。
    • ファイルは1つ以上のレコードからなる。レコードは改行で区切られる。最後のレコードの後には改行はあってもなくてもいい。
    • レコードは1つ以上の同じ個数のフィールドからなる。フィールドはコンマ「,」で区切られる。最後のフィールドの後にはコンマは付けない。
    • 1,2,となっている場合は3列目はnull文字を表す
    • ファイルの先頭には、オプションとして、通常のレコードと同一の書式の「ヘッダ行」があってもいい。ヘッダ行は、他のレコードと同じ個数のフィールドを持ち、フィールドの名称が書かれている。
    • フィールドは、ダブルクォート「"」で囲んでも囲まなくてもよい。
    • フィールドがコンマ、ダブルクォート、改行を含む場合は、かならずダブルクォートで囲む。また、フィールドに含まれるダブルクォートは2つ並べてエスケープする。


    これまでの条件を満たし規格や使い勝手を考慮したDataTableからCSV/TSVファイルを作成するサンプルソース(DataTable2CharacterSeparatedValuesクラス)を記述する。

    サンプルソースのpublicメソッドは以下の通り。
    メソッド名 シグニチャ 概要
    テキストデータファイル作成 DataTable2CharacterSeparatedValues.CreateFile
    (
      DataTable dtData,
      string sDustFilePath,
      Option opt
    )
    CSV/TSVファイルの作成。
    引数は以下の通り
    dtData 出力対象のDataTable
    sDustFilePath 出力ファイルパス
    opt オプション(後述)

    上記メソッドの第3引数のOptionクラスのフィールドは以下の通り。
    フィールド シグニチャ 既定値 概要
    文字コード Encoding enc Shift-JIS ファイルの文字コードを指定。
    フィールド区切り文字 string sFiledSeparator カンマ(,) フィールド区切り文字を指定。
    行区切り文字 string sLineBreak CRLF 行区切り文字を指定。
    フィールド囲み enumFieldEnclosed enFieldEnclosed 特殊文字列を含む文字列フィールドだけ囲む フィールドをダブルクォーテーション(")で囲むか指定。
    ヘッダ行の出力有無 bool bOutputHeader false ヘッダ行の出力するか指定。
    ヘッダ行の列名は引数dtDataのDataColumns[n].ColumnName。
    最終レコードに行区切り文字挿入 bool bLastRecordLineBreak true 最終レコードに行区切り文字を挿入するか指定。
    Boolean型の出力書式 bool bBooleanTypeFormat true Boolean型の出力書式を指定。
    trueの場合、True/Falseで出力。
    falseの場合、1/0で出力。
    DateTime型の出力書式 string sDateTimeTypeFormat yyyyMMdd HH:mm:ss DateTime型の出力書式を指定。
    出力書式はDateTime.ToString()と同じ書式。

    実行結果及びASP.NETソースコードの確認
    
    
    using System;
    using System.IO;
    using System.Data;
    using System.Text;
    
    /// <summary>
    /// DataTableからテキストファイル(CSV/TSV)作成クラス
    /// </summary>
    public class DataTable2CharacterSeparatedValues
    {
        /// <summary>
        /// フィールド囲み
        /// </summary>
        public enum enumFieldEnclosed
        {
            None,                               // フィールドを囲まない
            AllField,                           // 全フィールドを囲む
            StringField,                        // 文字列フィールドだけ囲む
            ContainingSpecialCharactersField    // 特殊文字列を含む文字列フィールドだけ囲む
        }
        /// <summary>
        /// オプション
        /// </summary>
        public class Option
        {
            /// <summary>
            /// 文字コード
            /// </summary>
            public Encoding enc = Encoding.GetEncoding("Shift-JIS");
            /// <summary>
            /// フィールド区切り文字
            /// </summary>
            public string sFiledSeparator = ",";
            /// <summary>
            /// 行区切り文字
            /// </summary>
            public string sLineBreak = "\r\n";
            /// <summary>
            /// フィールド囲み
            /// </summary>
            public enumFieldEnclosed enFieldEnclosed = enumFieldEnclosed.ContainingSpecialCharactersField;
            /// <summary>
            /// ヘッダ行の出力有無
            /// </summary>
            public bool bOutputHeader = true;
            /// <summary>
            /// 最終レコードに行区切り文字挿入
            /// </summary>
            public bool bLastRecordLineBreak = true;
            /// <summary>
            /// Boolean型の出力書式(trueでTrue/False、falseで'1'/'0'と出力)
            /// </summary>
            public bool bBooleanTypeFormat = true;
            /// <summary>
            /// DateTime型の出力書式
            /// </summary>
            public string sDateTimeTypeFormat = "yyyyMMdd HH:mm:ss";
        }
        /// <summary>
        /// テキストデータファイル作成
        /// </summary>
        /// <param name="dtData">出力対象のDataTable</param>
        /// <param name="sDustFilePath">出力ファイルパス</param>
        /// <param name="opt">
        /// オプション(DataTable2TextFile.Optionクラス)
        /// enc                 : 文字コード            既定:Shift-JIS
        /// sFiledSeparator     : フィールド区切り      既定:カンマ(,)
        /// sLineBreak          : 行区切り              既定:CRLF
        /// enFieldEnclosed     : フィールド囲み        既定:特殊文字列を含む文字列フィールドだけ囲む
        /// bOutputHeader       : ヘッダ行の出力有無    既定:false
        /// bBooleanTypeFormat  : DateTime型の出力書式  既定:true(yyyyMMdd HH:mm:ss)
        /// sDateTimeTypeFormat : DateTime型の出力書式  既定:true(yyyyMMdd HH:mm:ss)
        /// </param>
        public static void CreateFile(DataTable dtData, string sDustFilePath, Option opt)
        {
            StringBuilder sbContents = new StringBuilder(1024); // ファイルコンテンツ
            string sFieldEnclosed;                              // フィールド囲み文字
            //-----------------------------------------------------------------------------------------
            // データ型チェック
            //-----------------------------------------------------------------------------------------
            foreach (DataColumn col in dtData.Columns)
            {
                // データ型取得
                Type type = col.DataType;
                // 配列型チェック(Byte[]向け)
                // ※バイト配列型は印字不可能な文字になるかもしれないので削除
                if (type.IsArray)
                {
                    throw new ApplicationException("配列はフィールドに設定できません");
                }
                // バイト型(Byte/SByte)チェック
                // ※バイト型は印字不可能な文字になるかもしれないので削除
                if (type == typeof(Byte) || type == typeof(SByte))
                {
                    throw new ApplicationException("バイト型はフィールドに設定できません");
                }
            }
            //-----------------------------------------------------------------------------------------
            // フィールド囲み文字
            //-----------------------------------------------------------------------------------------
            // 「全フィールドを囲む」の場合
            if (opt.enFieldEnclosed == enumFieldEnclosed.AllField)
            {
                sFieldEnclosed = "\"";
            }
            // 「フィールドを囲まない」
            // 「文字列フィールドだけ囲む」
            // 「特殊文字列を含む文字列フィールドだけ囲む」の場合
            else
            {
                sFieldEnclosed = "";
            }
            //-----------------------------------------------------------------------------------------
            // ヘッダ行作成
            //-----------------------------------------------------------------------------------------
            if (opt.bOutputHeader)
            {
                // 列名作成
                foreach (DataColumn col in dtData.Columns)
                {
                    sbContents.Append(col.ColumnName);
                    sbContents.Append(opt.sFiledSeparator);
                }
                // 最後のフィールド区切りを削除
                if (sbContents.Length > 0)
                {
                    sbContents.Remove(sbContents.Length - opt.sFiledSeparator.Length, opt.sFiledSeparator.Length);
                }
                // 行区切り挿入
                sbContents.Append(opt.sLineBreak);
            }
            //-----------------------------------------------------------------------------------------
            // コンテンツ行作成
            //-----------------------------------------------------------------------------------------
            for (int iRow = 0; iRow < dtData.Rows.Count; iRow++)
            {
                // 列データ作成
                for (int iCol = 0; iCol < dtData.Columns.Count; iCol++)
                {
                    // フィールドデータ取得
                    object objField = dtData.Rows[iRow][iCol];
                    // NULLの場合
                    if (objField is DBNull)
                    {
                        sbContents.Append(opt.sFiledSeparator);
                    }
                    // 文字(String/Char)の場合
                    else if (objField is String || objField is Char)
                    {
                        string sField = objField.ToString();
                        switch(opt.enFieldEnclosed)
                        {
                            //「フィールドを囲まない」
                            case enumFieldEnclosed.None:
                                sbContents.Append(sField);
                                break;
                            //「全フィールドを囲む」の場合
                            case enumFieldEnclosed.AllField:
                                sField = sField.Replace("\"", "\"\"");
                                sbContents.AppendFormat("\"{0}\"", sField);
                                break;
                            //「文字列フィールドだけ囲む」の場合
                            case enumFieldEnclosed.StringField:
                                sField = sField.Replace("\"", "\"\"");
                                sbContents.AppendFormat("\"{0}\"", sField);
                                break;
                            //「特殊文字列を含む文字列フィールドだけ囲む」の場合
                            case enumFieldEnclosed.ContainingSpecialCharactersField:
                                sField = sField.Replace("\"", "\"\"");
                                if (sField.IndexOf(opt.sFiledSeparator) != -1)
                                {
                                    sbContents.AppendFormat("\"{0}\"", sField);
                                }
                                else if (sField.IndexOf(opt.sLineBreak) != -1)
                                {
                                    sbContents.AppendFormat("\"{0}\"", sField);
                                }
                                else if (sField.IndexOf("\"") != -1)
                                {
                                    sbContents.AppendFormat("\"{0}\"", sField);
                                }
                                else
                                {
                                    sbContents.AppendFormat("{0}", sField);
                                }
                                break;
                        }
                        sbContents.Append(opt.sFiledSeparator);
                    }
                    // 真偽型(Boolean)の場合
                    else if (objField is Boolean)
                    {
                        string sValue;
                        // True/Falseで出力
                        if (opt.bBooleanTypeFormat)
                        {
                            sValue = ((bool)objField).ToString();
                        }
                        // 1/0で出力
                        else
                        {
                            sValue = ((bool)objField) ? "1" : "0";
                        }
                        sbContents.AppendFormat("{1}{0}{1}", sValue, sFieldEnclosed);
                        sbContents.Append(opt.sFiledSeparator);
                    }
                    // 日時(DateTime)
                    else if (objField is DateTime)
                    {
                        string sFormat = "{1}{0:" + opt.sDateTimeTypeFormat + "}{1}";
                        sbContents.AppendFormat(sFormat, objField, sFieldEnclosed);
                        sbContents.Append(opt.sFiledSeparator);
                    }
                    // 数値型(Decimal/Double/Int16/Int32/Int64/Single/UInt16/UInt32/UInt64)
                    // 日時(TimeSpan)
                    else
                    {
                        sbContents.AppendFormat("{1}{0}{1}", objField, sFieldEnclosed);
                        sbContents.Append(opt.sFiledSeparator);
                    }
                }
                // 最後のフィールド区切りを削除
                sbContents.Remove(sbContents.Length - opt.sFiledSeparator.Length, opt.sFiledSeparator.Length);
                // 行区切り挿入
                sbContents.Append(opt.sLineBreak);
            }
            // 最終レコードの行区切り文字を削除
            if (!opt.bLastRecordLineBreak && sbContents.Length > 0)
            {
                sbContents.Remove(sbContents.Length - opt.sLineBreak.Length, opt.sLineBreak.Length);
            }
            //-----------------------------------------------------------------------------------------
            // ファイル書込
            //-----------------------------------------------------------------------------------------
            using (StreamWriter sw = new StreamWriter(sDustFilePath, false, opt.enc))
            {
                sw.Write(sbContents.ToString());
                sw.Close();
            }
        }
    }
    
    


    
    using System;
    using System.Data;
    using System.Text;
    
    class Program
    {
        static void Main(string[] args)
        {
            //-------------------------------------------------------------------------------------
            // 表示用データ作成
            //-------------------------------------------------------------------------------------
            DataTable dtData = new DataTable();
            // 列作成
            dtData.Columns.Add("colInt32", typeof(Int32));
            dtData.Columns.Add("colInt64", typeof(Int64));
            dtData.Columns.Add("colDouble", typeof(Double));
            dtData.Columns.Add("colDecimal", typeof(Decimal));
            dtData.Columns.Add("colNull", typeof(Int32));
            dtData.Columns.Add("colDateTime", typeof(DateTime));
            dtData.Columns.Add("colBoolean", typeof(Boolean));
            dtData.Columns.Add("colString", typeof(String));
            dtData.Columns.Add("colSpecialString", typeof(String));
            // データ投入
            for (int i = 1; i <= 5; i++)
            {
                DataRow dr = dtData.NewRow();
                dr["colInt32"] = i;
                dr["colInt64"] = i * i;
                dr["colDouble"] = 1.1 * i;
                dr["colDecimal"] = 10.1 * i;
                dr["colNull"] = DBNull.Value;
                dr["colDateTime"] = new DateTime(2010, 1, i, 23, 59, 59);
                dr["colBoolean"] = (i % 2 == 0) ? true : false;
                dr["colString"] = string.Format("文字列{0}", (char)('A' + i - 1));
                if (i % 5 == 1)
                {
                    dr["colSpecialString"] = ",";
                }
                else if (i % 5 == 2)
                {
                    dr["colSpecialString"] = "\t";
                }
                else if (i % 5 == 3)
                {
                    dr["colSpecialString"] = "\r\n";
                }
                else if (i % 5 == 4)
                {
                    dr["colSpecialString"] = "\"";
                }
                else
                {
                    dr["colSpecialString"] = "";
                }
                dtData.Rows.Add(dr);
            }
            //-------------------------------------------------
            // CSV/TSVファイル作成
            //-------------------------------------------------
            DataTable2CharacterSeparatedValues.Option opt = new DataTable2CharacterSeparatedValues.Option();
            // 文字コード
            opt.enc = Encoding.GetEncoding("Shift-JIS");
            // フィールド区切り(","・"\t"のいずれか)
            opt.sFiledSeparator = ",";
            // 行区切り("\r\n"・"\r"・"\n"のいずれか)
            opt.sLineBreak = "\r\n";
            // フィールド囲み(ダブルクォーテーション(")の囲み方を指定)
            opt.enFieldEnclosed = DataTable2CharacterSeparatedValues.enumFieldEnclosed.AllField;
            // ヘッダ行を作成
            opt.bOutputHeader = true;
            // 最終レコードの後ろを改行
            opt.bLastRecordLineBreak = true;
            // Boolean型の出力形式(true:True/False or false:1/0)
            opt.bBooleanTypeFormat = false;
            // DateTime型の出力書式
            opt.sDateTimeTypeFormat = "yyyy/MM/dd hh:mm:ss";
            // ファイル作成
            string sTempFilePath = @"c:\temp\test.csv";
            DataTable2CharacterSeparatedValues.CreateFile(dtData, sTempFilePath, opt);
        }
    }
    
    

    上記ソースで作成されるCSVファイルの内容


  • RFC 4180
  • Comma-Separated Values - Wikipe
  • DataColumn.DataType プロパティ

  • ASP.NET(C#)でJQuery+TableSorterを利用

    ASP.NET(C#)とJQuery+TableSorterを連携してみた。
    対象はグリッド系コントロールのGridView・ListView・Repeater・DataList・DataGrid。



    ■開発・運用環境
    • Visual Studio 2008 SP1
    • .NET Framework 3.5 SP1
    • ASP.NET3.5

    ■ブラウザ
    • IE6,IE8
    • Firefox3
    • Opera9
    • Chrome2.0


    TableSorterではtableタグ内にtheadタグが必須である。
    しかしASP.NETのグリッド系コントロールは「デフォルト設定ではtheadを出力しない」もしくは「theadを出力できない」。(下表参照)
    コントロール 出力可否(*1) 設定方法
    GridView プロパティで設定。
    ListView Templateコントロールにtableタグを記述。
    Repeater Templateコントロールにtableタグを記述。
    DataList × 「サーバサイド設定」「JavaScript(*2)」連携が必要。
    DataGrid × 「サーバサイド設定」「JavaScript(*2)」連携が必要。
    (*1)出力可否の基準は「簡単に出力できるか?」である。サーバサイドでもtheadタグの出力方法はあると思う。(方法は不明)。
    (*2)JavaScript処理内でtableタグのinnerHTMLとouterHTMLに対して読み書きしているが、innerHTMLとouterHTMLにはブラウザ依存がある。

    ASP.NETでTableSorterを利用する為には、この制限を突破しtheadタグを出力させる必要がある。

    なお後述のサンプルソースではtheadのほかにtbodyも出力している。
    本ページでは関係ないことだが他のテーブル操作プラグインでtbodyが必要な場合もあるため一応出力している。


    ■GridView
    ①Page_Load等で以下のプロパティ設定を行う。
    
    GridView1.UseAccessibleHeader = true;
    GridView1.HeaderRow.TableSection = TableRowSection.TableHeader;
    
    
    ②JavaScriptでtablesorter()関数呼び出し。
    
    $(function () {
        $("#GridView1").tablesorter();
    };
    
    

    ■ListView
    ①aspxファイルでLayoutTemplate・ItemTemplateにtableタグを記述。
    
    <asp:ListView ID="ListView1" runat="server">
        <LayoutTemplate>
            <table id="ListView1Table" class="tablesorter">
                <thead>
                    <tr>
                        <th>No</th>
                        <th>文字列</th>
                    </tr>
                </thead>
                <tbody>
                    <asp:PlaceHolder runat="server" ID="itemPlaceholder" />
                </tbody>
            </table>
        </LayoutTemplate>
        <ItemTemplate>
                <tr>
                    <td><%# Eval("No") %></td>
                    <td><%# Eval("文字列") %></td>
                </tr>
        </ItemTemplate>
    </asp:ListView>
    
    
    ②JavaScriptでtablesorter()関数呼び出し。
    
    $(function () {
        $("#ListView1Table").tablesorter();
    };
    
    

    ■Repeater
    ①aspxファイルでHeaderTemplate・ItemTemplate・FooterTemplateにtableタグを記述。
    
    <asp:Repeater ID="Repeater1" runat="server">
         <HeaderTemplate>
            <table id="Repeater1Table" class="tablesorter">
                <thead>
                    <tr>
                        <th>No</th>
                        <th>文字列</th>
                    </tr>
                </thead>
                <tbody>
        </HeaderTemplate>
        <ItemTemplate>
                    <tr>
                        <td><%# Eval("No") %></td>
                        <td><%# Eval("文字列")%></td>
                    </tr>
        </ItemTemplate>
        <FooterTemplate>
                </tbody>
            </table>
        </FooterTemplate>
    </asp:Repeater>
    
    
    ②JavaScriptでtablesorter()関数呼び出し。
    
    $(function () {
        $("#Repeater1Table").tablesorter();
    };
    
    

    ■DataList
    ①aspxファイルでHeaderTemplate・ItemTemplate・FooterTemplateにtableタグを記述。
    
    <asp:DataList ID="DataList1" runat="server">
        <HeaderTemplate>
            <table id="DataList1Table" class="tablesorter">
                <thead>
                    <tr>
                        <th>No</th>
                        <th>文字列</th>
                    </tr>
                </thead>
                <tbody>
        </HeaderTemplate>
        <ItemTemplate>
                    <tr>
                        <td><%# Eval("No") %></td>
                        <td><%# Eval("文字列")%></td>
                    </tr>
        </ItemTemplate>
        <FooterTemplate>
                </tbody>
            </table>
        </FooterTemplate>
    </asp:DataList>
    
    
    ②Page_Load等で以下のプロパティ設定を行う。
    
    DataList1.RepeatLayout = RepeatLayout.Flow;
    
    
    ③JavaScriptで②の設定変更で出力されるspan・brタグを除去後、tablesorter()関数呼び出し。
    
    $(function () {
        var objDataList1Table = document.getElementById("DataList1Table")
        if ($.browser.msie)
        {
            // IE
            var sDataList1TableHTML = objDataList1Table.outerHTML;
            sDataList1TableHTML = sDataList1TableHTML.replace(/[<]+SPAN[>]+/gi, "");
            sDataList1TableHTML = sDataList1TableHTML.replace(/[<]+\/SPAN[>]+/gi, "");
            sDataList1TableHTML = sDataList1TableHTML.replace(/[<]+BR[>]+/gi, "");
            objDataList1Table.outerHTML = sDataList1TableHTML;
        }
        else
        {
            // FireFox,Opera,Chrome
            var sDataList1TableHTML = objDataList1Table.innerHTML;
            sDataList1TableHTML = sDataList1TableHTML.replace(/[<]+SPAN[>]+/gi, "");
            sDataList1TableHTML = sDataList1TableHTML.replace(/[<]+\/SPAN[>]+/gi, "");
            sDataList1TableHTML = sDataList1TableHTML.replace(/[<]+BR[>]+/gi, "");
            objDataList1Table.innerHTML = sDataList1TableHTML;
        }
        $("#DataList1Table").tablesorter();
    });
    
    

    ■DataGrid
    ①Page_Load等で以下のプロパティ設定を行う。
    
    DataGrid1.ShowHeader = false;
    
    
    ②JavaScriptで「theadタグの付与」「ヘッダー列作成」「tableからstyle属性削除」後、tablesorter()関数呼び出し。
    
    $(function () {
        var objDataGrid1 = document.getElementById("DataGrid1")
        if ($.browser.msie)
        {
            // IE
            var sNewOuterHTML;
            var sNewInnerHTML = "";
            sNewInnerHTML += "<thead><th>No</th><th>文字列</th></thead>";
            sNewInnerHTML += objDataGrid1.innerHTML;
            sNewOuterHTML = objDataGrid1.outerHTML.replace(objDataGrid1.innerHTML, sNewInnerHTML);
            objDataGrid1.outerHTML = sNewOuterHTML;
        }
        else
        {
            // FireFox,Opera,Chrome
            var sNewInnerHTML = "";
            sNewInnerHTML += "<thead><th>No</th><th>文字列</th></thead>";
            sNewInnerHTML += objDataGrid1.innerHTML;
            objDataGrid1.innerHTML = sNewInnerHTML;
        }
        $("#DataGrid1").removeAttr("style");
        $("#DataGrid1").tablesorter();
    });
    
    

    ASP.NET(C#)とJQuery+TableSorterを連携したときのサンプルソースを記述する。
    
    <%@ Page Language="C#" AutoEventWireup="true" %>
    <%@ Import Namespace="System.Data" %>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title>各種グリッド+TableSorter</title>
        <script src="../js/jquery/jquery-1.3.2.js" type="text/ecmascript"></script>
        <link href="../js/Tablesorter/blue/style.css" rel="stylesheet" type="text/css" />
        <script src="../js/Tablesorter/jquery.tablesorter.js" type="text/javascript"></script>
        <script type="text/C#" runat="server">
        /// <summary>
        /// Page_Load
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                //-------------------------------------------------------------------------------------
                // DataTable作成
                //-------------------------------------------------------------------------------------
                DataTable dt = new DataTable("DataTable");
                dt.Columns.Add("No", typeof(int));
                dt.Columns.Add("文字列", typeof(string));
                for (int i = 1; i <= 3; i++)
                {
                    DataRow dr = dt.NewRow();
                    dr[0] = i;
                    dr[1] = string.Format("文字{0}", 4-i);
                    dt.Rows.Add(dr);
                }
                //-------------------------------------------------------------------------------------
                // テーブル系コントロール設定
                //-------------------------------------------------------------------------------------
                // GridView
                GridView1.DataSource = dt;
                GridView1.DataBind();
                GridView1.UseAccessibleHeader = true;
                GridView1.HeaderRow.TableSection = TableRowSection.TableHeader;
                // ListView
                ListView1.DataSource = dt;
                ListView1.DataBind();
                // Repeater
                Repeater1.DataSource = dt;
                Repeater1.DataBind();
                // DataList
                DataList1.DataSource = dt;
                DataList1.DataBind();
                DataList1.RepeatLayout = RepeatLayout.Flow;
                // DataGrid
                DataGrid1.DataSource = dt;
                DataGrid1.DataBind();
                DataGrid1.ShowHeader = false;
            }
        }
        </script>
        <script type="text/ecmascript">
            $(function () {
                //-------------------------------------------------------------------------------------
                // Tablesorterの有効化
                // <注意1>
                // Tablesorterにはthead,tbodyが必要。しかしDataList,DataGridコントロールは
                // サーバサイド処理でthead,tbodyを出すのが困難なため、クライアントスクリプトで
                // 強引にthead,tbodyを付与している。
                // <注意2>
                // 注意1に関連することだがIE系はtableタグのinnerHTMLは読取専用である。
                // このためinnerHTMLの代用としてouterHTMLを使っている。
                // ちなみにFirefoxはouterHTMLがない。
                // <注意3>
                // DataListはHTML上部にspanタグをレンダリングする。これがレイアウトをおかしくする。
                //-------------------------------------------------------------------------------------
                // GridView
                $("#GridView1").tablesorter();
                // ListView
                $("#ListView1Table").tablesorter();
                // Repeater
                $("#Repeater1Table").tablesorter();
                // DataList
                var objDataList1Table = document.getElementById("DataList1Table")
                if ($.browser.msie)
                {
                    // IE
                    var sDataList1TableHTML = objDataList1Table.outerHTML;
                    sDataList1TableHTML = sDataList1TableHTML.replace(/[<]+SPAN[>]+/gi, "");
                    sDataList1TableHTML = sDataList1TableHTML.replace(/[<]+\/SPAN[>]+/gi, "");
                    sDataList1TableHTML = sDataList1TableHTML.replace(/[<]+BR[>]+/gi, "");
                    objDataList1Table.outerHTML = sDataList1TableHTML;
                }
                else
                {
                    // FireFox,Opera,Chrome
                    var sDataList1TableHTML = objDataList1Table.innerHTML;
                    sDataList1TableHTML = sDataList1TableHTML.replace(/[<]+SPAN[>]+/gi, "");
                    sDataList1TableHTML = sDataList1TableHTML.replace(/[<]+\/SPAN[>]+/gi, "");
                    sDataList1TableHTML = sDataList1TableHTML.replace(/[<]+BR[>]+/gi, "");
                    objDataList1Table.innerHTML = sDataList1TableHTML;
                }
                $("#DataList1Table").tablesorter();
                // DataGrid
                var objDataGrid1 = document.getElementById("DataGrid1")
                if ($.browser.msie)
                {
                    // IE
                    var sNewOuterHTML;
                    var sNewInnerHTML = "";
                    sNewInnerHTML += "<thead><th>No</th><th>文字列</th></thead>";
                    sNewInnerHTML += objDataGrid1.innerHTML;
                    sNewOuterHTML = objDataGrid1.outerHTML.replace(objDataGrid1.innerHTML, sNewInnerHTML);
                    objDataGrid1.outerHTML = sNewOuterHTML;
                }
                else
                {
                    // FireFox,Opera,Chrome
                    var sNewInnerHTML = "";
                    sNewInnerHTML += "<thead><th>No</th><th>文字列</th></thead>";
                    sNewInnerHTML += objDataGrid1.innerHTML;
                    objDataGrid1.innerHTML = sNewInnerHTML;
                }
                $("#DataGrid1").removeAttr("style");
                $("#DataGrid1").tablesorter();
            });
        </script>
    </head>
    <body>
    <form id="form1" runat="server">
    GridView:
    <asp:GridView ID="GridView1" runat="server" CssClass="tablesorter"></asp:GridView>
    ListView:<br />
    <asp:ListView ID="ListView1" runat="server">
        <LayoutTemplate>
            <table id="ListView1Table" class="tablesorter">
                <thead>
                    <tr>
                        <th>No</th>
                        <th>文字列</th>
                    </tr>
                </thead>
                <tbody>
                    <asp:PlaceHolder runat="server" ID="itemPlaceholder" />
                </tbody>
            </table>
        </LayoutTemplate>
        <ItemTemplate>
                <tr>
                    <td><%# Eval("No") %></td>
                    <td><%# Eval("文字列") %></td>
                </tr>
        </ItemTemplate>
    </asp:ListView>
    Repeater:<br />
    <asp:Repeater ID="Repeater1" runat="server">
         <HeaderTemplate>
            <table id="Repeater1Table" class="tablesorter">
                <thead>
                    <tr>
                        <th>No</th>
                        <th>文字列</th>
                    </tr>
                </thead>
                <tbody>
        </HeaderTemplate>
        <ItemTemplate>
                    <tr>
                        <td><%# Eval("No") %></td>
                        <td><%# Eval("文字列")%></td>
                    </tr>
        </ItemTemplate>
        <FooterTemplate>
                </tbody>
            </table>
        </FooterTemplate>
    </asp:Repeater>
    DataList:<br />
    <asp:DataList ID="DataList1" runat="server">
        <HeaderTemplate>
            <table id="DataList1Table" class="tablesorter">
                <thead>
                    <tr>
                        <th>No</th>
                        <th>文字列</th>
                    </tr>
                </thead>
                <tbody>
        </HeaderTemplate>
        <ItemTemplate>
                    <tr>
                        <td><%# Eval("No") %></td>
                        <td><%# Eval("文字列")%></td>
                    </tr>
        </ItemTemplate>
        <FooterTemplate>
                </tbody>
            </table>
        </FooterTemplate>
    </asp:DataList>
    DataGrid:<br />
    <asp:DataGrid ID="DataGrid1" runat="server" CssClass="tablesorter" AutoGenerateColumns="false">
        <Columns>
            <asp:BoundColumn DataField="No" />
            <asp:BoundColumn DataField="文字列" />
        </Columns>
    </asp:DataGrid>
    </form>
    </body>
    </html>
    
    



    上記ソースからASP.NETのグリッド系コントロールとTableSorterの有効な組み合わせなのは、GridView・ListView・Repeater だと考えられる。
    DataList・DataGridも利用可能だがJavaScriptによるタグ操作がある為、表示後にサーバサイド処理と連携すると 何らかの問題が発生する可能性が高い。
    またDataListはspan・brタグの置換が発生するため画面自由度が低減する。
    他にDataListはFirefox・Chromeでコントロール上部のレイアウトが崩れることも確認している。




    Google AdSense


    • ---

    Amazon ウィジェット

    • ウィジェット

    @niyo_naのツイート

    無料ブログはココログ

    Google Analytics