Разработка в среде SharePoint 2010 Word Automation Services

Обзор:   в данной статье описывается использование служб Word Automation Services для преобразования различных форматов документов на стороне сервера. С помощью пакета Open XML SDK можно выполнять такие сложные задачи, как обновление оглавления или разбивка документов на страницы.

Дата последнего изменения: 9 марта 2015 г.

Применимо к: Business Connectivity Services | Office 2010 | Open XML | SharePoint Designer 2010 | SharePoint Foundation 2010 | SharePoint Online | SharePoint Server 2010 | Visual Studio | Word Autmomation Services

В этой статье
Использование Word Automation Services для изменения форматов документов
Один сценарий использования Word Automation Services
Как работает компонент Word Automation Services
Настройка Word Automation Services
Создание приложения Word Automation Services
Отслеживание состояния преобразования
Идентификация документов, которые не удалось преобразовать
Удаление исходных файлов после преобразования
Интеграция с пакетом Open XML SDK
Заключение
Дополнительные материалы

Предоставлено:   Эрик Уайт (Eric White), корпорация Майкрософт | Тристан Дэвис (Tristan Davis), корпорация Майкрософт | Зияд Раджаби (Zeyad Rajabi), корпорация Майкрософт

Содержание

  • Использование Word Automation Services для изменения форматов документов

  • Один сценарий использования Word Automation Services

  • Как работает компонент Word Automation Services

  • Создание приложения Word Automation Services

  • Отслеживание состояния преобразования

  • Идентификация документов, которые не удалось преобразовать

  • Удаление исходных файлов после преобразования

  • Интеграция с пакетом Open XML SDK

  • Заключение

  • Дополнительные материалы

Щелкните, чтобы скопировать код  Загрузить код (Возможно, на английском языке)

Использование Word Automation Services для изменения форматов документов

При использовании Open XML SDK 2.0 для Microsoft Office трудно выполнить некоторые задачи, например разбивку на страницы, преобразование в другие форматы документов, например в PDF, или обновление оглавления, полей и другого динамического контента в документах. Word Automation Services — это новый компонент SharePoint 2010, который может помочь в этих сценариях. Это общая служба, которая обеспечивает автоматическое преобразование документов в другие форматы на стороне сервера, а также некоторые другие важные функции. Она с самого начала разрабатывалась для работы на серверах и может обрабатывать множество документов надежным и предсказуемым образом.

С помощью Word Automation Services можно выполнять преобразования из Open XML WordprocessingML в другие форматы документов. Например, можно преобразовать множество документов в формат PDF и отправить их в очередь на печать или отправить клиентам по электронной почте. Или же можно преобразовать документы из других форматов (например, из HTML или из двоичных документов Word 97-2003) в текстовые документы Open XML.

Кроме средств преобразования документов, Word Automation Services обеспечивает и другие важные функциональные возможности, например обновление кодов полей в документах и преобразование контента altChunk в абзацы с применением обычного стиля. Эти задачи могут быть сложными для выполнения с помощью пакета SDK Open XML версии 2.0. Однако для их выполнения легко использовать Word Automation Services. Раньше компонент Word Automation Services использовался при выполнении подобных задач для клиентских приложений. Однако такой подход проблематичен. Клиент Word — это приложение, которое лучше всего подходит для интерактивной разработки документов и не предназначено для обработки больших объемов данных на сервере. При выполнении этих задач Word может вывести диалоговое окно с сообщением об ошибке, и если клиент Word выполняется на сервере в автоматическом режиме, пользователь не сможет среагировать на диалоговое окно и процесс может преждевременно остановиться. Проблемы, связанные с автоматизацией Word, задокументированы в статье базы знаний, посвященной вопросам автоматизации Office на стороне сервера.

Один сценарий использования Word Automation Services

В этом сценарии описано использование Word Automation Services для автоматизации обработки документов на сервере.

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

  • На сервере запускается программа для объединения шаблонов документов с данными, создающая набор документов Open XML WordprocessingML (DOCX). Эту программу лучше всего написать с помощью пакета Open XML SDK 2.0 для Microsoft Office, который был разработан специально для создания документов на сервере. Эти документы помещаются в библиотеку документов SharePoint.

  • После создания набора документов они могут быть автоматически напечатаны. Или же они могут быть отправлены по электронной почте набору пользователей как документы WordprocessingML или как документы в формате PDF, XPS или MHTML после их преобразования из формата WordprocessingML в требуемый формат.

  • В процессе преобразования можно указать Word Automation Services выполнить обновление полей, например оглавления.

Использование Open XML SDK 2.0 для Microsoft Office с Word Automation Services позволяет создавать полноценные, комплексные решения, эффективные и не требующие автоматизации клиентского приложения Word.

Одним из ключевых преимуществ Word Automation Services является возможность масштабирования в соответствии с потребностями пользователя. В отличие от клиентского приложения Word, этот компонент можно настроить для использования нескольких процессоров. Более того, его можно настроить для балансировки нагрузки между несколькими серверами, если существует такая необходимость.

