2014-02-12 267 views
4

嗨,我使用EPPlus创建xslx文件与一些数据转储。它可以在本地机器上以及在少量数据的Web服务器上完美工作。大数据损坏的Excel文件

但我有一个案例,我在数据集中有40,000行。它在本地机器上再次正常工作。

但在服务器上它正在创建文件,当我试图打开该文件时,它显示错误,该文件已损坏。我尝试用记事本编辑文件,并注意到它有HTML内容

我使用此代码:

public static void CreateExcel(string file_Name, DataSet ds) 
{ 
    // rowsPerSheet = 50000; 
    string msg = ""; 
    string Type = ""; 
    using (ExcelPackage pck = new ExcelPackage()) { 
     //Create the worksheet 
     ExcelWorksheet ws = default(ExcelWorksheet); 
     int clCnt = 1; 



     foreach (DataTable tbl in ds.Tables) { 
      ws = pck.Workbook.Worksheets.Add(tbl.TableName); 

      //Load the datatable into the sheet, starting from cell A1. Print the column names on row 1 
      ws.Cells("A1").LoadFromDataTable(tbl, true); 

      if (tbl.Rows.Count != 0) { 
       clCnt = 1; 
       foreach (DataColumn col in tbl.Columns) { 
        ws.Column(clCnt).AutoFit(); 
        // format all dates in german format (adjust accordingly) 
        if (col.DataType.Equals(typeof(System.DateTime))) { 
         dynamic colNumber = col.Ordinal + 1; 
         ExcelRange range = ws.Cells(2, colNumber, tbl.Rows.Count + 1, colNumber); 
         range.Style.Numberformat.Format = "MM/dd/yyyy"; 
        } 
        if (col.DataType.Equals(typeof(System.Decimal)) || col.DataType.Equals(typeof(System.Double))) { 
         dynamic colNumber = col.Ordinal + 1; 
         ExcelRange range = ws.Cells(2, colNumber, tbl.Rows.Count + 1, colNumber); 
         range.Style.Numberformat.Format = "0.00"; 
        } 
        clCnt += 1; 
       } 
      } 
     } 

     file_Name = file_Name.Replace(" ", "_") + ".xlsx"; 


     HttpContext.Current.Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; 
     HttpContext.Current.Response.AddHeader("content-disposition", "attachment; filename=" + file_Name + ""); 

     HttpContext.Current.Response.BinaryWrite(pck.GetAsByteArray()); 
     HttpContext.Current.Response.End(); 
    } 


} 

父函数:

