C# 在内存中以Excel工作簿形式打开XML字符串,而不使用windows窗体C保存#
我在内存中有一个excel字符串(我构建的);代码如下所示:C# 在内存中以Excel工作簿形式打开XML字符串,而不使用windows窗体C保存#,c#,xml,excel,in-memory,C#,Xml,Excel,In Memory,我在内存中有一个excel字符串(我构建的);代码如下所示: public static void exportToExcel() { const string startExcelXML = "<xml version>\r\n<Workbook " + "xmlns=\"urn:schemas-microsoft-com:office:spreadsheet\"\r\n" +
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);
}
publicstaticvoidexporttoexcel()
{
常量字符串startExcelXML=“\r\n\r\n\r\n”+
“\r\n”+
“\r\n”+
“\r\n\r\n\r\n”+
“\r\n\r\n\r\n”+
“\r\n\r\n\r\n”+
“\r\n\r\n\r\n\r\n\r\n\r\n\r\n”+
“\r\n\r\n\r\n\r\n\r\n\r\n\r\n”+
“\r\n”;
常量字符串endExcelXML=“”;
int sheetCount=1;
StringBuilder sb=新的StringBuilder();
sb.Append(startExcelXML);
某人加上(“”);
某人加上(“”);
某人加上(“”);
某人加上(“”);
某人附加(“母国”);
某人加上(“”);
某人加上(“”);
sb.追加(“外派类型”);
某人加上(“”);
某人加上(“”);
某人加上(“”);
某人附加(“)+
"");
sb.附加(“新加坡”);
某人加上(“”);
某人附加(“)+
"");
sb.附加(“基准”);
某人加上(“”);
某人加上(“”);
某人加上(“”);
某人加上(“”);
sb.Append(endExcelXML);
}
只有在物理保存文件后,我才能以excel工作表的形式打开文件;但是,还有其他方法可以从内存中以excel工作表的形式打开xml字符串吗?我认为您需要的是某种内存映射文件实现 不过,我相信.NET4.0将具有内置的
MemoryMappedFile
支持
您可以使用搜索引擎找到其他.net实现。我不确定,但大多数Microsoft automation对象都支持,这可以让您从内存中的流加载 类似于(伪代码): 您可以使用shell helper函数围绕某些内存创建包装:
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;
将字符串放入内存中,查看是否加载。如何从文件系统打开它?现在,我们将保存到物理磁盘,并使用excel对象打开文件。我们希望避免将文件另存为用户的物理磁盘。作为一名VB用户,我不明白C#为什么会有如此多的背景词。我搜索了MemoryMappedFile,并在.net中获得了一些实现。filemap-2.0.2.zip就是一个这样的工具。我还在检查它,但乍看起来有点复杂。使用应用程序打开一个流真的很复杂吗?是的,它相当复杂。老实说,我不认为这是值得的努力-它不会花很长时间写出来的字符串到文件系统;我就是这么想的。我们没有实施这一点。现在,我们已经更改了要求,并要求用户提供保存文件的位置,然后将其保存到该位置。
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;