简体   繁体   中英

Unable to generate the .xlsx file

I have a text file which is in tab deliminator and following is my code to generate its Excel.

protected void to_excel(object sender, EventArgs e)
    {
        string filepath = Path.Combine(Server.MapPath("~/Files"), fileupload.FileName);
        fileupload.SaveAs(filepath);
        string fname = fileupload.PostedFile.FileName;
        DataTable dt = (DataTable)ReadToEnd(filepath);
        string sFilename = fname.Substring(0, fname.IndexOf("."));
        HttpResponse response = HttpContext.Current.Response;
        Response.Clear();
        Response.AddHeader("content-disposition", "attachment;filename=" + sFilename + ".xls");
        Response.Charset = "";
        Response.Cache.SetCacheability(HttpCacheability.NoCache);
        Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
        System.IO.StringWriter stringWrite = new System.IO.StringWriter();
        System.Web.UI.HtmlTextWriter htmlWrite = new System.Web.UI.HtmlTextWriter(stringWrite);
        System.Web.UI.WebControls.DataGrid dg = new System.Web.UI.WebControls.DataGrid();
        dg.DataSource = dt;
        dg.DataBind();
        dg.RenderControl(htmlWrite);
        Response.Write(stringWrite.ToString());
        Response.End();
    }
    private object ReadToEnd(string filePath)
    {
        DataTable dtDataSource = new DataTable();
        string[] fileContent = File.ReadAllLines(filePath);
        if (fileContent.Count() > 0)
        {
            string[] columns = fileContent[0].Split('\t');
            for (int i = 0; i < columns.Count(); i++)
            {
                dtDataSource.Columns.Add(columns[i]);
            }
            for (int i = 1; i < fileContent.Count(); i++)
            {
                string[] rowData = fileContent[i].Split('\t');
                dtDataSource.Rows.Add(rowData);
            }
        }
        return dtDataSource;
    }

This code works fine since i am generating 2003 excel file (.xls).

But if i am generating a 2007 (.xlsx) by changing the code to

Response.AddHeader("content-disposition", "attachment;filename=" + sFilename + ".xlsx");

i get an error like this .

I did my homework and came to know that this error is because the .xlsx file generated by my program is done by using HTML (markup language) XML (markup language) which should actually be done for a 2007 excel file.

My question is what changes should i do so that i get the desired result ie I get the 2007 excel sheet!!!

You can create the Excel with multiple Worksheet using DataSet like

using Excel = Microsoft.Office.Interop.Excel;
using Microsoft.Office.Interop.Excel;
using System.Data;
using System.IO;

[HttpPost]
    public ActionResult CreateExcel(int id)
    {
        DataSet dataSet = new DataSet(); //Your Data Set
        if (dataSet.Tables.Count > 0)
        {
            System.Data.DataTable dt1 = new System.Data.DataTable();
            System.Data.DataTable dt2 = new System.Data.DataTable();
            dt1 = dataSet.Tables[0];
            dt2 = dataSet.Tables[1];

            if (dt1.Rows.Count > 1 && dt2.Rows.Count > 1)
            {
                var excel = new Microsoft.Office.Interop.Excel.Application();
                var workbook = excel.Workbooks.Add(true);

                AddExcelSheet(dt1, workbook);
                AddExcelSheet(dt2, workbook);

                //KK-Save the excel file into server path
                string strLocation = "~/Upload/TempExcel/";
                string fName = "Report_" + DateTime.Now.ToString("MMddyyyyHHmmss") + ".xlsx";
                string strPath = Path.Combine(Server.MapPath(strLocation), fName);
                workbook.SaveAs(strPath);
                workbook.Close();

                //KK-Generate downloading link view page
                System.Web.HttpResponse Response = System.Web.HttpContext.Current.Response;
                Response.ClearContent();
                Response.Clear();
                //Response.ContentType = "application/vnd.ms-excel";  //This is for office 2003
                Response.ContentType = "application/application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
                Response.AppendHeader("Content-Disposition", "attachment; filename=YourReport.xlsx");
                Response.TransmitFile(strPath);
                Response.Flush();
                Response.End();

                //KK-Deleting the file after downloading
                if (System.IO.File.Exists(strPath))
                    System.IO.File.Delete(strPath);
            }
        }

        return View();
    }

    /// <summary>
    /// KK-This method add new Excel Worksheet using DataTable
    /// </summary>
    /// <param name="ds"></param>
    private static void AddExcelSheet(System.Data.DataTable dt, Workbook wb)
    {
        Excel.Sheets sheets = wb.Sheets;
        Excel.Worksheet newSheet = sheets.Add();

        int iCol = 0;

        foreach (DataColumn c in dt.Columns)
        {
            iCol++;
            newSheet.Cells[1, iCol] = c.ColumnName;
            newSheet.Cells[1, iCol].Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.RoyalBlue);
            newSheet.Cells[1, iCol].Font.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.White);
            newSheet.Cells[1, iCol].Font.Bold = true;
            newSheet.Cells[1, iCol].BorderAround(Excel.XlLineStyle.xlContinuous, Excel.XlBorderWeight.xlThin);
        }

        int iRow = 0;
        foreach (DataRow r in dt.Rows)
        {
            iRow++;

            // add each row's cell data...
            iCol = 0;

            foreach (DataColumn c in dt.Columns)
            {
                iCol++;
                newSheet.Cells[iRow + 1, iCol] = r[c.ColumnName];
                newSheet.Cells[iRow + 1, iCol].BorderAround(Excel.XlLineStyle.xlContinuous, Excel.XlBorderWeight.xlThin);
            }
        }

    }

