0

Excel でデータをエクスポートしようとしている場所をデバッグするコードがあります。小さいデータでは問題なく動作しますが、データ サイズが数千に増えると、「メモリ不足の例外」が発生します。私のアプリケーションは IIS 6.0 で実行されています。推奨事項はありますか?

PS: 通常、プロセスは 1.2 GB を超えるメモリを使用すると失敗します (タスク マネージャーを参照)。

Protected Overrides Sub Render(ByVal writer As System.Web.UI.HtmlTextWriter)
  If (IsExportToCSV) Then
  Response.Clear()
        Response.ContentType = "application/vnd.ms-excel"

        Response.ContentType = "a"
        'Remove the charset from the Content-Type header.
        Response.Charset = ""
        'Turn off the view state.
        Page.EnableViewState = False
        Dim tw As System.IO.StringWriter
        tw = New System.IO.StringWriter
        Dim hw As HtmlTextWriter = New HtmlTextWriter(tw)
        'Get the HTML for the control.
        Me.GridView1.AllowPaging = False
        Me.GridView1.DataBind()
        Me.GridView1.EnableViewState = False
        Me.GridView1.AutoGenerateEditButton = False
        Me.GridView1.RenderControl(hw)
        Response.Write(tw.ToString)
        Response.Flush()
        Response.End()

    Else
        MyBase.Render(writer)
    End If

End Sub
4

2 に答える 2

4

完璧なソリューション!

私はしばらくこれと戦ってきましたが、解決策はとても簡単です。文字列がメモリに存在するため、応答書き込みに渡す文字列を作成しないでください。代わりに、複数の Response.Write 呼び出しを使用して、各行を直接応答に入れます。

HTMLテーブルに変換され、Excelとしてクライアントに送信されるDataTableの例...

string contentType = "Reports.xls";
string fileName = "application/msexcel";

Response.Clear();
Response.Buffer = true;
Response.ContentType = contentType;
string attachment = string.Format("attachment; filename=\"{0}\"", fileName);
Response.AddHeader("Content-Disposition: ", attachment);
byte[] preamble = Encoding.UTF8.GetPreamble();
Response.BinaryWrite(preamble);

string strFontSize = "12";

Response.Write("<html xmlns:o=\"urn:schemas-microsoft-com:office:office\" \r\n xmlns:x=\"urn:schemas-microsoft-com:office:excel\" \r\n xmlns=\"http://www.w3.org/TR/REC-html40\">");
Response.Write(@"<head>");
Response.Write("<meta http-equiv=Content-Type content=\"text/html; charset=windows-1252\">");
Response.Write("<meta name=ProgId content=Excel.Sheet>");
Response.Write("<meta name=Generator content=\"Microsoft Excel 11\">");
Response.Write(@"</head>");
Response.Write(@"<body>");

Response.Write(@"<table style='width: 100%; font-size:" + strFontSize + ";' border='1'>");

foreach (DataColumn column in dt.Columns)
    {
        Response.Write(@"<td><b>" + column.ColumnName + "</b></td>");
    }
Response.Write(@"</tr>");

int intCell = 0;
string strCell = "";
foreach (DataRow row in dt.Rows)
    {
        intCell = 0;
        Response.Write(@"<tr>");
        foreach (DataColumn column in dt.Columns)
        {
            strCell = row.ItemArray[dt.Columns[column.ColumnName].Ordinal].ToString().Trim();
            Response.Write(@"<td>" + strCell + "</td>");
        }
        Response.Write(@"</tr>");
    }
Response.Write(@"</table>");
Response.Write(@"</body>");
Response.Write(@"</html>");
Response.End();
于 2012-10-31T19:22:27.183 に答える
1

StringWriter を介して渡すのではなく、各行を直接応答ストリームに書き込む

于 2012-08-28T14:29:47.943 に答える