2014-02-12 265 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

其簡單。我從數據庫中獲取數據到一個數據集中,並將這些數據傳遞給這個函數。 –