You should check the OpenXML SDK: http://msdn.microsoft.com/en-us/library/office/gg278328.aspx

Alternatively, you can check the various commercial libraries listed here: http://polymathprogrammer.com/spreadsheetopenxml/spreadsheetcodelibrariescomparison.pdf

I had a good experience with Aspose Cells.

PS: your code doesn't generate a valid xls file, but html that gets somehow correctly interpreted by excel.

You have to use extended libraries which I recommend using EPPlus which is a .net library that reads & writes Excel 2007/2010 files using the Open Office Xml format (xlsx). Library

and then replace the code

protected void to_excel(object sender, EventArgs e)
    {
        string filepath = Path.Combine(Server.MapPath("~/Files"), fileupload.FileName);
        fileupload.SaveAs(filepath);
        string fname = fileupload.PostedFile.FileName;
        DataTable dt = (DataTable)ReadToEnd(filepath);
        string sFilename = fname.Substring(0, fname.IndexOf("."));
        sFilename = sFilename + ".xlsx";
        MemoryStream ms = DataTableToExcelXlsx(dt, "Sheet1");
        ms.WriteTo(HttpContext.Current.Response.OutputStream);
        HttpContext.Current.Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
        HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment;filename=" + sFilename);
        HttpContext.Current.Response.StatusCode = 200;
        HttpContext.Current.Response.End();
    }

public void toexcel(DataTable dt, string Filename)
    {
        MemoryStream ms = DataTableToExcelXlsx(dt, "Sheet1");
        ms.WriteTo(HttpContext.Current.Response.OutputStream);
        HttpContext.Current.Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
        HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment;filename=" + Filename);
        HttpContext.Current.Response.StatusCode = 200;
        HttpContext.Current.Response.End();
    }
    public bool IsReusable
    {
        get { return false; }
    }
    public static MemoryStream DataTableToExcelXlsx(DataTable table, string sheetName)
    {
        MemoryStream Result = new MemoryStream();
        ExcelPackage pack = new ExcelPackage();
        ExcelWorksheet ws = pack.Workbook.Worksheets.Add(sheetName);
        int col = 1;
        int row = 1;
        foreach (DataColumn column in table.Columns)
        {
            ws.Cells[row, col].Value = column.ColumnName.ToString();
            col++;
        }
        col = 1;
        row = 2;
        foreach (DataRow rw in table.Rows)
        {
            foreach (DataColumn cl in table.Columns)
            {
                if (rw[cl.ColumnName] != DBNull.Value)
                    ws.Cells[row, col].Value = rw[cl.ColumnName].ToString();
                col++;
            }
            row++;
            col = 1;
        }
        pack.SaveAs(Result);
        return Result;
    }

I got this solution here

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM