将嵌入的 OLE 从 RTF 转换为外部文件(并返回)

本文关键字:文件 外部 返回 转换 OLE RTF | 更新日期: 2023-09-27 18:32:00

>我有一个RTF文件,内容如下:

{'object'objemb{'*'objclass Excel.Sheet.12}'objw8415'objh3015{'*'objdata 
01050000
02000000
0f000000...}}}

(可能是Excel或Word)

我需要的是将'objdata部分提取到外部文件中以便能够对其进行编辑。之后,该文件应转换回RTF文件中的嵌入对象。

我已经四处搜索了一下,似乎这不是一个微不足道的问题。从这篇文章中,经过一个小的修改,我试图访问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));
    }
}

有什么想法可以实现上述目标吗?

提前非常感谢任何帮助!

将嵌入的 OLE 从 RTF 转换为外部文件(并返回)

在这种情况下,objdata 的内容是一个复合文件。您可以发现著名的"d0cf11e0"标头(看起来像"docfile")。更多关于这一点: 开发一个工具来识别MS Office文件类型(.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).

和文档文件帮助程序代码:

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");
    }
}