距離上一篇openxml的文章已經過去很久了,這段時間一直忙於openxml來自動生成word。把自動生成word的心得寫出來,這一篇就寫插入word2007數學公式吧。
在寫插入數學公式之前先回顧一下openxml的相關知識,openxml是基於xml和zip協議的文檔描述格式。所以我們可以將word的中一個個組成看成一個個標簽對,自動生成word的內容就是在生成一個個標簽對,然后插入內容,插入到文檔標簽中。使用openxml生成word速度比微軟自帶的接口速度快了十幾倍,不過稍顯不足的是word2003不是openxml格式的。
Paragraph是openxml中的段落標簽,這個標簽是word的基本組成部分,word中除了表格標簽外,其他的內容都是放在Paragraph中的。
OfficeMath即數學公式標簽。
下面是示例代碼,這里先只寫一個簡單的公式,有空我在把常用的公式整理出來
代碼
公式類:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using W = DocumentFormat.OpenXml.Wordprocessing; using M = DocumentFormat.OpenXml.Math; using DocumentFormat.OpenXml; namespace OMath { /// <summary> /// 生成公式的類 /// 這段代碼是使用word2007插入新公式后,使用Open XML SDK 2.0 Productivity Tool反編譯出c#代碼寫出來的 /// </summary> class MathHelper { #region 常用變量 public static string fontName = "微軟雅黑"; //四號字,對應word中的大小是10.5(Ps:這是openxml的一個不好之處就是,單位和word中顯示的不一致) public static string fontSize = "21"; public static string fontSizeComplexScript = "24"; #endregion #region 插入文檔的公式 public static M.OfficeMath GetSubScript(string baseString, string downString) { M.OfficeMath officeMath = new M.OfficeMath(); M.Subscript subScript = GenerateSubscript(baseString, downString); officeMath.Append(subScript); return officeMath; } public static M.OfficeMath GetSubScript(string baseString, string downString, string runText) { M.OfficeMath officeMath = new M.OfficeMath(); M.Subscript subScript = GenerateSubscript(baseString, downString); M.Run run = GenerateMathRun(runText); officeMath.Append(subScript); officeMath.Append(run); return officeMath; } #endregion #region 基礎公式 /// <summary> /// 帶有下標的公式 /// </summary> /// <param name="baseString">基礎字符</param> /// <param name="downString">下標字符</param> /// <returns></returns> public static M.Subscript GenerateSubscript(string baseString, string downString) { M.Subscript subscript1 = new M.Subscript(); M.Base base1 = new M.Base(); M.Run run1 = GenerateMathRun(baseString); base1.Append(run1); M.SubArgument subArgument = new M.SubArgument(); M.Run run = GenerateMathRun(downString); subArgument.Append(run); subscript1.Append(base1); subscript1.Append(subArgument); return subscript1; } /// <summary> /// 帶有下標的公式 /// </summary> /// <param name="baseElement">基礎元素</param> /// <param name="downElement">下標元素</param> /// <returns></returns> public static M.Subscript GenerateSubscript(OpenXmlElement baseElement, OpenXmlElement downElement) { M.Subscript subscript1 = new M.Subscript(); M.Base base1 = new M.Base(); base1.Append(baseElement); M.SubArgument subArgument = new M.SubArgument(); subArgument.Append(downElement); subscript1.Append(base1); subscript1.Append(subArgument); return subscript1; } /// <summary> /// 帶有上標的公式 /// </summary> /// <param name="baseString">基礎字符</param> /// <param name="upString">上標字符</param> /// <returns></returns> public static M.Superscript GenerateSuperscript(string baseString, string upString) { M.Superscript superscript = new M.Superscript(); M.Base base1 = new M.Base(); M.Run run1 = GenerateMathRun(baseString); base1.Append(run1); M.SuperArgument superArgument = new M.SuperArgument(); M.Run run = GenerateMathRun(upString); superArgument.Append(run); superscript.Append(base1); superscript.Append(superArgument); return superscript; } /// <summary> /// 帶有上標的公式 /// </summary> /// <param name="baseElement">基礎元素</param> /// <param name="upElement">上標元素</param> /// <returns></returns> public static M.Superscript GenerateSuperscript(OpenXmlElement baseElement, OpenXmlElement upElement) { M.Superscript superscript = new M.Superscript(); M.Base base1 = new M.Base(); base1.Append(baseElement); M.SubArgument subArgument = new M.SubArgument(); subArgument.Append(upElement); superscript.Append(base1); superscript.Append(subArgument); return superscript; } #endregion #region run,是存放最基礎的文本信息的標簽 private static M.Run GenerateMathRun(string baseString) { M.Run run1 = new M.Run(); W.RunProperties runProperties = new W.RunProperties(); //字體 W.RunFonts runFonts1 = new W.RunFonts() { Ascii = fontName, HighAnsi = fontName, EastAsia = fontName }; //字的大小 W.FontSize fontSize1 = new W.FontSize() { Val = fontSize }; W.FontSizeComplexScript fsc = new W.FontSizeComplexScript { Val = fontSizeComplexScript }; run1.Append(new W.RunProperties(runFonts1, fontSize1, fsc)); run1.Append(new W.Text() { Text = baseString }); return run1; } #endregion } }
word處理類:
using W = DocumentFormat.OpenXml.Wordprocessing; using M = DocumentFormat.OpenXml.Math; using System; using System.Collections.Generic; using System.Linq; using System.Text; using DocumentFormat.OpenXml.Packaging; using System.IO; using DocumentFormat.OpenXml; namespace OMath { public class OpenWord { public WordprocessingDocument wDoc; public MainDocumentPart mainDoc; public W.Body body; public W.Document doc; public static string fontName = "微軟雅黑"; //四號字,對應word中的大小是10.5(Ps:這是openxml的一個不好之處就是,單位和word中顯示的不一致) public static string fontSize = "21"; /// <summary> /// 初始化文檔 /// </summary> /// <param name="fileName">創建文檔的路徑名稱</param> public void Init(string fileName) { if (File.Exists(fileName)) { File.Delete(fileName); } wDoc = WordprocessingDocument.Create(fileName, WordprocessingDocumentType.Document); mainDoc = wDoc.AddMainDocumentPart(); doc = new W.Document(); body = new W.Body(); } public void AddMath(M.OfficeMath oMath) { W.Paragraph paragraph = new W.Paragraph(); //修飾段落的屬性, W.ParagraphProperties paragraphProperties1 = new W.ParagraphProperties(); //修飾段落中一些 W.ParagraphMarkRunProperties paragraphMarkRunProperties = new W.ParagraphMarkRunProperties(); //字體 W.RunFonts runFonts1 = new W.RunFonts() { Ascii = fontName, HighAnsi = fontName, EastAsia = fontName }; //字的大小 W.FontSize fontSize1 = new W.FontSize() { Val = fontSize }; paragraphMarkRunProperties.Append(runFonts1); paragraphMarkRunProperties.Append(fontSize1); //段落格式,這里設置段落居中(ps:在很多很多的word中或者是書籍中,公式一般都是居中滴) W.Justification justification = new W.Justification() { Val = W.JustificationValues.Center }; paragraphProperties1.Append(paragraphMarkRunProperties); paragraphProperties1.Append(justification); paragraph.Append(paragraphProperties1); //添加公式 paragraph.Append(oMath); //將短路添加入文檔 body.Append(paragraph); } public void save() { doc.Body = body; mainDoc.Document = doc; wDoc.Close(); } } }
測試類:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; namespace OMath { class Program { static void Main(string[] args) { string FileName = "D:\\testMath.docx"; #region 創建word文檔 OpenWord ow = new OpenWord(); ow.Init(FileName); ow.AddMath(MathHelper.GetSubScript("X","i")); ow.AddMath(MathHelper.GetSubScript("X", "i","=y+2")); ow.save(); #endregion } } }
效果圖
相應的源碼:http://files.cnblogs.com/weu135/OMath%E7%A4%BA%E4%BE%8B%E7%89%88.rar