Другим важным преимуществом является идеальная совместимость Word Automation Services с клиентскими приложениями Word. Структура документа, в том числе разбивка на страницы, является идентичной независимо от того, обрабатывается ли документ на сервере или на клиенте.

Поддерживаемые форматы исходных документов

Для исходных документов поддерживаются следующие форматы.

  1. Документы в формате Open XML (DOCX, DOCM, DOTX, DOTM)

  2. Документы Word 97-2003 (DOC, DOT)

  3. Файлы в формате RTF (Portable Document Format)

  4. Веб-страницы в одном файле (MHT, MHTML)

  5. XML-документы Word 2003 (XML)

  6. XML-документы Word (XML)

Поддерживаемые целевые форматы документов

Поддерживаемые целевые форматы документов включают все поддерживаемые форматы исходных документов, а также следующие форматы.

  1. Формат PDF (Portable Document Format)

  2. Формат XPS (Open XML Paper Specification)

Другие возможности Word Automation Services

Кроме возможности загрузки и сохранения документов в различных форматах, Word Automation Services включает и другие возможности.

Word Automation Services можно использовать для обновления оглавления, таблицы ссылок и полей индекса. Это важно при создании документов. Если в созданном документе есть оглавление, особенно трудной задачей представляется определение разбивки на страницы таким образом, чтобы оглавление обновлялось правильно. Компонент Word Automation Services легко справляется с этой задачей.

Текстовые документы Open XML могут содержать различные типы полей, которые позволяют добавлять в документ динамический контент. Word Automation Services можно использовать для запуска пересчета всех полей. Например, можно включить тип поля, который вставляет в документ текущую дату. При обновлении полей связанный контент также обновляется, так что документ отображает текущую дату в месте расположения поля.

Одним из мощных способов использования элементов управления контентом является их привязка к элементам XML в настраиваемой части XML. В статье Построение систем создания документов на основе шаблонов с помощью Word 2010 и Word 2007 дано описание привязанных элементов управления контентом, а также приведены ссылки на несколько ресурсов для начала работы. Содержимое привязанных элементов управления контентом можно заменить, заменив код XML в настраиваемой части XML. При этом изменять основную часть документа не нужно. Основная часть документа содержит кэшированные значения для всех привязанных элементов управления контентом, и при замене кода XML в настраиваемой части XML кэшированные значения в основной части документа не обновляются. Это не является проблемой, если пользователи будут просматривать эти документы только с помощью клиента Word. Однако если необходимо также обработать разметку WordprocessingML, придется обновить кэшированные значения в основной части документа. Компонент Word Automation Services может это сделать.

Контент в альтернативном формате (представленный элементом altChunk) — это замечательный способ импорта HTML-контента в документ WordprocessingML. В статье Построение систем создания документов на основе шаблонов с помощью Word 2010 и Word 2007 рассматривается контент в альтернативном формате и его использование, а также представлены ссылки для начала работы. Однако, пока вы не откроете и не сохраните документ, содержащий элементы altChunk, документ будет содержать HTML, а не обычную разметку WordprocessingML, такую как элементы Paragraph, Run и Text. Word Automation Services можно использовать для импорта HTML (или других типов альтернативного контента) и преобразования в разметку WordprocessingML, содержащую привычные элементы Paragraph разметки WordprocessingML со стилями.

Также можно выполнять преобразования в форматы (и из них), которые использовались предыдущими версиями Word. При создании приложения корпоративного класса, используемого тысячами пользователей, некоторые пользователи могут использовать Word 2007 или Word 2003 для редактирования документов Open XML. Можно преобразовать документы Open XML так, чтобы они содержали только разметку и функции, которые используются в Word 2007 или Word 2003.

Ограничения Word Automation Services

Компонент Word Automation Services не поддерживает печать документов. Однако можно просто преобразовать документы WordprocessingML в формат PDF или XPS и отправить их на печать.

Иногда возникает вопрос, можно ли использовать Word Automation Services, не приобретая и не устанавливая SharePoint Server 2010. В Word Automation Services используются возможности SharePoint 2010, компонентом которого он является. Для их использования необходимо приобрести и установить SharePoint Server 2010. Компонент Word Automation Services входит в стандартный и корпоративный выпуски.

Как работает компонент Word Automation Services

По умолчанию Word Automation Services представляет собой службу, которая устанавливается и запускается вместе с автономной установкой SharePoint Server 2010. Если SharePoint 2010 используется в ферме серверов, необходимо явно включить Word Automation Services.

Чтобы использовать этот компонент, применяется программный интерфейс для запуска задания преобразования. Для каждого задания преобразования укажите, какие файлы, папки или документы необходимо обработать. На основании конфигурации, заданной при запуске задания преобразования, начинается указанное количество процессов преобразования на каждом сервере. Можно задать частоту, с которой будут запускаться задания преобразования, а также число преобразований, запускаемых для каждого процесса преобразования. Кроме того, можно задать максимальный процент памяти, который может использоваться Word Automation Services.

