有必要将MS-WORD 2003或更低版本中的MathType方程转换为MathML,以便在网络上很好地呈现。 MathType的内置函数“发布到MathPage”可以很好地完成这项工作,但是我想将方程转换过程集成到C#应用程序中。因为我找不到MathType SDK提供的MathPage导出接口提供的任何API引用,所以我需要自己找出一种进行单个方程式转换的方法。
当前过程是将MS-WORD 2003或更低版本的文档转换为Open XML格式(docx)。 docx转换后,我可以看到MathType嵌入式ole对象二进制字符串保存在打开的xml(即docx)中。然后,下一步是从嵌入式对象二进制字符串中解码MTEF数据,因此我尝试通过参考MathType MTEF标头上的官方文档来提取MTEF。
从base64 binary string中提取表示由MathType创建的嵌入式对象的MS-WORD Test DOCX file。
MTEF标头定义:
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
来查看是否可以通过使用代码BinaryFormatter.Deserialize(stream)
将二进制字符串反序列化为IDataObject类型的对象。但这也不起作用,提示出现异常Binary stream '0' does not contain a valid BinaryHeader
我尝试用来解析MTEF数据的方法有问题吗?
最佳答案
Kata,您应该已经收到我的电子邮件回复,但是对于其他感兴趣的人,我们有一个示例,该示例是从我们的SDK修改而来的,我们很乐意将其发送给需要它的任何人。对于任何使用它的人来说,如果您还没有下载SDK,它可能就没有多大意义。如果您想尝试一下,请告诉我。
鲍勃·马修斯
设计科学
关于c# - 从OLE二进制字符串解析MathType MTEF数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15320088/