web-dev-qa-db-fra.com

Générer un fichier CSV en ASP.Net

J'utilise le code ci-dessous sur une page aspx sur un événement de clic sur un bouton pour générer un fichier csv. Cela fonctionne lorsque je ne nomme pas mon fichier mais lorsque j'essaie d'utiliser: Response.AddHeader ("Content-Disposition", "pièce jointe; nom du fichier = nomfichier.csv");

pour nommer le fichier comme mon_fichier.csv, la feuille Excel générée est la capture d'écran de la page Web au lieu de contenir du texte. Quelqu'un peut-il m'aider avec ce problème.
Merci!

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;
}
12
user1178192

Je ne suis pas tout à fait sûr de ce que vous visez ici. J'ai donc supposé que vous souhaitiez créer un fichier CSV dans un événement de clic sur un bouton et le renvoyer à l'utilisateur. Ce que vous avez actuellement semble écrire le code HTML du contrôle dans un fichier XLS.

Essaye ça:

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();
}

Lorsque je lance ceci, le navigateur me demande de sauvegarder le fichier CSV.

Modifier:

Si vous souhaitez conserver votre approche actuelle (produire du HTML, pas du CSV), essayez ceci:

Response.AddHeader("Content-Disposition", "attachment;filename=myfilename.xls");

Notez que j'ai simplement changé l'extension de fichier de CSV à XLS. Lors de l'utilisation de l'extension CSV, le texte apparaît dans Excel au format HTML. En utilisant XLS, il apparaît exactement comme lorsque la ligne ci-dessus est commentée.

17
nick_w

Enfin, je pense que nous avons compris, nous devons écrire un gestionnaire http si nous voulons générer des fichiers Excel sur des pages asp.net. Désormais, mon bouton_click redirige simplement la page TestHandler.ashx et rend le fichier Excel. :)

Merci beaucoup tous vous guyz 

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;
        }
    }
}
1
user1178192

Identique à la solution de NickW, mais plus concise avec LINQ:

//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();
1
Zev Spitz

Essayez de changer ceci:

Response.ContentType = "application/text";

Ou

Response.ContentType = "text/csv";
0
Amin Sayed