Параметры конфигурации позволяют настроить компонент Word Automation Services так, чтобы он не потреблял слишком много ресурсов на серверах SharePoint, которые являются частью важной инфраструктуры. Параметры, которые следует использовать, определяются тем, как требуется использовать компонент SharePoint Server. Если он используется только для преобразования документов, настройте параметры так, чтобы служба преобразования могла использовать большую часть времени процессора. Если служба преобразования используется для преобразований в фоновом режиме с низким приоритетом, настройте параметры соответственно.

Важное примечание.Важно!

Рекомендуется, чтобы максимальное число рабочих процессов было на единицу меньше, чем число процессоров на сервере. Если на сервере четыре процессора, задайте не больше трех рабочих процессов.

Если выполняется установка на ферме серверов, число рабочих процессов должно быть на единицу меньше, чем число процессоров на сервере с наименьшим числом процессоров в ферме серверов.

Рекомендуется настроить систему для преобразования максимум 90 документов на рабочий процесс в минуту.

Кроме написания кода, который запускает процессы преобразования, можно также написать код для отслеживания выполнения преобразований. Это позволит информировать пользователей или отправлять оповещения с результатами при завершении очень больших заданий преобразования.

Компонент Word Automation Services позволяет настроить четыре дополнительных аспекта преобразований.

  1. Можно ограничить число поддерживаемых форматов файлов.

  2. Можно задать число документов, преобразуемых процессом преобразования перед его перезапуском. Это полезно, так как недопустимые документы могут заставить Word Automation Services использовать слишком много памяти. При перезапуске процесса вся память освобождается.

  3. Можно задать для Word Automation Services количество попыток преобразования документа. По умолчанию указано две попытки, поэтому если Word Automation Services не удается преобразовать документ с первой попытки, выполняется только одна дополнительная попытка (в данном задании преобразования).

  4. Можно задать интервал времени перед началом отслеживания процессов преобразования. Это полезно, так как компонент Word Automation Services отслеживает преобразования, чтобы убедиться, что преобразования не были остановлены.

Настройка Word Automation Services

Если не установлена ферма серверов, по умолчанию компонент Word Automation Services устанавливается и запускается в SharePoint Server 2010. Однако разработчик может изменить его конфигурацию, чтобы улучшить возможности разработки. По умолчанию процессы преобразования запускаются с интервалом в 15 минут. При тестировании кода, который им используется, полезнее задать минутный интервал. Кроме того, существуют сценарии, в которых компонент Word Automation Services должен использовать как можно больше ресурсов. В таких сценариях также полезнее задать интервал в одну минуту.

Чтобы настроить интервал процесса преобразования на одну минуту, выполните следующие действия

  1. Запустите центр администрирования SharePoint 2010.

  2. На домашней странице центра администрирования SharePoint 2010 щелкните Управление приложениями-службами.

  3. На странице администрирования приложений-служб приложения-службы отсортированы в алфавитном порядке. Прокрутите экран вниз до конца страницы и щелкните Word Automation Services. Если устанавливается ферма серверов и компонент Word Automation Services был установлен вручную, на этой странице можно увидеть имя, которое было ранее задано для службы.

  4. На странице администрирования Word Automation Services настройте поле производительности преобразования для требуемой частоты запуска заданий преобразования.

  5. Как разработчик, вы возможно захотите задать число процессов преобразования и настроить число преобразований на один рабочий процесс. Если настроить частоту запуска процессов преобразования и не настроить остальные два значения, то при попытке преобразования множества документов процесс преобразования будет гораздо менее эффективным. Лучшие значения для этих параметров должны учитывать мощность компьютера, на котором выполняется SharePoint Server 2010.

  6. Прокрутите экран вниз до конца страницы и нажмите кнопку OK.

Создание приложения Word Automation Services

Поскольку Word Automation Services — это служба SharePoint Server 2010, ее можно использовать только в приложении, которое выполняется непосредственно на SharePoint Server. Необходимо построить приложение как решение фермы. Нельзя использовать Word Automation Services из решения для песочницы.

Удобным способом использования Word Automation Services является создание веб-службы, которую можно использовать из клиентских приложений.

Однако самым простым способом демонстрации написания кода, который использует Word Automation Services, является создание консольного приложения. Консольное приложение необходимо построить и запустить на SharePoint Server, а не на клиентском компьютере. Код для запуска и отслеживания заданий преобразования идентичен коду, который был бы разработан для веб-части, рабочего процесса или обработчика события. Демонстрация использования Word Automation Services из консольного приложения позволяет обсудить API, не включая в рассмотрение сложностей, связанных с веб-частями, обработчиком событий или рабочим процессом.

Важное примечание.Важно!

Обратите внимание, что в следующих примерах приложений вызывается метод Sleep(Int32) так, что запрос состояния выполняется каждые пять секунд. Такой подход не будет оптимальным при разработке кода, который предназначен для развертывания на рабочих серверах. Вместо этого необходимо создать рабочий процесс с задержкой действия.

