Ich verwende den folgenden Code auf einer ASPX-Seite beim Klicken auf ein Schaltflächenereignis, um eine CSV-Datei zu generieren. Dies funktioniert, wenn ich meine Datei nicht benenne, aber versuche, Folgendes zu verwenden: Response.AddHeader ("Content-Disposition", "attachment; Dateiname = meinDateiname.csv");
um die Datei mit dem Dateinamen myfilename.csv zu benennen, ist das erzeugte Excel-Blatt der Screenshot der Webseite und nicht der Text. Kann mir jemand bei diesem Problem helfen?.
Vielen Dank!
DataGrid dg = new DataGrid();
dg.DataSource = GetData();
htmlTextWriter.WriteLine("<b>Details</b>");
//Get the html for the control
dg.HeaderStyle.Font.Bold = true;
dg.HeaderStyle.BackColor = System.Drawing.Color.Gray;
dg.DataBind();
dg.RenderControl(htmlTextWriter);
//Write the HTML back to the browser.
Response.Clear();
Response.ContentType = "application/vnd.ms-Excel";
//Response.AddHeader("Content-Disposition", "attachment;filename=myfilename.csv");
this.EnableViewState = false;
Response.Write(textWriter.ToString());
Response.End();
private System.Data.DataTable GetData()
{
System.Data.DataTable dt = new System.Data.DataTable("TestTable");
dt.Columns.Add("SSN");
dt.Columns.Add("Employee ID");
dt.Columns.Add("Member Last Name");
dt.Columns.Add("Member First Name");
dt.Columns.Add("Patient Last Name");
dt.Columns.Add("Patient First Name");
dt.Columns.Add("Claim No.");
dt.Columns.Add("Service Line No.");
dt.Columns.Add("Error Code");
dt.Columns.Add("Error Message");
dt.Rows.Add(123456789,4455,"asdf","asdf","sdfg","xzcv","dsfgdfg123",1234,135004,"some error");
dt.Rows.Add(123456788,3344,"rth","ojoij","poip","wer","aadf124",1233,135005,"Some Error");
dt.Rows.Add(123456787,2233,"dfg","sdfg","vcxb","cxvb","UHCAL125",1223,135006,"another error");
return dt;
}
Ich bin mir nicht ganz sicher, was Sie hier anstreben, also bin ich davon ausgegangen, dass Sie eine CSV-Datei in einem Schaltflächenklickereignis erstellen und an den Benutzer zurücksenden möchten. Was Sie derzeit haben, scheint den HTML-Code des Steuerelements in eine XLS-Datei zu schreiben.
Versuche dies:
protected void Button1_Click(object sender, EventArgs e)
{
var dataTable = GetData();
StringBuilder builder = new StringBuilder();
List<string> columnNames = new List<string>();
List<string> rows = new List<string>();
foreach (DataColumn column in dataTable.Columns)
{
columnNames.Add(column.ColumnName);
}
builder.Append(string.Join(",", columnNames.ToArray())).Append("\n");
foreach (DataRow row in dataTable.Rows)
{
List<string> currentRow = new List<string>();
foreach (DataColumn column in dataTable.Columns)
{
object item = row[column];
currentRow.Add(item.ToString());
}
rows.Add(string.Join(",", currentRow.ToArray()));
}
builder.Append(string.Join("\n", rows.ToArray()));
Response.Clear();
Response.ContentType = "text/csv";
Response.AddHeader("Content-Disposition", "attachment;filename=myfilename.csv");
Response.Write(builder.ToString());
Response.End();
}
Bei der Ausführung werde ich vom Browser aufgefordert, die CSV-Datei zu speichern.
Bearbeiten:
Wenn Sie Ihren aktuellen Ansatz beibehalten möchten (der HTML und nicht CSV erzeugt), versuchen Sie Folgendes:
Response.AddHeader("Content-Disposition", "attachment;filename=myfilename.xls");
Beachten Sie, dass ich die Dateierweiterung einfach von CSV in XLS geändert habe. Bei Verwendung der CSV-Erweiterung wurde der Text in Excel als HTML angezeigt. Bei Verwendung von XLS wird es genauso angezeigt, wenn die obige Zeile auskommentiert wird.
Schließlich denke ich, dass ich herausgefunden habe, dass wir einen http-Handler schreiben müssen, wenn wir Excel-Dateien auf asp.net-Seiten generieren wollen. :)
Vielen Dank, alles Gute
public class TestHandler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
StringWriter textWriter = new StringWriter();
Html32TextWriter htmlTextWriter = new Html32TextWriter(textWriter);
DataGrid dg = new DataGrid();
dg.DataSource = GetData();
//Get the html for the control
dg.EnableViewState = false;
dg.DataBind();
dg.RenderControl(htmlTextWriter);
//Write the HTML back to the browser.
context.Response.Clear();
//context.Response.AddHeader("Content-Disposition", string.Format("attachment;filename=test.csv"));
//context.Response.ContentType = "text/csv";
context.Response.AddHeader("Content-Disposition", string.Format("attachment;filename=abc.xls"));
context.Response.ContentType = "application/vnd.ms-Excel";
context.Response.Write(textWriter.ToString());
context.Response.End();
}
public bool IsReusable
{
get
{
return false;
}
}
}
Entspricht der NickW-Lösung, aber mit LINQ noch genauer:
//Append column names
builder.Append(String.Join(",",
from DataColumn c in dataTable.Columns
select c.ColumnName
)).Append("\n");
//Append data from datatable
builder.Append(string.Join("\n",
from DataRow row in dataTable.Rows
select String.Join("\n",
String.Join(",", row.ItemArray)
)
));
Response.Clear();
Response.ContentType = "text/csv";
Response.AddHeader("Content-Disposition", "attachment;filename=myfilename.csv");
Response.Write(builder.ToString());
Response.End();
Versuchen Sie dies zu ändern:
Response.ContentType = "application/text";
Oder
Response.ContentType = "text/csv";