2010-11-02 2 views
4

Для создания текстовых документов на основе данных из базы данных SQL, я использую Office Open XML SDK, чтобы избежать использования взаимодействия. Это ускоряет процесс и устраняет необходимость установки офисного пакета Microsoft в клиентской системе.Office Open XML SDK word replace

Хотя это работает очень хорошо, возникает проблема, возникающая при замене определенного текста в документе. Чтобы сохранить настройку окончательного документа в качестве опции, я создал документ с некоторыми тегами в нем в качестве шаблона. Этот шаблон содержит теги, такие как [TagHere]. Поскольку имена тегов должны быть легко читаемыми, их можно использовать во всем документе, поэтому я окружил тег фигурными скобками [].

Это работает довольно хорошо, но иногда возникает проблема. Когда вы вводите документ docx, текст можно разделить на несколько тегов, даже в том же слове. Тег как [TagHere] можно разбить на

<tag>[</tag><tag>TagHere</tag><tag>]</tag>

Когда это произойдет, то замена не будет работать.

В настоящее время формат docx имеет некоторые альтернативные варианты выполнения таких операций, как, например, элементы управления содержимым, но это делает процесс создания шаблона более сложным. Более того, в этих документах нет ничего необычного, чтобы получить одну строку таблицы с тегами и скопировать ее несколько раз, что, вероятно, нарушит принцип тега контента. Поэтому я решил не использовать этот вариант.

Было бы здорово, если бы у кого-то было решение этой проблемы.

+0

Вам не нужно заменять рыболовные крючки (= угловые скобки?), Если вы сделаете этот материал секцией кода: выберите текст и нажмите кнопку «101010». – LarsH

+0

Thansk для комментария, изучая каждый день :) –

ответ

4

вместо ввода простого текста «taghere», вставьте поле слияния. (в слове, нажмите «Вставить»> «Быстрые части»). Выберите «mergefield» и введите «TagHere» в поле «Имя поля».)

затем вместо того, чтобы выполнять поиск текста, и установить внутренние тексты.

class Program 
{ 
    static void Main(string[] args) 
    { 
     string document = args[0]; 
     using (WordprocessingDocument wordDoc = WordprocessingDocument.Open(document, true)) 
     { 
      Dictionary<string, string> replaceOperations = new Dictionary<string, string>(); 

      replaceOperations.Add("company", "alex's applications"); 
      replaceOperations.Add("first_name", "alexander"); 
      replaceOperations.Add("last_name", "taylor"); 
      //etc 

      Replace(wordDoc, replaceOperations); 
     } 
    } 

    public static char[] splitChar = new char[] {' '}; 
    public static void Replace(WordprocessingDocument document, Dictionary<string, string> replaceOperations) 
    { 
     //find all the fields 
     foreach (var field in document.MainDocumentPart.Document.Body.Descendants<SimpleField>()) 
     { 
      //parse the instruction 
      string[] instruction = field.Instruction.Value.Split(splitChar, StringSplitOptions.RemoveEmptyEntries); 

      //check if it's a merge field, and if so... 
      if (instruction[0].ToLower().Equals("mergefield")) 
      { 
       //get the field name 
       string fieldname = instruction[1]; 

       //find the text inside (there will only be one) 
       foreach (var fieldtext in field.Descendants<Text>()) 
       { 
        //see if we know what to set this value to 
        string value = replaceOperations.ContainsKey(fieldname) ? replaceOperations[fieldname] : null; 

        //if we found the replace value, set the text to this value 
        if (value != null) 
         fieldtext.Text = value; 

        //should only be one text inside 
        break; 
       } 
      } 
     } 
    } 
} 
+0

Спасибо за ответ, это работает! –

+1

Я пытаюсь что-то очень похожее, но проблема в том, что поля слияния не всегда представлены как «SimpleField», иногда они являются «FieldCode» с соответствующими 'FieldChar'. –

Смежные вопросы