Построение приложения

  1. Запустите Microsoft Visual Studio 2010.

  2. В меню Файл выберите пункт Создать, а затем выберите Проект.

  3. В диалоговом окне Создание проекта в области Последние шаблоны разверните узел Visual C# и выберите пункт Windows.

  4. В правой части области Последние шаблоны выберите Консольное приложение.

  5. По умолчанию в Visual Studio создается проект для платформы .NET Framework 4. Однако в этом случае необходимо выбрать платформу .NET Framework 3.5. В списке, расположенном в верхней части диалогового окна Открытие файла, выберите элемент .NET Framework 3.5.

  6. В поле Имя введите имя для проекта, например FirstWordAutomationServicesApplication.

  7. В поле Расположение укажите место для сохранения проекта.

    Рис. 1. Создание решения в диалоговом окне "Создание проекта"

    Создание решения в диалоговом окне "Новый проект"

  8. Нажмите кнопку ОК, чтобы создать решение.

  9. По умолчанию в Visual Studio 2010 создаются проекты для процессоров x86, но при построении приложений SharePoint Server следует задать любой процессор.

  10. Если создается приложение Microsoft Visual C#, в окне обозревателя решений щелкните правой кнопкой мыши проект и выберите Свойства.

  11. В окне свойств проекта щелкните Построить.

  12. Укажите на список Целевая платформа и выберите Любой ЦП.

    Рис. 2. Выбор любого процессора при построении консольного приложения C#

    Изменение целевой платформы на "Любой ЦП"

  13. Если создается приложение Microsoft Visual Basic .NET Framework, в окне свойств проекта щелкните Компиляция.

    Рис. 3. Параметры компиляции для приложения Visual Basic

    Параметры компиляции для приложений Visual Basic

  14. Щелкните Дополнительные параметры компиляции.

    Рис. 4. Диалоговое окно "Дополнительные параметры компилятора"

    Диалоговое окно "Дополнительные параметры компилятора"

  15. Укажите на список Целевая платформа и выберите Любой ЦП.

  16. Чтобы добавить ссылку на сборку Microsoft.Office.Word.Server, в меню "Проект" выберите команду Добавить ссылку, чтобы открыть диалоговое окно "Добавление ссылки".

  17. Выберите вкладку .NET и добавьте компонент с именем "компонент Microsoft Office 2010".

    Рис. 5. Добавление ссылки на компонент Microsoft Office 2010

    Добавление ссылки на компонент Microsoft Office 2010

  18. После этого добавьте ссылку на сборку Microsoft.SharePoint.

    Рис. 6. Добавление ссылки на Microsoft SharePoint

    Добавление ссылки на Microsoft SharePoint

В следующих примерах представлены полные листинги кода C# и Visual Basic для простейшего приложения Word Automation Services.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint;
using Microsoft.Office.Word.Server.Conversions;

class Program
{
    static void Main(string[] args)
    {
        string siteUrl = "https://localhost";
        // If you manually installed Word automation services, then replace the name
        // in the following line with the name that you assigned to the service when
        // you installed it.
        string wordAutomationServiceName = "Word Automation Services";
        using (SPSite spSite = new SPSite(siteUrl))
        {
            ConversionJob job = new ConversionJob(wordAutomationServiceName);
            job.UserToken = spSite.UserToken;
            job.Settings.UpdateFields = true;
            job.Settings.OutputFormat = SaveFormat.PDF;
            job.AddFile(siteUrl + "/Shared%20Documents/Test.docx",
                siteUrl + "/Shared%20Documents/Test.pdf");
            job.Start();
        }
    }
}
Imports Microsoft.SharePoint
Imports Microsoft.Office.Word.Server.Conversions
Module Module1
    Sub Main()
        Dim siteUrl As String = "https://localhost"
        ' If you manually installed Word automation services, then replace the name
        ' in the following line with the name that you assigned to the service when
        ' you installed it.
        Dim wordAutomationServiceName As String = "Word Automation Services"
        Using spSite As SPSite = New SPSite(siteUrl)
            Dim job As ConversionJob = New ConversionJob(wordAutomationServiceName)
            job.UserToken = spSite.UserToken
            job.Settings.UpdateFields = True
            job.Settings.OutputFormat = SaveFormat.PDF
            job.AddFile(siteUrl + "/Shared%20Documents/Test.docx", _
                siteUrl + "/Shared%20Documents/Test.pdf")
            job.Start()
        End Using
    End Sub
End Module
ЗаметкаПримечание

Замените URL-адрес, присвоенный параметру siteUrl, на URL-адрес сайта SharePoint.

Построение и запуск примера

  1. Добавьте документ Word с именем Test.docx в папку "Общие документы" на сайте SharePoint.

  2. Постройте и запустите пример.

  3. Дождитесь запуска процесса преобразования (процесс запустится через одну минуту), перейдите в папку "Общие документы" на сайте SharePoint и обновите страницу. Теперь библиотека документов содержит новый документ PDF с именем Test.pdf.

