2010-01-27 69 views
2

我在內存中有一個excel字符串(我構建);代碼看起來是這樣的:在內存中作爲Excel工作簿在內存中打開而不保存使用Windows窗體C#

public static void exportToExcel() 
     { 
      const string startExcelXML = "<xml version>\r\n<Workbook " + 
        "xmlns=\"urn:schemas-microsoft-com:office:spreadsheet\"\r\n" 
+ 
        " xmlns:o=\"urn:schemas-microsoft-com:office:office\"\r\n " + 
        "xmlns:x=\"urn:schemas- microsoft-com:office:" + 
        "excel\"\r\n xmlns:ss=\"urn:schemas-microsoft-com:" 
+ 
        "office:spreadsheet\">\r\n <Styles>\r\n " + 
        "<Style ss:ID=\"Default\" ss:Name=\"Normal\">\r\n " + 
        "<Alignment ss:Vertical=\"Bottom\"/>\r\n <Borders/>" + 
        "\r\n <Font/>\r\n <Interior/>\r\n <NumberFormat/>" + 
        "\r\n <Protection/>\r\n </Style>\r\n " + 
        "<Style ss:ID=\"BoldColumn\">\r\n <Font " + 
        "x:Family=\"Swiss\" ss:Bold=\"1\"/>\r\n </Style>\r\n " + 
        "<Style  ss:ID=\"StringLiteral\">\r\n <NumberFormat" + 
        " ss:Format=\"@\"/>\r\n </Style>\r\n <Style " + 
        "ss:ID=\"Decimal\">\r\n <NumberFormat/>\r\n </Style>\r\n " + 
        "<Style ss:ID=\"Integer\">\r\n <NumberFormat " 
+ 
        "ss:Format=\"0\"/>\r\n </Style>\r\n <Style " + 
        "ss:ID=\"DateLiteral\">\r\n <NumberFormat " + 
        "ss:Format=\"dd/mm/yyyy;@\"/>\r\n </Style>\r\n " + 
        "</Styles>\r\n "; 
      const string endExcelXML = "</Workbook>"; 

      int sheetCount = 1; 
      StringBuilder sb = new StringBuilder(); 

      sb.Append(startExcelXML); 
      sb.Append("<Worksheet ss:Name=\"Sheet" + sheetCount + "\">"); 
      sb.Append("<Table>"); 
      sb.Append("<Row>"); 
      sb.Append("<Cell ss:StyleID=\"BoldColumn\"><Data ss:Type=\"String\">"); 
      sb.Append("Home country"); 
      sb.Append("</Data></Cell>"); 
      sb.Append("<Cell ss:StyleID=\"BoldColumn\"><Data ss:Type=\"String\">"); 
      sb.Append("Expatriation Type"); 
      sb.Append("</Data></Cell>"); 
      sb.Append("</Row>"); 
      sb.Append("<Row>"); 
    sb.Append("<Cell ss:StyleID=\"StringLiteral\">" + 
     "<Data ss:Type=\"String\">"); 
    sb.Append("Singapore"); 
    sb.Append("</Data></Cell>"); 
    sb.Append("<Cell ss:StyleID=\"StringLiteral\">" + 
     "<Data ss:Type=\"String\">"); 
    sb.Append("Benchmark"); 
    sb.Append("</Data></Cell>"); 
      sb.Append("</Row>"); 
      sb.Append("</Table>"); 
      sb.Append(" </Worksheet>"); 
      sb.Append(endExcelXML); 
     } 

我能夠打開該文件,因爲只有當我保存物理文件excel表;但有沒有其他的方式來打開內存中的XML字符串作爲Excel表?

+0

你如何從文件系統打開它? – 2010-01-27 05:43:29

+0

截至目前,我們保存到物理磁盤並使用Excel對象打開文件。我們希望避免將文件另存爲用戶的物理磁盤。 – 2010-01-28 09:07:37

+0

作爲一個VB用戶,我無法理解C#是如何使用backwords,只要它涉及[XML文字](http://msdn.microsoft.com/en-us/library/bb384629.aspx「XML文字概述(Visual Basic)「)。 – Shimmy 2010-12-23 04:39:28

回答

1

我認爲你需要的是某種內存映射文件的實現。

但我相信,.NET 4.0將內置MemoryMappedFile支持。

您可以使用搜索引擎找到其他.net實現。

+0

我搜索了MemoryMappedFile並在.net中獲得了一些實現。一個這樣的推理是filemap-2.0.2.zip。我仍在檢查它,但首先看起來它看起來有點複雜。使用應用程序打開一個流真的很複雜嗎? – 2010-01-28 09:13:50

+0

是的,它非常複雜。老實說,我不認爲這是值得的努力 - 將該字符串寫入文件系統並不需要很長時間。 – Jay 2010-01-28 09:34:35

+0

是的;我也這麼想。我們沒有實現這一點。現在我們改變了我們的要求,並要求用戶保存文件的位置,然後將其保存到該位置。 – 2010-01-28 10:30:56

0

我並不確定,但大多數Microsoft自動化對象支持IPersist or IPersistStream,這可能允許您從內存中的流加載。

類似的信息(僞代碼):

xl = new Office.ExcelApplication; 
(xl as IPersistStream).Load(myMemoryStream); 

您可以使用shell輔助函數CreateStreamOnHGlobal創建一個圍繞一些內存的IStream包裝:

functionCreateStreamOnMemory(pData: Pointer; nCount: DWORD): IStream; 
var 
    hMem: HGLOBAL; 
    dwError: DWORD; 
    p: Pointer; 
begin 
    hMem := GlobalAlloc(GMEM_MOVEABLE or GMEM_NODISCARD, nCount); 
     //CreateStreamOnHGlobal says "The handle must be 
     //allocated as movable and nondiscardable." 
    if hMem = 0 then 
     RaiseLastWin32Error; 

    p := GlobalLock(hMem); 
    if p = nil then 
    begin 
     dwError := GetLastError; 
     GlobalFree(hMem); 
     raise EWin32Error.Create('Could not lock global memory object: '+SysErrorMessage(dwError)); 
    end; 
    try 
     CopyMemory(p, pData, nCount); 
    finally 
     GlobalUnlock(hMem); 
    end; 

    OleCheck(CreateStreamOnHGlobal(hMem, True, Result)); //Because we pass True, the stream will take care of freeing the HGLOBAL when the stream is released 
end; 

的東西你在存儲串和看看它是否加載。

相關問題