Получение всего документа из надстройки для PowerPoint или Word

Вы можете создать надстройку Office для отправки или публикации Word документа или презентации PowerPoint в удаленном расположении. В этой статье показано, как создать простую надстройку области задач для PowerPoint или Word, которая получает всю презентацию или документ в виде объекта данных и отправляет эти данные на веб-сервер через HTTP-запрос.

Необходимые условия создания надстройки для PowerPoint или Word

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

  • В общей сетевой папке или на веб-сервере вам потребуются следующие файлы.

    • HTML-файл (GetDoc_App.html), содержащий пользовательский интерфейс, а также ссылки на файлы JavaScript (включая файлы Office.js и .js приложения) и каскадные таблицы стилей (CSS).

    • Файл JavaScript (GetDoc_App.js), содержащий логику программирования надстройки.

    • CSS-файл (Program.css), содержащий стили и форматирование надстройки.

  • XML-файл манифеста (GetDoc_App.xml) для надстройки, доступный в общей сетевой папке или каталоге надстроек. Файл манифеста должен указывать на расположение HTML-файла, упомянутого ранее.

Кроме того, можно создать надстройку для приложения Office, используя один из следующих вариантов. Вам не придется создавать новые файлы, так как эквивалент каждого обязательного файла будет доступен для обновления. Например, параметры генератора Yeoman включают ./src/taskpane/taskpane.html, ./src/taskpane/taskpane.js, ./src/taskpane/taskpane.css и ./manifest.xml.

Основные понятия, позволяющие создавать надстройки области задач

Прежде чем приступать к разработке этой надстройки для PowerPoint или Word, ознакомьтесь с созданием Надстройки Office и работой с HTTP-запросами. В этой статье не рассматривается декодирование текста в кодировке Base64 из HTTP-запроса на веб-сервере.

Создание манифеста надстройки

XML-файл манифеста надстройки Office содержит важную информацию о надстройке: какие приложения могут ее размещать, расположение HTML-файла, название и описание надстройки, а также многие другие характеристики.

  1. В текстовом редакторе добавьте следующий код в файл манифеста.

    <?xml version="1.0" encoding="utf-8" ?>
    <OfficeApp xmlns="http://schemas.microsoft.com/office/appforoffice/1.1"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:type="TaskPaneApp">
        <Id>[Replace_With_Your_GUID]</Id>
        <Version>1.0</Version>
        <ProviderName>[Provider Name]</ProviderName>
        <DefaultLocale>EN-US</DefaultLocale>
        <DisplayName DefaultValue="Get Doc add-in" />
        <Description DefaultValue="My get PowerPoint or Word document add-in." />
        <IconUrl DefaultValue="http://officeimg.vo.msecnd.net/_layouts/images/general/office_logo.jpg" />
        <SupportUrl DefaultValue="[Insert the URL of a page that provides support information for the app]" />
        <Hosts>
            <Host Name="Document" />
            <Host Name="Presentation" />
        </Hosts>
        <DefaultSettings>
            <SourceLocation DefaultValue="[Network location of app]/GetDoc_App.html" />
        </DefaultSettings>
        <Permissions>ReadWriteDocument</Permissions>
    </OfficeApp>
    
  2. Сохраните файл какGetDoc_App.xml с помощью кодировки UTF-8 в сетевом расположении или каталоге надстроек.

Создание пользовательского интерфейса надстройки

Для пользовательского интерфейса надстройки можно использовать HTML-код, написанный непосредственно в GetDoc_App.html файл. Логика программирования и функциональные возможности надстройки должны содержаться в файле JavaScript (например, GetDoc_App.js).

