有必要对MathType的公式转换在2003年MS-WORD或低于成MathML为了很好地呈现在网络上。 在MathType中内置的功能“发布到MathPage”可以做的工作非常漂亮,但我想公式转换过程在我的C#应用程序集成。 因为我无法找到该MathPage出口接口由MathType的SDK提供的API参考,我需要想出一个办法自己做独立式转换。
当前过程是到MS-Word 2003或以下的文件转换成打开XML格式(DOCX)。 在DOCX转换后,我可以看到MathType的嵌入OLE对象的二进制字符串保存在打开XML,这是DOCX。 然后,下一个步骤是从嵌入对象二进制串的MTEF数据进行解码,所以我试图通过参照上的MathType MTEF头中的正式文件以提取MTEF。
所述的base64二进制串 ,表示由创建的MathType嵌入对象,从提取的MS-WORD测试DOCX文件 。
中期支出框架头定义:
MTEF数据被保存为对象的本地数据格式。 每当一个等式对象是要被写入到一个OLE“流”中,28-字节的头被写入,随后MTEF数据。 用于该标题的C结构如下:
struct EQNOLEFILEHDR {
WORD cbHdr; // length of header, sizeof(EQNOLEFILEHDR) = 28 bytes
DWORD version; // hiword = 2, loword = 0
WORD cf; // clipboard format ("MathType EF")
DWORD cbObject; // length of MTEF data following this header in bytes
DWORD reserved1; // not used
DWORD reserved2; // not used
DWORD reserved3; // not used
DWORD reserved4; // not used
};
在CF成员是Windows API函数的RegisterClipboardFormat(“MathType的EF”)的调用的返回值。
然后我试图将其转换为C#版本:
[StructLayout(LayoutKind.Sequential, Pack=1)]
struct EQNOLEFILEHDR
{
public UInt16 cbHdr;
public UInt32 version;
public UInt16 format;
public UInt32 size;
public UInt32 reserved1;
public UInt32 reserved2;
public UInt32 reserved3;
public UInt32 reserved4;
}
与插头结构准备,下面的代码试图填补从嵌入对象二进制串标头结构的信息。
foreach (EmbeddedObjectPart eop in wordDoc.MainDocumentPart.EmbeddedObjectParts)
{
Stream stream = eop.GetStream();
byte[] buffer = new byte[int.Parse(stream.Length.ToString())];
using (BinaryReader reader = new BinaryReader(stream))
{
int res = reader.Read(buffer, 0, int.Parse(stream.Length.ToString()));
}
GCHandle hdl = GCHandle.Alloc(buffer, GCHandleType.Pinned);
IntPtr intp = Marshal.AllocHGlobal(buffer.Length);
Marshal.Copy(buffer, 0, intp, Marshal.SizeOf(typeof(EQNOLEFILEHDR)));
EQNOLEFILEHDR header = (EQNOLEFILEHDR)Marshal.PtrToStructure(intp, typeof(EQNOLEFILEHDR));
Marshal.FreeHGlobal(intp);
}
然而,充满在头结构中的数据是不正确的,让我觉得这是不是从DOCX文件中嵌入的对象二进制字符串解析MTEF数据是正确的做法。
我也看了在MathType的SDK下载的样本.NET代码,并找到了IDataObject用来包含MathType的信息和转换程序。 因此,另一种方法是使用BinaryFormatter
,看它是否可以反序列化二进制串到IDataObject的类型的对象中,通过使用码BinaryFormatter.Deserialize(stream)
。 但它也不行,提示异常Binary stream '0' does not contain a valid BinaryHeader
什么错在我试图用解析中期支出框架数据的方法?