OpenXML SDK и MathML

Я использую MathML для создания некоторых блоков данных, и мне нужно вставить его через OpenXML SDK в файл docx. Я слышал, что это возможно, но мне это не удалось. Может ли кто-нибудь помочь мне с этой проблемой?


person user1450792    schedule 12.06.2012    source источник


Ответы (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);
    }
  }
}
person Hans    schedule 12.06.2012
comment
Большое спасибо за ответ! Я очень ценю это! Я уже пробовал ваш код, и у меня все получилось! Вы спасли меня! Спасибо еще раз! - person user1450792; 13.06.2012
comment
@ user1450792: Добро пожаловать! Пожалуйста, примите мой ответ, нажав на галочку рядом с ответом, чтобы переключить его с пустого на зеленый. - person Hans; 13.06.2012
comment
Очень хорошее решение @Hans. Но как я могу сделать обратное. Я хочу преобразовать содержимое xml файла слова с помощью OMML в обычный текст, содержащий MML..!? - person serene; 27.05.2013
comment
@serene: Пожалуйста, посмотрите мой ответ на ваш вопрос. - person Hans; 27.05.2013
comment
@ Ганс, привет! спасибо и это работает! Я хочу преобразовать MathML в Open Xml Math в качестве надстройки в области ленты с помощью C#, но не могу найти такой метод, как par.Append(om); в PIA, и я не знаю, как преобразовать тип WordprocessingDocument в тип Globals.ThisAddIn.Application.ActiveDocument. Можно ли каким-либо образом выполнить тот же метод в надстройке или с помощью правой кнопки мыши, которая может в режиме реального времени преобразовать эти MathMl в уравнения MS группами или по одному, спасибо! - person archenoo; 19.10.2013
comment
Самый отличный и полезный ответ. Небольшое изменение, которое я сделал, заключается в поиске математической формулы с помощью Descendants‹DocumentFormat.OpenXml.Math.OfficeMath›, так как это также найдет формулу в середине абзаца. Спасибо. - person too; 29.08.2014
comment
@Hans Извинения, я добавил комментарий к неправильному вопросу. Я имел в виду ваш ответ на 16759100 об обратном - импорте одного уравнения из документа Word. Возможно, это изменение может относиться к этому ответу. - person too; 29.08.2014
comment
@ Ганс, очень полезный ответ! мне установить офис, чтобы заставить его работать? Я хочу использовать его на сервере. Спасибо! - person James Hao; 14.01.2020