Используйте следующую процедуру для создания простого пользовательского интерфейса надстройки, содержащего заголовок и одну кнопку.

  1. В новом файле в текстовом редакторе добавьте HTML-код для выбранного приложения Office.

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="UTF-8" />
            <meta http-equiv="X-UA-Compatible" content="IE=Edge"/>
            <title>Publish presentation</title>
            <link rel="stylesheet" type="text/css" href="Program.css" />
            <script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-1.9.0.min.js" type="text/javascript"></script>
            <script src="https://appsforoffice.microsoft.com/lib/1/hosted/office.js" type="text/javascript"></script>
            <script src="GetDoc_App.js"></script>
        </head>
        <body>
            <form>
                <h1>Publish presentation</h1>
                <br />
                <div><input id='submit' type="button" value="Submit" /></div>
                <br />
                <div><h2>Status</h2>
                    <div id="status"></div>
                </div>
            </form>
        </body>
    </html>
    
  2. Сохраните файл какGetDoc_App.html с помощью кодировки UTF-8 в сетевом расположении или на веб-сервере.

    Примечание.

    Убедитесь, что теги головы надстройки содержат тег скрипта с допустимой ссылкой на файл Office.js.

  3. Мы будем использовать некоторые CSS, чтобы придать надстройке простой, но современный и профессиональный внешний вид. Используйте CSS для определения стиля надстройки.

    В новый файл, используя текстовый редактор, добавьте следующий CSS-код.

    body
    {
        font-family: "Segoe UI Light","Segoe UI",Tahoma,sans-serif;
    }
    h1,h2
    {
        text-decoration-color:#4ec724;
    }
    input [type="submit"], input[type="button"]
    {
        height:24px;
        padding-left:1em;
        padding-right:1em;
        background-color:white;
        border:1px solid grey;
        border-color: #dedfe0 #b9b9b9 #b9b9b9 #dedfe0;
        cursor:pointer;
    }
    
  4. Сохраните файл как Program.css , используя кодировку UTF-8 в сетевом расположении или на веб-сервере, где находится файлGetDoc_App.html .

Добавление JavaScript для получения документа

В коде надстройки обработчик события Office.initialize добавляет обработчик события нажатия кнопки Submit (Отправить), расположенной на форме, и информирует пользователя о том, что надстройка готова.

В следующем примере кода показан обработчик событий для Office.initialize события вместе со вспомогательной функцией , updateStatusдля записи в раздел состояния.

// The initialize or onReady function is required for all add-ins.
Office.initialize = function (reason) {

    // Checks for the DOM to load using the jQuery ready method.
    $(document).ready(function () {

        // Run sendFile when Submit is clicked.
        $('#submit').on("click", function () {
            sendFile();
        });

        // Update status.
        updateStatus("Ready to send file.");
    });
}

// Create a function for writing to the status div.
function updateStatus(message) {
    var statusInfo = $('#status');
    statusInfo[0].innerHTML += message + "<br/>";
}

При нажатии кнопки Отправить в пользовательском интерфейсе надстройка вызывает sendFile функцию, которая содержит вызов метода Document.getFileAsync . Метод getFileAsync использует асинхронный шаблон, аналогичный другим методам в API JavaScript для Office. Он имеет один обязательный параметр, fileType и два необязательных параметра, параметры и обратный вызов.

Параметр fileType ожидает одну из трех констант из перечисления FileType : Office.FileType.Compressed ("compressed"), Office.FileType.PDF ("pdf") или Office.FileType.Text ("text"). Поддержка текущего типа файлов для каждой платформы указана в разделе Document.getFileType . При передаче значения Compressed для параметра getFileAsyncfileType метод возвращает текущий документ в виде файла презентации PowerPoint (*.pptx) или файла документа Word (*.docx) путем создания временной копии файла на локальном компьютере.

Метод getFileAsync возвращает ссылку на файл в виде объекта File . Объект File предоставляет следующие четыре элемента.

Свойство size возвращает количество байтов в файле. Возвращает sliceCount количество объектов Slice (рассматривается далее в этой статье) в файле.

Используйте следующий код, чтобы получить текущий документ PowerPoint или Word в качестве File объекта с помощью Document.getFileAsync метода , а затем выполнить вызов локально определенной getSlice функции. Обратите внимание, что File объект, переменная счетчика и общее количество срезов в файле передаются вместе при вызове в getSlice анонимном объекте.

