2015-03-17 3 views
2

Я использую открытый XML (Microsoft Word - .docx) в качестве шаблона файла для автоматического создания других документов. В документе шаблона я определил элементы управления содержимым, и я написал код для замены контента в этих элементах управления контентом.Как сохранить стиль в открытых документах xml

Содержимое заменяется, и документы создаются, но я борюсь с сохранением стиля. В Word, проверяя свойства элемента управления содержимым, я проверил checbox для «Использовать стиль для форматирования текста в пустой элемент управления: стиль», а также отмечен «Удалить элементы управления контентом при редактировании контента». По-видимому, это не оказывает никакого влияния, если документы генерируются кодом.

Here is how I set the properties of the content control in Word Это мой код (который член сообщества здесь был достаточно любезен, чтобы помочь) для замены данных в элементах управления контентом. Любые идеи, что я должен делать, чтобы сохранить форматирование? Форматирование - это простое форматирование текста, например размер и шрифт. Пожалуйста, совет:

private static void ReplaceTags(MainDocumentPart mainPart, string tagName, string tagValue) 
    { 
     //grab all the tag fields 
     var tagFields = mainPart.Document.Body.Descendants<SdtBlock>().Where 
      (r => r.SdtProperties.GetFirstChild<Tag>().Val == tagName); 

     foreach (var field in tagFields) 
     { 
      //remove all paragraphs from the content block 
      field.SdtContentBlock.RemoveAllChildren<DocumentFormat.OpenXml.Wordprocessing.Paragraph>(); 
      //create a new paragraph containing a run and a text element 
      var newParagraph = new DocumentFormat.OpenXml.Wordprocessing.Paragraph(); 
      var newRun = new DocumentFormat.OpenXml.Wordprocessing.Run(); 
      var newText = new DocumentFormat.OpenXml.Wordprocessing.Text(tagValue); 
      newRun.Append(newText); 
      newParagraph.Append(newRun); 
      //add the new paragraph to the content block 
      field.SdtContentBlock.Append(newParagraph); 
     } 
    } 

ответ

6

При назначении стиля управления содержимым нового RunProperties элемент добавляется под SdtProperties. Например, если я назначу новый стиль под названием Style1 я могу видеть, генерируется следующий XML:

<w:sdt> 
    <w:sdtPr> 
     <w:rPr> 
      <w:rStyle w:val="Style1" /> 
     </w:rPr> 
    <w:alias w:val="LastName" /> 
    <w:tag w:val="LastName" /> 
    .... 

Вы должны захватить это значение и присвоить его новый Paragraph вы создаете, добавьте Paragraph в том же как SdtBlock, а затем удалите SdtBlock, что и в Word, когда вы выбираете параметр «Удалить контент-контроль при редактировании содержимого». RunProperties - это элемент <w:rPr>. Следующее должно делать то, что вам нужно.

private static void ReplaceTags(MainDocumentPart mainPart, string tagName, string tagValue) 
{ 
    //grab all the tag fields 
    IEnumerable<SdtBlock> tagFields = mainPart.Document.Body.Descendants<SdtBlock>().Where 
     (r => r.SdtProperties.GetFirstChild<Tag>().Val == tagName); 

    foreach (var field in tagFields) 
    { 
     //grab the RunProperties from the SdtBlcok 
     RunProperties runProp = field.SdtProperties.GetFirstChild<RunProperties>(); 

     //create a new paragraph containing a run and a text element 
     Paragraph newParagraph = new Paragraph(); 
     Run newRun = new Run(); 
     if (runProp != null) 
     { 
      //assign the RunProperties to our new run 
      newRun.Append(runProp.CloneNode(true)); 
     } 
     Text newText = new Text(tagValue); 
     newRun.Append(newText); 
     newParagraph.Append(newRun); 
     //insert the new paragraph before the field we're going to remove 
     field.Parent.InsertBefore(newParagraph, field); 

     //remove the SdtBlock to mimic the Remove content control when contents are edited option 
     field.Remove(); 
    } 
} 
+0

Привет, и спасибо миллион за вашу помощь в кодировании и очень хорошее объяснение. Код работал с сохранением стиля, но у меня возникла новая проблема :). При запуске этого кода он сохраняет стиль неповрежденным, но после ввода нового текста внутри элемента управления содержимым текст помещается в нижней части страницы. У меня было это сверху. Любые идеи, как заставить его сохранить свою позицию?? Еще раз спасибо – Ilyas

+0

Thanks @Ilyas. Строка 'field.Parent.AppendChild (newParagraph);' добавляла новый абзац в конце документа. Я отредактировал ответ, чтобы использовать 'field.Parent.InsertBefore (newParagraph, field);' который добавит его перед элементом управления содержимым (которое затем будет удалено, поэтому по существу оно находится в той же точке, что и элемент управления содержимым) – petelids

+1

Отлично кусок кода! Вы можете даже использовать это, чтобы поддерживать тот же формат при создании нескольких строк в одном и том же абзаце, вызывая следующее в цикле: RunProperties runProps = newRun.AppendChild (новый RunProperties()); Break linebreak = new Break(); runProps.Append (linebreak); – Themos