private void GenerateReport() 
{ 
    string msg = ""; 
    string output = "where"; 
    int count = 0; 
    string jsscript = ""; 
    string _FID = ""; 
    if ((ddlPortfolio.SelectedValue <= 0 & grvforecast.Rows.Count <= 0)) { 
     jsscript = "<script>alert('Please select potfolio')</script>"; 
     this.Page.ClientScript.RegisterStartupScript(Page.GetType, "jsclose", jsscript); 
    } else if ((grvforecast.Rows.Count <= 0)) { 
     jsscript = "<script>alert('Please add some entry in grid')</script>"; 
     this.Page.ClientScript.RegisterStartupScript(Page.GetType, "jsclose", jsscript); 
    } else { 
     if (btnValue.Value == "Cash/GAAP Report") { 
      _SqlStr = "[USP_CashGaapReport] '"; 
      foreach (GridViewRow row in grvforecast.Rows) { 
       if ((count < grvforecast.Rows.Count - 1)) { 
        _SqlStr += "" + grvforecast.Rows(count).Cells(1).Text + ","; 
       } else { 
        _SqlStr += "" + grvforecast.Rows(count).Cells(1).Text + ""; 
       } 
       count = count + 1; 
      } 
      _SqlStr += "'"; 

     } else { 
      if ((btnValue.Value == "Forecast Attribute Report")) { 
       _SqlStr = "SELECT f.AttributeSetID as AttributeSetID , Attribute_Set.TabName as AttributeSetName FROM Forecast_Account as f INNER JOIN Attribute_Set ON f.AttributeSetID = Attribute_Set.AttributeSetID where "; 
      } else if ((btnValue.Value == "Forecast Data Report")) { 
       _SqlStr = "SELECT p.LegalEntityName AS Portfolio, f.Name, c.AccountName, a.RepeatNumber, d.CashGAAP, d.TheDate, SUM(d.Amount) AS Amount, d.LastUpdated, d.UpdatedBy "; 
       _SqlStr += "FROM dbo.Portfolio AS p INNER JOIN dbo.Forecast AS f ON p.PortfolioID = f.PortfolioID INNER JOIN dbo.Forecast_Account AS a ON f.ForecastID = a.ForecastID "; 
       _SqlStr += "INNER JOIN dbo.Forecast_Data AS d ON a.ForecastAccountID = d.ForecastAccountID INNER JOIN dbo.CoA AS c ON c.AccountNumber = a.AccountNumber where "; 
      } else { 
       // _SqlStr = "SELECT Portfolio, Name, AccountName, CashGAAP, OriginalDate, sum(Amount) as Amount, AccountNumber, AttributeSetName, TheDate, Year" 
       // _SqlStr &= " FROM (SELECT Portfolio.LegalEntityName AS Portfolio, f.Name, CoA.AccountName, Forecast_Data.CashGAAP, CONVERT(date, Forecast_Data.TheDate) AS OriginalDate," 
       // _SqlStr &= " SUM(Forecast_Data.Amount) AS Amount, CoA.AccountNumber, Attribute_Set.AttributeSetName, '' + CONVERT(varchar, YEAR(Forecast_Data.TheDate))" 
       // _SqlStr &= " + '-' + CONVERT(varchar, MONTH(Forecast_Data.TheDate)) + '-01' AS TheDate, YEAR(Forecast_Data.TheDate) AS Year, Forecast_Attribute.Value" 
       // _SqlStr &= " FROM Portfolio INNER JOIN Forecast AS f ON Portfolio.PortfolioID = f.PortfolioID INNER JOIN Forecast_Account ON f.ForecastID = Forecast_Account.ForecastID INNER JOIN Forecast_Data ON" 
       // _SqlStr &= " Forecast_Account.ForecastAccountID = Forecast_Data.ForecastAccountID INNER JOIN CoA ON CoA.AccountNumber = Forecast_Account.AccountNumber" 
       // _SqlStr &= " INNER JOIN Attribute_Set ON CoA.AttributeSetID = Attribute_Set.AttributeSetID INNER JOIN Forecast_Attribute ON Forecast_Account.ForecastAccountID = Forecast_Attribute.ForecastAccountID WHERE" 
       _SqlStr = "SELECT Portfolio, Name, AccountName, CashGAAP, OriginalDate, sum(Amount) as Amount, d.AccountNumber as AccountNumber, AttributeSetName, TheDate, Year"; 
       _SqlStr += " FROM (SELECT Portfolio.LegalEntityName AS Portfolio, f.Name, CoA.AccountName, Forecast_Data.CashGAAP, CONVERT(date, Forecast_Data.TheDate) AS OriginalDate,"; 
       _SqlStr += " SUM(Forecast_Data.Amount) AS Amount, CoA.AccountNumber, Attribute_Set.AttributeSetName, '' + CONVERT(varchar, YEAR(Forecast_Data.TheDate))"; 
       _SqlStr += " + '-' + CONVERT(varchar, MONTH(Forecast_Data.TheDate)) + '-01' AS TheDate, YEAR(Forecast_Data.TheDate) AS Year, Forecast_Attribute.Value"; 
       _SqlStr += " FROM Portfolio INNER JOIN Forecast AS f ON Portfolio.PortfolioID = f.PortfolioID INNER JOIN Forecast_Account ON f.ForecastID = Forecast_Account.ForecastID INNER JOIN Forecast_Data ON"; 
       _SqlStr += " Forecast_Account.ForecastAccountID = Forecast_Data.ForecastAccountID INNER JOIN CoA ON CoA.AccountNumber = Forecast_Account.AccountNumber"; 
       _SqlStr += " INNER JOIN Attribute_Set ON CoA.AttributeSetID = Attribute_Set.AttributeSetID INNER JOIN Forecast_Attribute ON Forecast_Account.ForecastAccountID = Forecast_Attribute.ForecastAccountID WHERE"; 
      } 
      foreach (GridViewRow row in grvforecast.Rows) { 
       if ((count < grvforecast.Rows.Count - 1)) { 
        _SqlStr += " f.ForecastID=" + grvforecast.Rows(count).Cells(1).Text + " or"; 
        _FID += " a.ForecastID=" + grvforecast.Rows(count).Cells(1).Text + " or"; 
       } else { 
        _SqlStr += " f.ForecastID=" + grvforecast.Rows(count).Cells(1).Text + " "; 
        _FID += " a.ForecastID=" + grvforecast.Rows(count).Cells(1).Text + " "; 
       } 
       count = count + 1; 
      } 
      if ((btnValue.Value == "Forecast Data Report")) { 
       _SqlStr += "GROUP BY p.LegalEntityName, f.Name, c.AccountName, a.RepeatNumber, d.CashGAAP, d.TheDate, d.LastUpdated, d.UpdatedBy"; 
      } else if ((btnValue.Value == "Cash/GAAP Report")) { 
       _SqlStr += " GROUP BY Portfolio.LegalEntityName, f.Name, CoA.AccountName, Forecast_Data.CashGAAP, Forecast_Data.TheDate, CoA.AccountNumber, Attribute_Set.AttributeSetName, Forecast_Attribute.Value) AS d LEFT OUTER JOIN Vendor ON d.Value = Vendor.VendorName"; 
       _SqlStr += " GROUP BY d.OriginalDate, d.TheDate, d.AccountNumber, d.Portfolio, d.Name, d.AccountName, d.CashGAAP, d.AttributeSetName, d.Year, Vendor.VendorName"; 
       // _SqlStr &= " GROUP BY Portfolio.LegalEntityName, f.Name, CoA.AccountName, Forecast_Data.CashGAAP, Forecast_Data.TheDate, CoA.AccountNumber, Attribute_Set.AttributeSetName, Forecast_Attribute.Value) AS d" 
       // _SqlStr &= " Group BY OriginalDate,TheDate,AccountNumber,Portfolio,Name,AccountName,CashGAAP,AttributeSetName,Year" 
      } 
     } 
     try { 
      if ((btnValue.Value != "Forecast Attribute Report")) { 
       _ds = new DataSet(); 
       _dtTable = myDB.ExecuteDatatable(CommandType.Text, _SqlStr, null); 
       _dtTable.TableName = btnValue.Value.Replace("_", " "); 
       _ds.Tables.Add(_dtTable); 
      } else { 
       _ds = new DataSet(); 
       _SqlStr += "Group by f.AttributeSetID,Attribute_Set.TabName "; 
       _dtTable = myDB.ExecuteDatatable(CommandType.Text, _SqlStr, null); 
       foreach (DataRow _dr in _dtTable.Rows) { 
        _SqlStr = "[USP_Forecast_Attributes] " + _dr["AttributeSetID"].ToString() + ",'" + _FID + "'"; 
        _dtTable = myDB.ExecuteDatatable(CommandType.Text, _SqlStr, null); 
        _dtTable.TableName = _dr["AttributeSetName"].ToString(); 
        _ds.Tables.Add(_dtTable); 
       } 
      } 
      if ((_ds != null)) { 
       if (DateAndTime.Now.IsDaylightSavingTime()) { 
        strTime = System.DateTime.UtcNow.AddHours(-5).ToString("_MM_dd_yyyy_hh_mm_tt"); 
       } else { 
        strTime = System.DateTime.UtcNow.AddHours(-4).ToString("_MM_dd_yyyy_hh_mm_tt"); 
       } 
       if (btnValue.Value != "Forecast Attribute Report") { 
        epXL.CreateExcel(btnValue.Value, _ds); 
       //epXL.ExportToExcel(_dtTable, btnValue.Value) 
       } else { 
        epXL.CreateExcel(btnValue.Value, _ds); 
        // & strTime, _ds) 
       } 
      } 
     } catch (Exception ex) { 
      jsscript = "<script>alert('Report not generated')</script>"; 
      this.Page.ClientScript.RegisterStartupScript(Page.GetType, "jsclose", jsscript); 
     } 
    } 
} 

