2010-01-27 26 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; 

的东西你在存储串和看看它是否加载。

相关问题