// Get all of the content from a PowerPoint or Word document in 100-KB chunks of text.
function sendFile() {
    Office.context.document.getFileAsync("compressed",
        { sliceSize: 100000 },
        function (result) {

            if (result.status === Office.AsyncResultStatus.Succeeded) {

                // Get the File object from the result.
                var myFile = result.value;
                var state = {
                    file: myFile,
                    counter: 0,
                    sliceCount: myFile.sliceCount
                };

                updateStatus("Getting file of " + myFile.size + " bytes");
                getSlice(state);
            } else {
                updateStatus(result.status);
            }
        });
}

Локальная функция getSlice выполняет вызов File.getSliceAsync метода для получения среза из File объекта . Метод getSliceAsync возвращает Slice объект из коллекции среза. Метод имеет два обязательных параметра: sliceIndex и callback. Параметр sliceIndex принимает целое число в качестве индексатора в коллекцию срезов. Как и другие методы в API JavaScript для Office, getSliceAsync метод также принимает функцию обратного вызова в качестве параметра для обработки результатов вызова метода.

Объект Slice предоставляет доступ к данным, содержащимся в файле. Если в параметре getFileAsyncoptions метода не указано иное, Slice размер объекта составляет 4 МБ. Объект Slice предоставляет три свойства: размер, данные и индекс. Свойство size получает размер среза (в байтах). Свойство index получает целое число, представляющее положение среза в коллекции срезов.

// Get a slice from the file and then call sendSlice.
function getSlice(state) {
    state.file.getSliceAsync(state.counter, function (result) {
        if (result.status == Office.AsyncResultStatus.Succeeded) {
            updateStatus("Sending piece " + (state.counter + 1) + " of " + state.sliceCount);
            sendSlice(result.value, state);
        } else {
            updateStatus(result.status);
        }
    });
}

Свойство Slice.data возвращает необработанные данные файла в виде массива байтов. Если данные имеют текстовый формат (то есть XML или обычного текста), фрагмент содержит необработанный текст. Если передать office.FileType.Compressed для параметра Document.getFileAsyncfileType объекта , срез содержит двоичные данные файла в виде массива байтов. В случае файла PowerPoint или Word фрагменты содержат массивы байтов.

Чтобы преобразовать данные массива байтов в строку с кодировкой Base64, вам необходимо применить собственную функцию (или использовать доступную библиотеку). Сведения о кодировке Base64 с помощью JavaScript см. в разделе Кодировка и декодирование Base64.

После преобразования данных в Base64 их можно передать на веб-сервер несколькими способами, включая текст HTTP-запроса POST.

Добавьте следующий код для отправки фрагмента веб-службе.

Примечание.

Этот код отправляет файл PowerPoint или Word на веб-сервер в нескольких срезах. Веб-сервер или служба должны добавить каждый отдельный срез в один файл, а затем сохранить его в виде файла .pptx или .docx, прежде чем вы сможете выполнять с ним какие-либо операции.

function sendSlice(slice, state) {
    var data = slice.data;

    // If the slice contains data, create an HTTP request.
    if (data) {

        // Encode the slice data, a byte array, as a Base64 string.
        // NOTE: The implementation of myEncodeBase64(input) function isn't
        // included with this example. For information about Base64 encoding with
        // JavaScript, see https://developer.mozilla.org/docs/Web/JavaScript/Base64_encoding_and_decoding.
        var fileData = myEncodeBase64(data);

        // Create a new HTTP request. You need to send the request
        // to a webpage that can receive a post.
        var request = new XMLHttpRequest();

        // Create a handler function to update the status
        // when the request has been sent.
        request.onreadystatechange = function () {
            if (request.readyState == 4) {

                updateStatus("Sent " + slice.size + " bytes.");
                state.counter++;

                if (state.counter < state.sliceCount) {
                    getSlice(state);
                } else {
                    closeFile(state);
                }
            }
        }

        request.open("POST", "[Your receiving page or service]");
        request.setRequestHeader("Slice-Number", slice.index);

        // Send the file as the body of an HTTP POST
        // request to the web server.
        request.send(fileData);
    }
}

