none
Изменение колонтитулов Word докуменгта RRS feed

  • Вопрос

  • Здравствуйте,

    делаю фичу для портала - изменение колонтитулов документа при его выгрузке.

    Возникли проблемы при работе с объектной моделью Word документов, а именно с тем как добраться до колонтитулов...

    Сейчас для изменения колонтитулов я использую такой метод:

     

    protected string AddCatchwords(string docPath, string docPassword)
        {
          Word.Application wordAppliaction = null;
    
          wordAppliaction = new Word.Application();
          wordAppliaction.Visible = false;
    
          object fileName = docPath;
          object confirmConversions = true;
          object;
          object addToRecentFiles = false;
          object passwordDocument = Type.Missing;
          object passwordTemplate = Type.Missing;
          object revert = true;
          object writePasswordDocument = Type.Missing;
          object writePasswordTemplate = Type.Missing;
          object format = Type.Missing;
          object encoding = Type.Missing;
          object visible = Type.Missing;
          object openConflictDocument = Type.Missing;
          object openAndRepair = Type.Missing;
          object documentDirection = Type.Missing;
          object noEncodingDialog = true;
          object xmlTransform = Type.Missing;
    
          Word.Document wordDocument = null;
    
          wordDocument = wordAppliaction.Documents.Open(
              ref fileName, ref confirmConversions, ref readOnly, ref addToRecentFiles, ref passwordDocument,
              ref passwordTemplate, ref revert, ref writePasswordDocument, ref writePasswordTemplate, ref format,
              ref encoding, ref visible, ref openAndRepair, ref documentDirection, ref noEncodingDialog, ref xmlTransform);
    
          wordDocument.Activate();
    
          Word.HeaderFooter documentFooter = null;
    
          documentFooter = wordDocument.Sections[1].Footers[Word.WdHeaderFooterIndex.wdHeaderFooterPrimary];
    
          try
          {
            documentFooter.Range.InsertAfter(
    // тут собственно и добавляю то что надо...
    );
          }
          catch
          {
            wordDocument.Unprotect(docPassword);
    
            documentFooter.Range.InsertAfter(
    // тут собственно и добавляю то что надо...
    );
    
            object recent = true;
            object password = docPassword;
            object useIRM = Type.Missing;
            object enforceStyleLock = Type.Missing;
    
            wordDocument.Protect(Word.WdProtectionType.wdAllowOnlyReading, ref recent, ref password, ref useIRM, ref enforceStyleLock);
          }
    
          string footer = documentFooter.Range.Text;
    
          object saveChanges = Word.WdSaveOptions.wdSaveChanges;
          object originalFormat = Type.Missing;
          object routeDocument = Type.Missing;
    
          ((Word._Document)wordDocument).Close(saveChanges, originalFormat, routeDocument);
    
          ((Word._Application)wordAppliaction).Quit();
    
          wordAppliaction = null;
    
          return footer;
        }
    

     

    Проблема в заключается в том, что через wordDocument.Sections[1].Footers[Word.WdHeaderFooterIndex.wdHeaderFooterPrimary] получается добраться только до колонтитулов титульной страницы (так называемых Колонтитулов раздела 1).

    Вопрос: как перебрать все нижние колонтитулы документа (всех страниц) и внести в них изменения?

Ответы

  • Если не ошибаюсь - вместо wordDocument.Sections[1] надо использовать

    foreach (Section section in wordDocument.Sections)
    {
       ... section.Footers[Word.WdHeaderFooterIndex.wdHeaderFooterPrimary]...
    }

    и вам совершенно верно подсказывают - на сервере нужно пользоваться OpenXML или обертками над ним.

     

    • Помечено в качестве ответа A.G.Sedov 19 мая 2011 г. 10:43

Все ответы

  • Пока не очень много сил потратили, перейдите на другой способ работы с документами - на сервере использовать Word не рекомендуется. Да и мало у кого получилось...

    Для сервера существует OpenXML. Хотя тоже не подарок...

    Отвечающий
  • Если не ошибаюсь - вместо wordDocument.Sections[1] надо использовать

    foreach (Section section in wordDocument.Sections)
    {
       ... section.Footers[Word.WdHeaderFooterIndex.wdHeaderFooterPrimary]...
    }

    и вам совершенно верно подсказывают - на сервере нужно пользоваться OpenXML или обертками над ним.

     

    • Помечено в качестве ответа A.G.Sedov 19 мая 2011 г. 10:43
  • Использовать OpenXML нет возможности...

    foreach (Section section in wordDocument.Sections)

    да это частично решает проблему... делов том что несколько секции могут ссылаться на один и тот же колонтитул, тогда вот такой цикл несколько раз запишет одно и тоже... Сейчас просто всякими кривыми методами, сначало проверяю редактировался ли уже колонтитул и если нет редактирую...

  • а если перебрать страницы и получить page.Section(1) ?
  • а если перебрать страницы и получить page.Section(1) ?

     

    Word.Document - не содержит колекции страниц, так что я понятия не имею как перебрать все страницы. По описанию DOM Word-а - документы должны сорержать колекции Footers, но не фига не содержат...

    Более того, есть колонтитулы секции, есть колонитулы первой страницы документа - и если до них ещё более менее понятно как добраться, то вот как добраться до колонитулов перволй страницы секции фиг. знает??? В документе они создаются,а через объектную модель их нигде не достать...

  • Перебор всех секций и колонтитулов (с проверкой не используется ли колонтитул с предыдущей секции):

    foreach (Word.Section section in wordDocument.Sections)
    {
        foreach (Word.HeaderFooter h in section.Headers)
        {
            if (!h.LinkToPrevious)//skip if linked to previous
            {
                Console.WriteLine(string.Format("Header (title): {0}", h.Range.Text));
            }
        }
    }

    Можно было бы вместо вложенного цикла по колонтитулам использовать доступ по индексу, если вам нужны не все а только конкретные:

    section.Headers[Word.WdHeaderFooterIndex.wdHeaderFooterPrimary]
    section.Headers[Word.WdHeaderFooterIndex.wdHeaderFooterFirstPage]
    section.Headers[Word.WdHeaderFooterIndex.wdHeaderFooterEvenPages]

    "По описанию DOM Word-а - документы должны сорержать колекции Footers" - где это вы такое нашли?