Отслеживание состояния преобразования

Во многих сценариях желательно отслеживать состояние преобразований, чтобы информировать пользователя о завершении процесса преобразования или чтобы дополнительно обработать преобразованные документы. Можно использовать класс ConversionJobStatus для запроса Word Automation Services о состоянии задания преобразования. Передайте имя класса WordServiceApplicationProxy как строку (по умолчанию "Word Automation Services") и идентификатор задания преобразования, который можно получить из объекта ConversionJob. Также можно передать идентификатор GUID, который задает раздел клиента. Однако если ферма SharePoint Server не настроена для нескольких клиентов, в качестве аргумента для этого параметра можно передать значение null ("Nothing" в Visual Basic).

После создания экземпляра объекта ConversionJobStatus можно обратиться к нескольким свойствам, которые показывают состояние задания преобразования. Ниже приведены три наиболее интересных свойства.

Свойства ConversionJobStatus

Свойство

Возвращаемое значение

Count

Число документов в задании преобразования в данный момент.

Succeeded

Число успешно преобразованных документов.

Failed

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

Тогда как в первом примере для преобразования задан один документ, в следующем примере выполняется преобразование всех документов в указанной библиотеке документов. Можно задать параметр для создания всех преобразованных документов в другой библиотеке, но для простоты в следующем примере для ввода и вывода документов задается одна библиотека. Кроме того, в следующем примере указывается, что задание преобразования должно перезаписывать выходные документы, если они уже существуют.

Загрузить код (Возможно, на английском языке)

Console.WriteLine("Starting conversion job");
ConversionJob job = new ConversionJob(wordAutomationServiceName);
job.UserToken = spSite.UserToken;
job.Settings.UpdateFields = true;
job.Settings.OutputFormat = SaveFormat.PDF;
job.Settings.OutputSaveBehavior = SaveBehavior.AlwaysOverwrite;
SPList listToConvert = spSite.RootWeb.Lists["Shared Documents"];
job.AddLibrary(listToConvert, listToConvert);
job.Start();
Console.WriteLine("Conversion job started");
ConversionJobStatus status = new ConversionJobStatus(wordAutomationServiceName,
    job.JobId, null);
Console.WriteLine("Number of documents in conversion job: {0}", status.Count);
while (true)
{
    Thread.Sleep(5000);
    status = new ConversionJobStatus(wordAutomationServiceName, job.JobId,
        null);
    if (status.Count == status.Succeeded + status.Failed)
    {
        Console.WriteLine("Completed, Successful: {0}, Failed: {1}",
            status.Succeeded, status.Failed);
        break;
    }
    Console.WriteLine("In progress, Successful: {0}, Failed: {1}",
        status.Succeeded, status.Failed);
}
Console.WriteLine("Starting conversion job")
Dim job As ConversionJob = New ConversionJob(wordAutomationServiceName)
job.UserToken = spSite.UserToken
job.Settings.UpdateFields = True
job.Settings.OutputFormat = SaveFormat.PDF
job.Settings.OutputSaveBehavior = SaveBehavior.AlwaysOverwrite
Dim listToConvert As SPList = spSite.RootWeb.Lists("Shared Documents")
job.AddLibrary(listToConvert, listToConvert)
job.Start()
Console.WriteLine("Conversion job started")
Dim status As ConversionJobStatus = _
    New ConversionJobStatus(wordAutomationServiceName, job.JobId, Nothing)
Console.WriteLine("Number of documents in conversion job: {0}", status.Count)
While True
    Thread.Sleep(5000)
    status = New ConversionJobStatus(wordAutomationServiceName, job.JobId, _
                                     Nothing)
    If status.Count = status.Succeeded + status.Failed Then
        Console.WriteLine("Completed, Successful: {0}, Failed: {1}", _
                          status.Succeeded, status.Failed)
        Exit While
    End If
    Console.WriteLine("In progress, Successful: {0}, Failed: {1}", _
                      status.Succeeded, status.Failed)
End While

Чтобы выполнить этот пример, добавьте несколько документов WordprocessingML в библиотеку "Общие документы". При выполнении этого примера вы увидите выходные данные, похожие на этот фрагмент,

Starting conversion job
Conversion job started
Number of documents in conversion job: 4
In progress, Successful: 0, Failed: 0
In progress, Successful: 0, Failed: 0
Completed, Successful: 4, Failed: 0

Идентификация документов, которые не удалось преобразовать

Может понадобиться определить, какие документы не удалось преобразовать, чтобы проинформировать пользователя или принять меры для исправления этой ситуации, например удалить недопустимый документ из входной библиотеки документов. Можно вызвать метод GetItems(), который возвращает коллекцию объектов ConversionItemInfo(). При вызове метода GetItems() передается параметр, который указывает, нужно ли получить коллекцию неудачных или удачных преобразований. В следующем примере показывается, как это можно сделать.

Загрузить код (Возможно, на английском языке)

