3

I have data-table which contain no of column also with date with "DATE" datatype. I tried following option

1) 3rd part DLL- ExcelLibrary It works fine if there is no date column in dataset, else it use some dummy value like -65284 instead of date.

ExcelLibrary.DataSetHelper.CreateWorkbook(@"C:\Users\ABC\Documents\Excel\Report123.xls", ds);

2)use simple export format without using 3rd party DLL as follow

public void ExportToExcel(System.Data.DataTable dt)
{
    if (dt.Rows.Count > 0)
    {
        string filename = "Report123.xls";
        System.IO.StringWriter tw = new System.IO.StringWriter();
        System.Web.UI.HtmlTextWriter hw = new System.Web.UI.HtmlTextWriter(tw);
        DataGrid dgGrid = new DataGrid();
        dgGrid.DataSource = dt;
        dgGrid.DataBind();

        //Get the HTML for the control.
        dgGrid.RenderControl(hw);
        //Write the HTML back to the browser.
        //Response.ContentType = application/vnd.ms-excel;
        Response.ContentType = "application/vnd.ms-excel";
        Response.AppendHeader("Content-Disposition", "attachment; filename=" + filename + "");
        this.EnableViewState = false;
        Response.Write(tw.ToString());
        Response.End();
    }
}

In above code extracting Excel perfectly , but when we open same excel it gets error that format is wrong.

also I want to read same file in datatable to store in database. when I go to read created excel (by 2nd option) then I get error that external table is not in expected format. If I save as the same file then it works file.

But I dont want to do every time "save As" file. please help me

Updates:

public void ExportToExcel1(System.Data.DataTable dt)
{
    //clear the response of any junk. This may not be necessary
    Response.Clear();

    //add a header so it has a nice file name
    Response.AddHeader("content-disposition", "attachment;filename=Reportengg.xlsx");

    //Set the MIME type correctly
    Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";

    //create a new package, this is the equivalent of an XLSX file.
    var package = new ExcelPackage();

    //Add a new sheet to the workbook
    var sheet = package.Workbook.Worksheets.Add("Sheet1");

    //EPPlus contains helper function to load data from a DataTable, though you could manually fill in rows/column values yourself if you want
    sheet.Cells["A1"].LoadFromDataTable(dt, true);
  //  byte[] array = package.GetAsByteArray();
    //write the file bytes to the response
    Response.BinaryWrite(package.GetAsByteArray());


    //end the response so we don't send anymore down and corrupt the file
    Response.End();
}
dwan
  • 193
  • 2
  • 3
  • 11
  • The #2 technique is one to avoid. The format is indeed wrong. It's not an Excel file, it's an HTML file being served with an Excel extension and MIME type. You should stick to techniques like #1 that will create actual Excel files. – mason Oct 05 '15 at 13:28

2 Answers2

1

Your #1 technique is saving the file on the server. Server side code can't save directly to the client file system. You must write the file bytes to the response, then the client's PC will choose what to do with it. Whether they choose to "save as" or just save directly to some Downloads folder is up to their browser settings. I'm not familiar with ExcelLibrary but I imagine they have some sort of API to get the file bytes? Do that. Then write those bytes to the response.

byte[] bytes = GetBytesFromTheirApiSomehow();
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.AppendHeader("Content-Disposition", "attachment; filename=filename.xlsx");
Response.BinaryWrite(bytes);
Response.End();

I took a look at the ExcelLibrary source code. That library doesn't appear to be maintained anymore. Perhaps you should move to a library that's actively maintained, such as EPPlus. An EPPlus implementation might look like this:

public void ExportToExcel(System.Data.DataTable dt)
{
    //clear the response of any junk. This may not be necessary
    Response.Clear();

    //add a header so it has a nice file name
    Response.AddHeader("content-disposition", "attachment;filename=myexcelfile.xlsx");

    //Set the MIME type correctly
    Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";

    //create a new package, this is the equivalent of an XLSX file.
    var package = new ExcelPackage();

    //Add a new sheet to the workbook
    var sheet = package.Workbook.Worksheets.Add("My Data"); 

    //EPPlus contains helper function to load data from a DataTable, though you could manually fill in rows/column values yourself if you want
    sheet.Cells["A1"].LoadFromDataTable(dt, true); 

    //write the file bytes to the response
    Response.BinaryWrite(package.GetAsByteArray());

    //end the response so we don't send anymore down and corrupt the file
    Response.End();
}
mason
  • 31,774
  • 10
  • 77
  • 121
  • @mason- still with same error, 1) date format is wrong(store dummy data) 2) when tried to read table get error that "External table is not in the expected format." – dwan Oct 05 '15 at 15:10
  • @dwan Did you switch to EPPlus? Did you make sure and use the `.xlsx` extension like in my example? – mason Oct 05 '15 at 15:22
  • Look at the resulting file. How many bytes is it? If you introduce a local variable when you do `package.GetAsByteArray()` how many bytes is that? – mason Oct 05 '15 at 16:23
  • byte are - byte[10897] – dwan Oct 05 '15 at 16:41
  • @dwan And does the file on the client side have the same size? – mason Oct 05 '15 at 16:43
  • @dwan Just like any other file. Download the file, the right click the file in Windows Explorer and hit properties. Look at the Size on the General tab (assuming your client machine is Windows). – mason Oct 05 '15 at 16:56
  • @mason- client file size- 52,041 in byte – dwan Oct 05 '15 at 17:03
  • @dwan So the sizes aren't matching. Prior to calling the method that writes the file to the response, do you write anything else to the response? – mason Oct 05 '15 at 17:04
  • @mason- sorry for wrong message the client side file size also same 10,897 – dwan Oct 05 '15 at 17:10
  • @dwan Okay, so now inspect the file to see if it's a .XLSX file. Try to open it with notepad. Does it look like HTML? – mason Oct 05 '15 at 17:11
  • not like HTML- its look like "PK ç´EGäH­¯ 3 [Content_Types].xmlµ’ÏJ1Æ_eÉUš´D¤ÛªU°>À˜ÌvCóÌ´¶oo6+"¥‚zš$ßÌ÷ý3_¼kö˜ÉÆÐŠ™œŠƒŽÆ†M+ÞÖ“[ÑC0àbÀV‘Är1_RSfµ¢gNwJ‘îÑɘ0¥‹Ù—kÞ¨zT×ÓéÒ10žðà!ó{ì`ç¸Yïƒu+ %g5pÁRÅL4‡"Ž”Ã]ýanÌ ÌäDftµ‡z›èê4 ¨4$<—ÉÖà¿"b×Y&ê/#’RF0Ô#²w²VéÁ†1ô2?/®êàÔGÌÛ÷·²j"êù·ü*’ªevAâ£C:G1*—Œî!£yå\–ü<ÁφoU—~ñ PKäH­¯ 3 PK ç´EG˜Úë‹® ' _look like somethig wrong – dwan Oct 05 '15 at 17:14
  • @dwan No, that's good! XLSX is a binary file. It's actually a zip file that contains various files describing the content (mostly XML files). It should be pretty unreadable in Notepad, which is why I wanted you to verify it wasn't HTML masquerading as an Excel file. Can you try to open this .xlsx file up with Excel and take a screenshot of the error and provide that screenshot to us? – mason Oct 05 '15 at 17:15
  • It open perfectly in .xlsx format without error but again invalid dateformat and when tried to open same file in code file get error "External table is not in the expected format" – dwan Oct 05 '15 at 17:27
  • @dwan The date thing isn't my main concern right now. That's probably related to the column type in the data table or perhaps EPPlus just doesn't handle date types from DataTable correctly, in which case you can easily customize it. What I don't understand is this "External table is not in the expected format" error. What do you mean "open the same file in code"? What code? Is that error not coming from Excel itself? – mason Oct 05 '15 at 17:57
  • Yes I am trying to pen same file in code then It get error at the time of open file con.open() that External table is not in the expected format.If I "save as" same file then it works perfectly – dwan Oct 06 '15 at 04:00
-1

This worked for me:

        Response.ClearContent();
        Response.Buffer = true;
        Response.AddHeader("content-disposition", string.Format("attachment; filename={0}", "Report123.xls"));
        Response.ContentType = "application/vnd.ms-excel";
        System.IO.StringWriter sw = new System.IO.StringWriter();
        System.Web.UI.HtmlTextWriter hw = new System.Web.UI.HtmlTextWriter(sw);
        GridView1.AllowPaging = false;
        GridView1.RenderControl(hw);
        Response.Write(sw.ToString());
        Response.End();
losopha
  • 127
  • 1
  • 3
  • 10