Я использую MathML для создания некоторых блоков данных, и мне нужно вставить его через OpenXML SDK в файл docx. Я слышал, что это возможно, но мне это не удалось. Может ли кто-нибудь помочь мне с этой проблемой?
OpenXML SDK и MathML
Ответы (1)
Насколько я знаю, OpenXml SDK не поддерживает презентацию MathML из коробки.
Вместо этого OpenXml SDK поддерживает Office MathML. Таким образом, чтобы вставить презентацию MathML в текстовый документ, мы сначала должны преобразовать презентацию MathML в Office MathML.
К счастью, Microsoft предоставляет файл XSL (названный MML2OMML.xsl) для преобразования MathML презентации в MathML Office. Файл MML2OMML.xsl находится в папке %ProgramFiles%\Microsoft Office\Office12
. В сочетании с классом .Net Framework XslCompiledTransform
мы можем преобразовать представление MathML в Office MathML.
Следующим шагом является создание объекта OfficeMath
из преобразованного MathML. Класс OfficeMath
представляет запуск, содержащий WordprocessingML, который должен обрабатываться так же, как если бы это был Office Open XML Math. Дополнительные сведения см. в MSDN.
Презентация MathML не содержит информации о шрифтах. Чтобы получить хороший результат, мы должны добавить информацию о шрифте к созданному объекту OfficeMath
.
На последнем шаге мы должны добавить объект OfficeMath
в наш текстовый документ. В приведенном ниже примере я просто ищу первый Paragraph
в текстовом документе с именем template.docx и добавляю объект 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);
}
}
}