我有一个RTF文件,内容如下:
{\object\objemb{\*\objclass Excel.Sheet.12}\objw8415\objh3015{\*\objdata
01050000
02000000
0f000000...}}}
(可能是Excel或Word)
我需要的是将\objdata
部分提取到外部文件中以便能够编辑它。之后,该文件将被转换回RTF文件中的嵌入对象。
我已经四处寻找,似乎这不是一个小问题。从this post进行了一些小修改,我尝试访问objdata
并将其保存到文件中,但这不会导致有效的Excel文件:
if (RtfReader.MoveToNextControlWord(enumerator, "objdata"))
{
byte[] data = RtfReader.GetNextTextAsByteArray(enumerator);
using (MemoryStream packageData = new MemoryStream())
{
RtfReader.ExtractObjectData(new MemoryStream(data), packageData);
File.WriteAllBytes(@"c:\temp\some-excel.xls", ReadToEnd(packageData));
}
}
有没有任何想法如何实现上述目标?
非常感谢您提供任何帮助!
答案 0 :(得分:1)
在这种情况下,objdata的内容是复合文件。你可以发现着名的'd0cf11e0'标题(看起来像“docfile”)。更多相关信息:Developing a tool to recognise MS Office file types ( .doc, .xls, .mdb, .ppt )。
我写了一个可以用来提取数据的小例子。您可以像这样使用它:
string ole = "2090_Object_Text_0.ole"; // your file
string text = File.ReadAllText(ole);
DocFile.Save(text, "mydoc.doc"); // you should adapt this depending on the object class (Word.Document.8 is a .doc).
DocFile帮助程序代码:
public static class DocFile
{
// magic Doc File header
// check this for more: http://social.msdn.microsoft.com/Forums/en-US/343d09e3-5fdf-4b4a-9fa6-8ccb37a35930/developing-a-tool-to-recognise-ms-office-file-types-doc-xls-mdb-ppt-
private const string Header = "d0cf11e0";
public static void Save(string text, string filePath)
{
if (text == null)
throw new ArgumentNullException("text");
if (filePath == null)
throw new ArgumentNullException("filePath");
int start = text.IndexOf(Header);
if (start < 0)
throw new ArgumentException(null, "Text does not contain a doc file.");
int end = text.IndexOf('}', start);
if (end < 0)
{
end = text.Length;
}
using (MemoryStream bytes = new MemoryStream())
{
bool highByte = true;
byte b = 0;
for (int i = start; i < end; i++)
{
char c = text[i];
if (char.IsWhiteSpace(c))
continue;
if (highByte)
{
b = (byte)(16 * GetHexValue(c));
}
else
{
b |= GetHexValue(c);
bytes.WriteByte(b);
}
highByte = !highByte;
}
File.WriteAllBytes(filePath, bytes.ToArray());
}
}
private static byte GetHexValue(char c)
{
if (c >= '0' && c <= '9')
return (byte)(c - '0');
if (c >= 'a' && c <= 'f')
return (byte)(10 + (c - 'a'));
if (c >= 'A' && c <= 'F')
return (byte)(10 + (c - 'A'));
throw new ArgumentException(null, "c");
}
}