Console.WriteLine("Starting conversion job");
ConversionJob job = new ConversionJob(wordAutomationServiceName);
job.UserToken = spSite.UserToken;
job.Settings.UpdateFields = true;
job.Settings.OutputFormat = SaveFormat.PDF;
job.Settings.OutputSaveBehavior = SaveBehavior.AlwaysOverwrite;
SPList listToConvert = spSite.RootWeb.Lists["Shared Documents"];
job.AddLibrary(listToConvert, listToConvert);
job.Start();
Console.WriteLine("Conversion job started");
ConversionJobStatus status = new ConversionJobStatus(wordAutomationServiceName,
    job.JobId, null);
Console.WriteLine("Number of documents in conversion job: {0}", status.Count);
while (true)
{
    Thread.Sleep(5000);
    status = new ConversionJobStatus(wordAutomationServiceName, job.JobId, null);
    if (status.Count == status.Succeeded + status.Failed)
    {
        Console.WriteLine("Completed, Successful: {0}, Failed: {1}",
            status.Succeeded, status.Failed);
        ReadOnlyCollection<ConversionItemInfo> failedItems =
            status.GetItems(ItemTypes.Failed);
        foreach (var failedItem in failedItems)
            Console.WriteLine("Failed item: Name:{0}", failedItem.InputFile);
        break;
    }
    Console.WriteLine("In progress, Successful: {0}, Failed: {1}", status.Succeeded,
        status.Failed);
}
Console.WriteLine("Starting conversion job")
Dim job As ConversionJob = New ConversionJob(wordAutomationServiceName)
job.UserToken = spSite.UserToken
job.Settings.UpdateFields = True
job.Settings.OutputFormat = SaveFormat.PDF
job.Settings.OutputSaveBehavior = SaveBehavior.AlwaysOverwrite
Dim listToConvert As SPList = spSite.RootWeb.Lists("Shared Documents")
job.AddLibrary(listToConvert, listToConvert)
job.Start()
Console.WriteLine("Conversion job started")
Dim status As ConversionJobStatus = _
    New ConversionJobStatus(wordAutomationServiceName, job.JobId, Nothing)
Console.WriteLine("Number of documents in conversion job: {0}", status.Count)
While True
    Thread.Sleep(5000)
    status = New ConversionJobStatus(wordAutomationServiceName, job.JobId, _
                                     Nothing)
    If status.Count = status.Succeeded + status.Failed Then
        Console.WriteLine("Completed, Successful: {0}, Failed: {1}", _
                          status.Succeeded, status.Failed)
        Dim failedItems As ReadOnlyCollection(Of ConversionItemInfo) = _
            status.GetItems(ItemTypes.Failed)
        For Each failedItem In failedItems
            Console.WriteLine("Failed item: Name:{0}", failedItem.InputFile)
        Next
        Exit While
    End If
    Console.WriteLine("In progress, Successful: {0}, Failed: {1}", _
                      status.Succeeded, status.Failed)
End While

Чтобы выполнить этот пример, создайте недопустимый документ и отправьте его в библиотеку документов. Чтобы создать недопустимый документ, просто переименуйте документ WordprocessingML, добавив к имени файла ".zip ". Затем удалите основную часть документа (с именем document.xml), которая находится в папке пакета Word. Переименуйте документ, удалив расширение .zip, чтобы вернуть обычное расширение .docx.

При выполнении этого примера будут получены выходные данные, подобные приведенным ниже.

Starting conversion job
Conversion job started
Number of documents in conversion job: 5
In progress, Successful: 0, Failed: 0
In progress, Successful: 0, Failed: 0
In progress, Successful: 4, Failed: 0
In progress, Successful: 4, Failed: 0
In progress, Successful: 4, Failed: 0
Completed, Successful: 4, Failed: 1
Failed item: Name:http://intranet.contoso.com/Shared%20Documents/IntentionallyInvalidDocument.docx

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

Удаление исходных файлов после преобразования

В некоторых ситуациях может понадобиться удалить исходные документы после преобразования. В следующем примере показывается, как это можно сделать.

Загрузить код (Возможно, на английском языке)

Console.WriteLine("Starting conversion job");
ConversionJob job = new ConversionJob(wordAutomationServiceName);
job.UserToken = spSite.UserToken;
job.Settings.UpdateFields = true;
job.Settings.OutputFormat = SaveFormat.PDF;
job.Settings.OutputSaveBehavior = SaveBehavior.AlwaysOverwrite;
SPFolder folderToConvert = spSite.RootWeb.GetFolder("Shared Documents");
job.AddFolder(folderToConvert, folderToConvert, false);
job.Start();
Console.WriteLine("Conversion job started");
ConversionJobStatus status = new ConversionJobStatus(wordAutomationServiceName,
    job.JobId, null);