编辑: 现在,我得到确切的错误:

System.IO.IsolatedStorage.IsolatedStorageException: Unable to create mutex. (Exception from HRESULT: 0x80131464) 
    at System.IO.IsolatedStorage.IsolatedStorageFile.Open(String infoFile, String syncName) 
    at System.IO.IsolatedStorage.IsolatedStorageFile.Lock(Boolean& locked) 
    at System.IO.IsolatedStorage.IsolatedStorageFileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, IsolatedStorageFile isf) 
    at MS.Internal.IO.Packaging.PackagingUtilities.SafeIsolatedStorageFileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, ReliableIsolatedStorageFileFolder folder) 
    at MS.Internal.IO.Packaging.PackagingUtilities.CreateUserScopedIsolatedStorageFileStreamWithRandomName(Int32 retryCount, String& fileName) 
    at MS.Internal.IO.Packaging.SparseMemoryStream.SwitchModeIfNecessary() 
    at MS.Internal.IO.Packaging.SparseMemoryStream.Write(Byte[] buffer, Int32 offset, Int32 count) 
    at MS.Internal.IO.Packaging.CompressEmulationStream.Write(Byte[] buffer, Int32 offset, Int32 count) 
    at MS.Internal.IO.Packaging.CompressStream.Write(Byte[] buffer, Int32 offset, Int32 count) 
    at MS.Internal.IO.Zip.ProgressiveCrcCalculatingStream.Write(Byte[] buffer, Int32 offset, Int32 count) 
    at MS.Internal.IO.Zip.ZipIOModeEnforcingStream.Write(Byte[] buffer, Int32 offset, Int32 count) 
    at System.IO.StreamWriter.Flush(Boolean flushStream, Boolean flushEncoder) 
    at System.IO.StreamWriter.Write(String value) 
    at System.IO.TextWriter.Write(String format, Object arg0) 
    at OfficeOpenXml.ExcelWorksheet.UpdateRowCellData(StreamWriter sw) 
    at OfficeOpenXml.ExcelWorksheet.SaveXml() 
    at OfficeOpenXml.ExcelWorksheet.Save() 
    at OfficeOpenXml.ExcelWorkbook.Save() 
    at OfficeOpenXml.ExcelPackage.GetAsByteArray(Boolean save) 
    at OfficeOpenXml.ExcelPackage.GetAsByteArray() 