Как следует из названия, File.closeAsync метод закрывает подключение к документу и освобождает ресурсы. Хотя мусор песочницы надстроек Office собирает область ссылки на файлы, по-прежнему рекомендуется явно закрывать файлы после выполнения кода с ними. Метод closeAsync имеет один параметр обратного вызова, который указывает функцию для вызова после завершения вызова.

function closeFile(state) {
    // Close the file when you're done with it.
    state.file.closeAsync(function (result) {

        // If the result returns as a success, the
        // file has been successfully closed.
        if (result.status === Office.AsyncResultStatus.Succeeded) {
            updateStatus("File closed.");
        } else {
            updateStatus("File couldn't be closed.");
        }
    });
}

Окончательный файл JavaScript может выглядеть следующим образом:

/*
 * Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
 * See LICENSE in the project root for license information.
 */

// The initialize or onReady function is required for all add-ins.
Office.initialize = function (reason) {

    // Checks for the DOM to load using the jQuery ready method.
    $(document).ready(function () {

        // Run sendFile when Submit is clicked.
        $('#submit').on("click", function () {
            sendFile();
        });

        // Update status.
        updateStatus("Ready to send file.");
    });
}

// Create a function for writing to the status div.
function updateStatus(message) {
    var statusInfo = $('#status');
    statusInfo[0].innerHTML += message + "<br/>";
}

// Get all of the content from a PowerPoint or Word document in 100-KB chunks of text.
function sendFile() {
    Office.context.document.getFileAsync("compressed",
        { sliceSize: 100000 },
        function (result) {

            if (result.status === Office.AsyncResultStatus.Succeeded) {

                // Get the File object from the result.
                var myFile = result.value;
                var state = {
                    file: myFile,
                    counter: 0,
                    sliceCount: myFile.sliceCount
                };

                updateStatus("Getting file of " + myFile.size + " bytes");
                getSlice(state);
            } else {
                updateStatus(result.status);
            }
        });
}

// Get a slice from the file and then call sendSlice.
function getSlice(state) {
    state.file.getSliceAsync(state.counter, function (result) {
        if (result.status == Office.AsyncResultStatus.Succeeded) {
            updateStatus("Sending piece " + (state.counter + 1) + " of " + state.sliceCount);
            sendSlice(result.value, state);
        } else {
            updateStatus(result.status);
        }
    });
}

function sendSlice(slice, state) {
    var data = slice.data;

    // If the slice contains data, create an HTTP request.
    if (data) {

        // Encode the slice data, a byte array, as a Base64 string.
        // NOTE: The implementation of myEncodeBase64(input) function isn't
        // included with this example. For information about Base64 encoding with
        // JavaScript, see https://developer.mozilla.org/docs/Web/JavaScript/Base64_encoding_and_decoding.
        var fileData = myEncodeBase64(data);

        // Create a new HTTP request. You need to send the request
        // to a webpage that can receive a post.
        var request = new XMLHttpRequest();

        // Create a handler function to update the status
        // when the request has been sent.
        request.onreadystatechange = function () {
            if (request.readyState == 4) {

                updateStatus("Sent " + slice.size + " bytes.");
                state.counter++;

                if (state.counter < state.sliceCount) {
                    getSlice(state);
                } else {
                    closeFile(state);
                }
            }
        }

        request.open("POST", "[Your receiving page or service]");
        request.setRequestHeader("Slice-Number", slice.index);

        // Send the file as the body of an HTTP POST
        // request to the web server.
        request.send(fileData);
    }
}

function closeFile(state) {
    // Close the file when you're done with it.
    state.file.closeAsync(function (result) {

        // If the result returns as a success, the
        // file has been successfully closed.
        if (result.status === Office.AsyncResultStatus.Succeeded) {
            updateStatus("File closed.");
        } else {
            updateStatus("File couldn't be closed.");
        }
    });
}