以.xlsx格式导出GridView到Excel时出错

时间:2015-07-30 17:13:45

标签: c# asp.net excel-2010 export-to-excel aspxgridview

我想将GridView导出为ex​​cel(格式为.xlsx)。 这是我的代码

using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Collections;
using System.IO;

public partial class _Default : System.Web.UI.Page
{
 GridView gv;

protected void Button1_Click(object sender, EventArgs e)
{
    setGridView();
    Response.Clear();
    Response.ClearContent();
    Response.ClearHeaders();
    string fileName = "TestExcelFile.xlsx";
    Response.Buffer = true;
    Response.AddHeader("Content-Disposition", "attachment;filename=" + fileName);
    Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
    //Response.ContentType = "application/vnd.ms-excel"; // Works perfectly for .xls files
    StringWriter sw = new StringWriter();
    HtmlTextWriter htw = new HtmlTextWriter(sw);
    gv.RenderControl(htw);
    Response.Write(sw.ToString());
    Response.Flush();
    Response.End();
}

private void setGridView()
{
    gv = new GridView();
    Queue q = new Queue();
    for (int i = 0; i < 20; i++)
    {
        q.Enqueue(i);
    }
    gv.DataSource = q;
    gv.DataBind();
 }
}

如果我将响应内容类型保持为:Response.ContentType = "application/vnd.ms-excel";,那么它适用于excel的.xls格式。

但是对于excel文件为.xlsx格式,内容类型应为:Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";

我可以使用.xls格式,但问题是.xls格式只能容纳64000条记录,根据我的项目要求,我将得到近100000(100K)行。所以我必须将它导出为.xlsx格式的Excel才能保存64000以上的记录。

这是错误Text&amp;图片: &#34; Excel无法打开文件&#39; TestExcelFile [2] .xlsx&#39;因为文件扩展名的文件格式无效。验证文件是否已损坏,文件扩展名是否与文件格式匹配。&#34; Error while opening the exported Excel File

2 个答案:

答案 0 :(得分:1)

首先,我不知道“Lakh”是什么,但我猜它超过了65535,但据我所知,ASP.NET Gridview无法直接将其导出为XLSX格式,因为它输出了它作为原始HTML。

我建议您查看一些像EPPlus(http://epplus.codeplex.com/)这样的组件,它可以更加灵活和可扩展,以满足您的需求。

你可以做什么,作为一种解决方法,虽然这不会那么优雅,但是尝试以下代码:

protected void btnExportData_Click(object sender, EventArgs e)
{
    Response.Clear();

    Response.AddHeader("content-disposition", "attachment;filename=output.xlsx");
    Response.Charset = "";
    Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";

    System.IO.StringWriter sw = new System.IO.StringWriter();
    System.Web.UI.HtmlTextWriter htmlWriter = new HtmlTextWriter(sw);

    foreach (GridViewRow row in gvData.Rows)
    {
        if (row.RowType == DataControlRowType.DataRow)
            for (int idxColumn = 0; idxColumn < row.Cells.Count; idxColumn++)
                row.Cells[idxColumn].Attributes.Add("class", "xlText");
    }

    gvData.RenderControl(htmlWriter);

    string appendStyle = @"<style> .xlText { mso-number-format:\@; } </style> ";
    Response.Write(appendStyle);

    Response.Write(sw.ToString());
    Response.End();
}

我已经使用了那个之前的Excel 2007,但这是一个黑客而不是非常优雅。

答案 1 :(得分:0)

另一种解决方案(只会让你说服{J {@}},正如JaggenSWE在我之前提到的那样,当比较相对工作量时)正在使用Microsoft.Office.Interop.Excel工具...

using Microsoft.Office.Interop.Excel

string path = @"C:\testoutput\output.xlsx";

Microsoft.Office.Interop.Excel.Application oXL;
Microsoft.Office.Interop.Excel.Workbook oBook;
Microsoft.Office.Interop.Excel.Worksheet oSheet;
Microsoft.Office.Interop.Excel.Range oRng;

oXL = new Microsoft.Office.Interop.Excel.Application();
oXL.Visible = false; //This can be fun to leave enabled though :)
oXL.UserControl = false;

oBook = oXL.Workbooks.Add();
oSheet = oBook.ActiveSheet;

//This part can take a while, so throwing it into an async method elsewhere may be a thought
for (int x = 0; x < gv.Rows.Count; x++)
{
    for (int y = 0; y < gv.Columns.Count; y++)
    {
        oSheet.Cells[x + 2, y + 1] = gv.Rows[x].Cells[y].ToString();
    }
}
oBook.SaveAs(path, Microsoft.Office.Interop.Excel.XlFileFormat.xlOpenXMLWorkbook);

oBook.Close(); //Don't forget this because the program will not close it automatically!!!