Console.WriteLine("Number of documents in conversion job: {0}", status.Count);
while (true)
{
    Thread.Sleep(5000);
    status = new ConversionJobStatus(wordAutomationServiceName, job.JobId, null);
    if (status.Count == status.Succeeded + status.Failed)
    {
        Console.WriteLine("Completed, Successful: {0}, Failed: {1}",
            status.Succeeded, status.Failed);
        Console.WriteLine("Deleting only items that successfully converted");
        ReadOnlyCollection<ConversionItemInfo> convertedItems =
            status.GetItems(ItemTypes.Succeeded);
        foreach (var convertedItem in convertedItems)
        {
            Console.WriteLine("Deleting item: Name:{0}", convertedItem.InputFile);
            folderToConvert.Files.Delete(convertedItem.InputFile);
        }
        break;
    }
    Console.WriteLine("In progress, Successful: {0}, Failed: {1}",
        status.Succeeded, status.Failed);
}
Console.WriteLine("Starting conversion job")
Dim job As ConversionJob = New ConversionJob(wordAutomationServiceName)
job.UserToken = spSite.UserToken
job.Settings.UpdateFields = True
job.Settings.OutputFormat = SaveFormat.PDF
job.Settings.OutputSaveBehavior = SaveBehavior.AlwaysOverwrite
Dim folderToConvert As SPFolder = spSite.RootWeb.GetFolder("Shared Documents")
job.AddFolder(folderToConvert, folderToConvert, False)
job.Start()
Console.WriteLine("Conversion job started")
Dim status As ConversionJobStatus = _
    New ConversionJobStatus(wordAutomationServiceName, job.JobId, Nothing)
Console.WriteLine("Number of documents in conversion job: {0}", status.Count)
While True
    Thread.Sleep(5000)
    status = New ConversionJobStatus(wordAutomationServiceName, job.JobId, _
                                     Nothing)
    If status.Count = status.Succeeded + status.Failed Then
        Console.WriteLine("Completed, Successful: {0}, Failed: {1}", _
                          status.Succeeded, status.Failed)
        Console.WriteLine("Deleting only items that successfully converted")
        Dim convertedItems As ReadOnlyCollection(Of ConversionItemInfo) = _
            status.GetItems(ItemTypes.Succeeded)
        For Each convertedItem In convertedItems
            Console.WriteLine("Deleting item: Name:{0}", convertedItem.InputFile)
            folderToConvert.Files.Delete(convertedItem.InputFile)
        Next
        Exit While
    End If
    Console.WriteLine("In progress, Successful: {0}, Failed: {1}",
                      status.Succeeded, status.Failed)
End While

Интеграция с пакетом Open XML SDK

Преимущества использования компонента Word Automation Services становятся очевидными при его использовании в сочетании с Open XML SDK 2.0 для Microsoft Office. Можно программно изменить документ в библиотеке документов с помощью Open XML SDK 2.0 для Microsoft Office, а затем использовать Word Automation Services для выполнения одной из задач, которые трудно выполнить с помощью пакета Open XML SDK. Типичным примером является необходимость программного создания документа с последующим созданием или обновлением его оглавления. Рассмотрим следующий документ, содержащий оглавление.

Рис. 7. Документ с оглавлением

Документ с оглавлением

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

  1. Открывается сайт и получается документ Test.docx с помощью запроса Collaborative Application Markup Language (CAML).

  2. Открывается документ с помощью пакета SDK Open XML версии 2.0 и добавляется новый абзац со стилем Heading 1 в начало документа.

  3. Запускается задание преобразования, которое преобразует документ Test.docx в TestWithNewToc.docx. Ожидается завершение преобразования и сообщается о том, было ли оно успешным.

Загрузить код (Возможно, на английском языке)

Console.WriteLine("Querying for Test.docx");
SPList list = spSite.RootWeb.Lists["Shared Documents"];
SPQuery query = new SPQuery();
query.ViewFields = @"<FieldRef Name='FileLeafRef' />";
query.Query =
  @"<Where>
      <Eq>
        <FieldRef Name='FileLeafRef' />
        <Value Type='Text'>Test.docx</Value>
      </Eq>
    </Where>";
SPListItemCollection collection = list.GetItems(query);
if (collection.Count != 1)
{
    Console.WriteLine("Test.docx not found");
    Environment.Exit(0);
}
Console.WriteLine("Opening");
SPFile file = collection[0].File;
byte[] byteArray = file.OpenBinary();
using (MemoryStream memStr = new MemoryStream())
{
    memStr.Write(byteArray, 0, byteArray.Length);
    using (WordprocessingDocument wordDoc =
        WordprocessingDocument.Open(memStr, true))
    {
        Document document = wordDoc.MainDocumentPart.Document;
        Paragraph firstParagraph = document.Body.Elements<Paragraph>()
            .FirstOrDefault();
        if (firstParagraph != null)
        {
            Paragraph newParagraph = new Paragraph(
                new ParagraphProperties(
                    new ParagraphStyleId() { Val = "Heading1" }),
                new Run(
                    new Text("About the Author")));
            Paragraph aboutAuthorParagraph = new Paragraph(
                new Run(
                    new Text("Eric White")));
            firstParagraph.Parent.InsertBefore(newParagraph, firstParagraph);
            firstParagraph.Parent.InsertBefore(aboutAuthorParagraph,
                firstParagraph);
        }
    }
    Console.WriteLine("Saving");
    string linkFileName = file.Item["LinkFilename"] as string;
    file.ParentFolder.Files.Add(linkFileName, memStr, true);
}
Console.WriteLine("Starting conversion job");
ConversionJob job = new ConversionJob(wordAutomationServiceName);
job.UserToken = spSite.UserToken;
job.Settings.UpdateFields = true;
job.Settings.OutputFormat = SaveFormat.Document;
job.AddFile(siteUrl + "/Shared%20Documents/Test.docx",
    siteUrl + "/Shared%20Documents/TestWithNewToc.docx");