我不能解决它。请建议。 谢谢

+0

当你说'它有html内容'时:它说什么? –

+0

它是整个aspx页面的内容。我有这个功能的页面。 –

回答

0

现在我得到了你的问题。 我认为这是由于在服务器上写入权限问题。 通常,ASP.net用户不具有应用程序文件夹外部的写入权限。 这里有两个链接可能会帮助你。

  1. Unable to create mutex. (Exception from HRESULT: 0x80131464)
  2. IsolatedStorageException: Unable to create the store directory

希望这有助于你。

+0

它是一个godaddy服务器。我如何检查内存? –

+0

现在我得到了你的问题。 我认为这是由于在服务器上写入权限问题。 通常,ASP.net用户不具有应用程序文件夹外部的写入权限。这里有两个链接可能会帮助你。 1. [link](https://epplus.codeplex.com/workitem/14877) 2. [link](http://stackoverflow.com/questions/1035576/isolatedstorageexception-unable-to-create-the-存储目录) – Sumedh

+0

它与RAM无关。如果内部SparseMemoryStream类超过1MB,它将尝试将任何内容加载到独立存储中。MS Packaging API使用这个类来打开包内的流。 - 当文件太大时,使用CSharpZipLib/SAX解析等其他库可能会更好。 – BrainSlugs83

1

我认为你的页面有一个设计问题。至少,快速解决方案是在您将文档写入Response之前添加此内容。

HttpContext.Current.Response.Clear(); 

当你在输出的响应,这意味着它试图呈现一个页面,并在其中,你尝试做别的事情,在这种情况下写文件。 (以How can I return a pdf from a web request in ASP.NET?为例)。

我们必须看到更多的代码才能完全检查这一点,但我想你不会使用HttpHandler这个我会推荐的。

public class DownloadFileHandler : IHttpHandler 
{ 
    public bool IsReusable 
    { 
     get { return true; } 
    } 

    public void ProcessRequest(HttpContext context) 
    { 
     Response.BinaryWrite(...); 
    } 
} 
+0

但它在本地机器上工作。并在服务器上为其他小文件工作。 –

+0

你能展示更多的背景吗?如何调用该方法? –

+0

其简单。我从数据库中获取数据到一个数据集中,并将这些数据传递给这个函数。 –