我尝试将DataTable的内容作为Excel .csv文件导出到用户的浏览器中。当我点击"导出"按钮并在调试器中单步执行我的代码,一切看起来都在发生,但实际上没有文件发送到浏览器。问题是,我在另一个项目中使用这个完全相同的代码,它在那里工作。
编辑:这是包含按钮的整个UpdatePanel的ASPX标记:
<asp:UpdatePanel ID="updNoUsage" runat="server">
<ContentTemplate>
<asp:Button ID="btnNoUsageLookup" runat="server" Text="Get No Usage Lines Report"
OnClick="btnNoUsageLookup_Click" /><br /><br />
<asp:Label ID="lblNoUsageMessage" runat="server" Font-Bold="True" ForeColor="Blue"
Text="Message" Visible="False"></asp:Label><br /><br />
<asp:Panel ID="pnlNoUsageReport" runat="server" Visible="False" BorderStyle="None">
<asp:GridView ID="gvNoUsage" runat="server" AllowPaging="True" AllowSorting="True"
AutoGenerateColumns="False" BorderColor="#666666" BorderStyle="Solid"
BorderWidth="1px" PageSize="25" OnPageIndexChanging="gv_PageIndexChanging"
OnSorting="gv_Sorting" OnRowCreated="gvNoUsage_RowCreated">
<HeaderStyle BackColor="Transparent" />
<RowStyle BackColor="#e5e5e5" />
<AlternatingRowStyle BackColor="White" />
<Columns>
<asp:BoundField DataField="CostCenter" HeaderText="Cost Center" SortExpression="CostCenter" />
<asp:BoundField DataField="WirelessNumber" HeaderText="Wireless Number" SortExpression="WirelessNumber" />
<asp:BoundField DataField="ESN" HeaderText="ESN" SortExpression="ESN" />
<asp:BoundField DataField="UserName" HeaderText="User Name" SortExpression="UserName" />
<asp:BoundField DataField="Model" HeaderText="Handset Model" SortExpression="Model" />
</Columns>
</asp:GridView>
<ajaxToolkit:AnimationExtender ID="aeNoUsage" runat="server"
TargetControlID="gvNoUsage">
<Animations>
<OnLoad>
<Sequence>
<FadeIn AnimationTarget="gvNoUsage" Duration=".25" />
</Sequence>
</OnLoad>
</Animations>
</ajaxToolkit:AnimationExtender>
<br /><br />
<asp:Button ID="btnNoUsageExport" runat="server" CausesValidation="false"
Text="Export to Excel" OnClick="btnExport_Click" />
</asp:Panel>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="btnNoUsageLookup" EventName="Click" />
<asp:AsyncPostBackTrigger ControlID="btnNoUsageExport" EventName="Click" />
</Triggers>
</asp:UpdatePanel>
这是&#34; btnExport_Click&#34; C#函数在后面的代码中:
protected void btnExport_Click(object sender, EventArgs e)
{
//Get dataset and output filename
DataTable dt = dtNoUsage;
string exportFile = "No Usage Report.csv";
//Now convert DataSet to a CSV file
// Clear the response so there is nothing coming back.
Response.Clear();
Response.ClearHeaders();
// Add an HTTP header for the content type to tell the browser that this is a file that is being passed back.
Response.AddHeader("Content-Disposition", string.Format("attachment; filename={0}", exportFile));
// Tell the browser the correct file type (should cause the file to open with Microsoft Excel)
Response.ContentType = "application/vnd.ms-excel";
// Get CSV file from DataTable
string csvData = HelperFunctions.CreateCSVFile(dt);
// Write the response to the HTTP stream back to the client browser
Response.Write(csvData);
// End the stream write and commit it
Response.End();
}
这里是HelperFunctions.CreateCSVFile()方法:
public static string CreateCSVFile(DataTable dt)
{
// Build the file line by line from the DataSet
StringBuilder sbFile = new StringBuilder();
// Add the header row
for (int i = 0; i < dt.Columns.Count; i++)
{
sbFile.AppendFormat("{0}", EscapeCSVField(dt.Columns[i].ColumnName));
if (i < dt.Columns.Count - 1)
{
sbFile.Append(",");
}
}
// Add a newline
sbFile.AppendLine(String.Empty);
// Add the data rows
for (int i = 1; i < dt.Rows.Count; i++)
{
for (int j = 0; j < dt.Columns.Count; j++)
{
sbFile.AppendFormat("{0}", EscapeCSVField(dt.Rows[i][j].ToString().Trim()));
if (j < dt.Columns.Count - 1)
{
sbFile.Append(",");
}
}
// Add a newline
sbFile.AppendLine(String.Empty);
}
return sbFile.ToString();
}
就像我说的,这个相同的代码在另一个项目中完美运行。任何想法可能会发生什么?
编辑:我看了Fiddler的回复,据我所知,正确的回复又回来了 - 浏览器(Chrome,IE,Firefox)只是没有响应文件发送。这是响应的样子:
HTTP/1.1 200 OK
Cache-Control: public
Content-Type: application/vnd.ms-excel; charset=utf-8
Server: Microsoft-IIS/8.0
Content-Disposition: attachment; filename=Upgrade Eligibility Report.csv
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?YzpcdXNlcnNcdGltb3RoeWJcZG9jdW1lbnRzXHZpc3VhbCBzdHVkaW8gMjAxMlxQcm9qZWN0c1xXaXJlbGVzc0JpbGxpbmdWMlxXaXJlbGVzc0JpbGxpbmdWMlxVc2VyXFdpcmVsZXNzQmlsbGluZy5hc3B4?=
X-Powered-By: ASP.NET
Date: Tue, 29 Oct 2013 15:19:43 GMT
Content-Length: 16310
然后有一个空行,文件内容被转储。内容也看起来正确。我感到困惑。
答案 0 :(得分:8)
正如@JoeEnos解释的那样,你的UpdatePanel是罪魁祸首。让btnNoUsageExport
在UpdatePanel的触发器部分中进行回发:
<asp:PostBackTrigger ControlID="btnNoUsageExport" />
这就是MS的AJAX脚本解释的response will be sent to the browser instad。
答案 1 :(得分:7)
UpdatePanel可能是这里的问题。您正在将文件直接写入响应,但UpdatePanel正在使用Microsoft的时髦AJAX voodoo,它希望其结果可以作为自己特殊的HTML和数据返回。我敢打赌他们的javascript会抛出错误。
如果从更新面板中删除该按钮,则应该没问题。