2012-05-16 41 views
7

Tôi đang cố gắng xuất C# DataTable sang tệp EXCEL khi đang chạy (mà không cần tạo tệp vật lý) bằng Microsoft Office EXCEL INTEROP và tải xuống asp.net trang web thông qua đối tượng Response. Tôi có thể tạo ra bộ nhớ bằng cách sử dụng thư viện Nhưng bằng cách nào đó các tập tin không nhận được lưu thông qua các dòng bộ nhớ. Mã tham chiếu được đưa ra dưới đây. Bạn sẽ được yêu cầu tham khảo cho DocumentFormat.OpenXml.dll & WindowsBase.DLL (bạn có thể tải xuống từ trang web microsoft).Tải xuống tệp EXCEL từ trang ASP.NET mà không cần tạo tệp vật lý trên máy chủ (On The Fly)

Bất kỳ ý tưởng nào về cách giải quyết sự cố? ? ?

Private void DownloadFile() 
{ 
       DataSet objTable = ReadTableFromViewstate(); 
      if (objTable != null && objTable.Rows.Count > 0) 
      { 

       string strDownloadableFilename = "TestExcelFileName.xls"; 
       MemoryStream fs1 = new MemoryStream(); 
       if (CreateExcelFile.CreateExcelDocument(objTable, fs1)) 
       { 
        Response.Clear(); 
         byte[] data1 = new byte[fs1.Length]; 
         fs1.Read(data1, 0, data1.Length); 
         fs1.Close(); 

        Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; 
        Response.AddHeader("Content-Disposition", string.Format("attachment; filename={0}", strDownloadableFilename)); 
        Response.BinaryWrite(data1); ; 
        Response.End(); 

       } 
       else 
       { 
        LblErrorMessage.Text = "Error Exporting File."; 
       } 
      } 

     } 

..

public static bool CreateExcelDocument(DataSet ds, System.IO.Stream excelFileStream) 
    { 
     try 
     { 
      using (SpreadsheetDocument document = SpreadsheetDocument.Create(excelFileStream, SpreadsheetDocumentType.Workbook)) 
      { 
       CreateParts(ds, document); 
      } 

      Trace.WriteLine("Successfully created: " + excelFileStream); 
      return true; 
     } 
     catch (Exception ex) 
     { 
      Trace.WriteLine("Failed, exception thrown: " + ex.Message); 
      return false; 
     } 
    } 
.. 




private static void CreateParts(DataSet ds, SpreadsheetDocument document) 
     { 
      WorkbookPart workbookPart = document.AddWorkbookPart(); 
      Workbook workbook = new Workbook(); 
      workbookPart.Workbook = workbook; 

      // If we don't add a "WorkbookStylesPart", OLEDB will refuse to connect to this .xlsx file ! 

       WorkbookStylesPart workbookStylesPart = workbookPart.AddNewPart<WorkbookStylesPart>("rIdStyles"); 
      Stylesheet stylesheet = new Stylesheet(); 

      workbookStylesPart.Stylesheet = stylesheet; 

      Sheets sheets = new Sheets(); 

      // Loop through each of the DataTables in our DataSet, and create a new Excel Worksheet for each. 
     uint worksheetNumber = 1; 
     foreach (DataTable dt in ds.Tables) 
     { 
      // For each worksheet you want to create 
      string workSheetID = "rId" + worksheetNumber.ToString(); 
      string worksheetName = dt.TableName; 

      WorksheetPart worksheetPart = workbookPart.AddNewPart<WorksheetPart>(workSheetID); 
      WriteDataTableToExcelWorksheet(dt, worksheetPart); 

      Sheet sheet = new Sheet() { Name = worksheetName, SheetId = (UInt32Value)worksheetNumber, Id = workSheetID }; 
      sheets.Append(sheet); 

      worksheetNumber++; 
     } 

     workbook.Append(sheets); 
    } 
+0

Tại sao không làm điều đó dưới dạng phân tách bằng tab và sau đó chỉ gửi cho người dùng? Nó sẽ mở ra trong Excel. –

+1

Không thực sự là câu trả lời, nhưng tôi có thể khuyên bạn nên [EPPLus] (http://epplus.codeplex.com/releases/view/42439) để tạo các tệp Excel khi đang di chuyển. http://stackoverflow.com/a/10547727/284240 Sau đó, tất cả những gì bạn cần là 'Response.BinaryWrite (pck.GetAsByteArray());' –

+0

@James: Cảm ơn bạn đã gợi ý. Nhưng tôi không muốn đi theo cách đó, nếu không tôi có thể đã được tạo ra tập tin .csv. Tôi muốn sử dụng INTEROP vì trong tương lai, tôi muốn thêm hình ảnh/đồ thị vào bảng excel (mà quá bay). – Sankalp

Trả lời

3

Nhờ All, Cuối cùng I Got giải pháp của vấn đề của tôi. Tôi chỉ thay thế dòng mã sau đây:

    byte[] data1 = new byte[fs1.Length]; 
        fs1.Read(data1, 0, data1.Length); 
        fs1.Close(); 

với dòng này

    byte[] data1 = fs1.ToArray(); 

và vấn đề của tôi đã được giải quyết.

1

Sau khi hoàn thành việc ghi vào luồng bộ nhớ, bạn cần đặt lại con trỏ về nguồn gốc của nó trước khi đọc.

fs1.Seek(0, SeekOrigin.Begin); 
Các vấn đề liên quan