我使用 MathML 创建一些数据块,我需要通过 OpenXML SDK 将其插入到 docx 文件中。我听说这是可能的,但我没有做到。有人可以帮我解决这个问题吗?
1 回答
据我所知,OpenXml SDK 不支持开箱即用的演示 MathML。
相反,OpenXml SDK 支持 Office MathML。因此,要将演示文稿 MathML 插入 Word 文档,我们首先必须将演示文稿 MathML 转换为 Office MathML。
幸运的是,Microsoft 提供了一个 XSL 文件(称为MML2OMML.xsl)来将演示文稿 MathML 转换为 Office MathML。文件 MML2OMML.xsl 位于%ProgramFiles%\Microsoft Office\Office12
. 结合 .Net Framework 类
XslCompiledTransform
,我们能够将演示文稿 MathML 转换为 Office MathML。
下一步是OfficeMath
从转换后的 MathML 创建一个对象。该类OfficeMath
表示包含 WordprocessingML 的运行,该运行应像 Office Open XML Math 一样进行处理。有关详细信息,请参阅MSDN。
表示 MathML 不包含字体信息。为了得到一个好的结果,我们必须将字体信息添加到创建的OfficeMath
对象中。
在最后一步中,我们必须将OfficeMath
对象添加到我们的 Word 文档中。Paragraph
在下面的示例中,我只是在名为template.docx的 word 文档中搜索第一个并将OfficeMath
对象添加到找到的段落中。
XslCompiledTransform xslTransform = new XslCompiledTransform();
// The MML2OMML.xsl file is located under
// %ProgramFiles%\Microsoft Office\Office12\
xslTransform.Load("MML2OMML.xsl");
// Load the file containing your MathML presentation markup.
using (XmlReader reader = XmlReader.Create(File.Open("mathML.xml", FileMode.Open)))
{
using (MemoryStream ms = new MemoryStream())
{
XmlWriterSettings settings = xslTransform.OutputSettings.Clone();
// Configure xml writer to omit xml declaration.
settings.ConformanceLevel = ConformanceLevel.Fragment;
settings.OmitXmlDeclaration = true;
XmlWriter xw = XmlWriter.Create(ms, settings);
// Transform our MathML to OfficeMathML
xslTransform.Transform(reader, xw);
ms.Seek(0, SeekOrigin.Begin);
StreamReader sr = new StreamReader(ms, Encoding.UTF8);
string officeML = sr.ReadToEnd();
Console.Out.WriteLine(officeML);
// Create a OfficeMath instance from the
// OfficeMathML xml.
DocumentFormat.OpenXml.Math.OfficeMath om =
new DocumentFormat.OpenXml.Math.OfficeMath(officeML);
// Add the OfficeMath instance to our
// word template.
using (WordprocessingDocument wordDoc =
WordprocessingDocument.Open("template.docx", true))
{
DocumentFormat.OpenXml.Wordprocessing.Paragraph par =
wordDoc.MainDocumentPart.Document.Body.Descendants<DocumentFormat.OpenXml.Wordprocessing.Paragraph>().FirstOrDefault();
foreach (var currentRun in om.Descendants<DocumentFormat.OpenXml.Math.Run>())
{
// Add font information to every run.
DocumentFormat.OpenXml.Wordprocessing.RunProperties runProperties2 =
new DocumentFormat.OpenXml.Wordprocessing.RunProperties();
RunFonts runFonts2 = new RunFonts() { Ascii = "Cambria Math", HighAnsi = "Cambria Math" };
runProperties2.Append(runFonts2);
currentRun.InsertAt(runProperties2, 0);
}
par.Append(om);
}
}
}