C#操作word:将rtf中的ole对象通过MathType转换成MathML

来源:互联网 发布:自动生成声音软件 编辑:程序博客网 时间:2024/06/05 07:57

最近有一个需求,有一个老的数据库,里面存了2000多道高数题目,同时还有题目的答案、解题过程、用到的知识点,他们都是以trf文本的方式保存。例如:

{\rtf1\adeflang1025\ansi\ansicpg936\uc2\adeff31507\deff0\stshfdbch31505\stshfloch31506\stshfhich31506\stshfbi0\deflang1033\deflangfe2052\themelang1033\themelangfe2052\themelangcs0{\fonttbl{\f0\fbidi \froman\fcharset0\fprq2{\*\panose 02020603050405020304}Times New Roman;}{\f13\fbidi \fnil\fcharset134\fprq2{\*\panose 02010600030101010101}\'cb\'ce\'cc\'e5{\*\falt SimSun};}{\f34\fbidi \froman\fcharset0\fprq2{\*\panose 02040503050406030204}Cambria Math;}{\f37\fbidi \fswiss\fcharset0\fprq2{\*\panose 020f0502020204030204}Calibri;}{\f38\fbidi \fswiss\fcharset0\fprq0{\*\panose 00000000000000000000}MS Sans Serif{\*\falt Arial};}{\f39\fbidi \fnil\fcharset134\fprq2{\*\panose 0201060003010101010...

然后保存成rtf后,用word打开就是一个个和数学相关的内容:

这一整个内容都是一个ole对象,嵌入到一个rtf中
处理过数学题目的朋友们都知道,数学公式的显示、保存、输入等是一个比较麻烦的问题,在这个数据库中保存的所有的内容都是一长串的rtf文本,文本保存的是数学公式和题目描述,需要将他们转成MathML,以方便在网页上显示。
在MathML提供的SDK中,有ConvertEquation这个类,这个类的作用就是格式的转换,如下是MathType所提供的输入的格式和输出的格式:
这里写图片描述
通过描述能够看出,除了在Word嵌入的对象(Embedded Object),不能将word作为文件直接传入,其他的格式都能直接输入文件,然后输出.text文本。因为数据库中的数据量太大,所以想到通过程序,将word中ole对象复制到剪贴板,然后再调用MathType提供的接口,实现。
具体操作如下:
首先初始化一些用到的对象

        static word.ApplicationClass wordapp = null;        static word.Document doc = null;        static word.Selection selection = null;        static object omissing = System.Reflection.Missing.Value;

打开文档:

 //打开文档        public static void OpenDocFile(string docName)        {            wordapp = new word.ApplicationClass();            wordapp.Visible = false;            object docObject = docName;            doc = wordapp.Documents.Add(ref docObject, ref omissing, ref omissing, ref omissing);            doc.Activate();            int ParagraphCount = doc.Content.Paragraphs.Count;            Console.WriteLine(ParagraphCount);        }

(建议讲wordapp.Visible设为false,表示打开文档但是不显示出来,这么做会提高些速度,不会造成卡顿)
然后分析word文件,结构非常简单,只有ole对象,对象前面有一连串的空格,所以思路就是首先将光标定义到文档最开始,然后一个字符一个字符的朝下走,当走到不是字符的时候停止,那么下一个字符就是所需要的ole对象,然后执行复制就好。

执行复制的操作在 selection.MoveRight(ref unit, ref count, ref extend);处,需要注意最后一个传入的参数是word.WdMovementType.wdExtend。关于这个参数可以使用Word里面非常强大的录制宏,查看宏作为向导(此处录制宏非常简单,就是移动到ole对象然后执行复制),VBA 宏如下:

Sub 宏()'' 宏 宏''    Selection.MoveRight Unit:=wdCharacter, Count:=6    Selection.MoveRight Unit:=wdCharacter, Count:=1, Extend:=wdExtend    Selection.CopyEnd Sub

可以看见执行复制操作是先设置wdExtend,然后执行Selection.Copy(),复制到剪贴板。
所以代码如下:
向下一个字符复制并且移动:

 //向右移动count个单位并进行复制        public static void CopyAndMove(object count)         {            object dummy = System.Reflection.Missing.Value;            object value = 1;            object unit = word.WdUnits.wdCharacter;            object extend = word.WdMovementType.wdExtend;            selection.MoveRight(ref unit, ref count, ref extend);            selection.Copy();            selection.MoveRight(ref unit, ref value, ref dummy);        }

其中selection.MoveRight(ref unit, ref value, ref dummy);是为了将光标移动向下一个单位。
当下一个字符不是空格时,停止:

 public static void CopyOleObject()         {            do            {                CopyAndMove(1);            } while (Paste().Equals(" "));        }

然后进行复制就可以将OLE对象添加到剪贴板,但是在使用剪贴板时出现一个问题,无法使用Clipboard对象,查阅发现,将main方法设置为单线程模式就可以。
[STAThread]
static void Main(string[] args)
{
OpenDocFile("F:\\doc\\l.rtf");
Console.WriteLine(getCurrentPos());
CopyOleObject();
Console.WriteLine(getCurrentPos());
Console.WriteLine("数据是:"+Paste() + "结束");
Console.ReadLine();
}

至此完成操作,然后将MathType的接口嵌入就可以。
示例:
这里写图片描述

<!-- MathType@Translator@5@5@MathML2 (m namespace).tdl@MathML 2.0 (m namespace)@ --><m:math> <m:semantics>  <m:mrow>   <m:mi>y</m:mi><m:mo>=</m:mo><m:mfrac>    <m:mrow>     <m:msup>      <m:mi>a</m:mi>      <m:mi>x</m:mi>     </m:msup>     <m:mo>+</m:mo><m:msup>      <m:mi>a</m:mi>      <m:mrow>       <m:mo>&#x2212;</m:mo><m:mi>x</m:mi></m:mrow>     </m:msup>     </m:mrow>    <m:mn>2</m:mn>   </m:mfrac>   </m:mrow>  <m:annotation encoding='MathType-MTEF'>MathType@MTEF@5@5@+=  feaagKart1ev2aqatCvAUfeBSjuyZL2yd9gzLbvyNv2CaerbuLwBLn  .....
1 0
原创粉丝点击