job.Start();
Console.WriteLine("After starting conversion job");
while (true)
{
    Thread.Sleep(5000);
    Console.WriteLine("Polling...");
    ConversionJobStatus status = new ConversionJobStatus(
        wordAutomationServiceName, job.JobId, null);
    if (status.Count == status.Succeeded + status.Failed)
    {
        Console.WriteLine("Completed, Successful: {0}, Failed: {1}",
            status.Succeeded, status.Failed);
        break;
    }
}
Console.WriteLine("Querying for Test.docx")
Dim list As SPList = spSite.RootWeb.Lists("Shared Documents")
Dim query As SPQuery = New SPQuery()
query.ViewFields = "<FieldRef Name='FileLeafRef' />"
query.Query = ( _
   <Where>
       <Eq>
           <FieldRef Name='FileLeafRef'/>
           <Value Type='Text'>Test.docx</Value>
       </Eq>
   </Where>).ToString()
Dim collection As SPListItemCollection = list.GetItems(query)
If collection.Count <> 1 Then
    Console.WriteLine("Test.docx not found")
    Environment.Exit(0)
End If
Console.WriteLine("Opening")
Dim file As SPFile = collection(0).File
Dim byteArray As Byte() = file.OpenBinary()
Using memStr As MemoryStream = New MemoryStream()
    memStr.Write(byteArray, 0, byteArray.Length)
    Using wordDoc As WordprocessingDocument = _
        WordprocessingDocument.Open(memStr, True)
        Dim document As Document = wordDoc.MainDocumentPart.Document
        Dim firstParagraph As Paragraph = _
            document.Body.Elements(Of Paragraph)().FirstOrDefault()
        If firstParagraph IsNot Nothing Then
            Dim newParagraph As Paragraph = New Paragraph( _
                New ParagraphProperties( _
                    New ParagraphStyleId() With {.Val = "Heading1"}), _
                New Run( _
                    New Text("About the Author")))
            Dim aboutAuthorParagraph As Paragraph = New Paragraph( _
                New Run( _
                    New Text("Eric White")))
            firstParagraph.Parent.InsertBefore(newParagraph, firstParagraph)
            firstParagraph.Parent.InsertBefore(aboutAuthorParagraph, _
                                               firstParagraph)
        End If
    End Using
    Console.WriteLine("Saving")
    Dim linkFileName As String = file.Item("LinkFilename")
    file.ParentFolder.Files.Add(linkFileName, memStr, True)
End Using
Console.WriteLine("Starting conversion job")
Dim job As ConversionJob = New ConversionJob(wordAutomationServiceName)
job.UserToken = spSite.UserToken
job.Settings.UpdateFields = True
job.Settings.OutputFormat = SaveFormat.Document
job.AddFile(siteUrl + "/Shared%20Documents/Test.docx", _
    siteUrl + "/Shared%20Documents/TestWithNewToc.docx")
job.Start()
Console.WriteLine("After starting conversion job")
While True
    Thread.Sleep(5000)
    Console.WriteLine("Polling...")
    Dim status As ConversionJobStatus = New ConversionJobStatus( _
        wordAutomationServiceName, job.JobId, Nothing)
    If status.Count = status.Succeeded + status.Failed Then
        Console.WriteLine("Completed, Successful: {0}, Failed: {1}", _
                          status.Succeeded, status.Failed)
        Exit While
    End If
End While

После выполнения этого примера с документом, аналогичным документу, который использовался ранее в этом разделе, создается новый документ, показанный на рис. 8.

Рис. 8. Документ с обновленным оглавлением

Документ с обновленным оглавлением

Заключение

Пакет SDK Open XML версии 2.0 — это мощное средство для построения систем обработки документов и создания документов на стороне сервера. Однако существует несколько сложных аспектов обработки документов, таких как преобразования документов, обновление полей и оглавления и т. д. Компонент Word Automation Services заполняет эту нишу высокопроизводительным решением, которое может масштабироваться в соответствии с потребностями пользователя. Использование пакета SDK Open XML версии 2.0 в сочетании с Word Automation Services позволяет выполнять многие сценарии, выполнение которых затруднительно при использовании только пакета SDK Open XML версии 2.0.

Дополнительные материалы

Щелкните, чтобы скопировать код  Загрузить код (Возможно, на английском языке)