Word addin不适用于在线单词

时间:2017-05-04 14:42:27

标签: javascript ms-word office-js

开发一个Word插件你可以选择一个docx文件并将其插入到新的空白文档中 - 这是一个templateHandler类型。

每个docx文件都有一个包含多个RTF的页脚 -  contentControlers。在加载文档(insertFileFromBase64)之前,代码中有一个thisDocument.body.clear()。

在本地wordclient中加载不同的文档没有问题,但是在word在线我收到关于body.clear()的错误: Word Online

不支持该操作

编辑:调整代码,使页眉和页脚与docx文件分开,并插入insertOoxml。打开插件时,它们会以初始方式加载。 body.clear()不再是问题了。

页脚中还有contenControllers。他们在网上版本中退出了。

编辑:当页脚与docx分开加载时,它们现在可见。 现在只有addin的一大问题是 - 当你打开插件时,你只能在文档的一行编辑。如果你点击文字它就会变得不可见。如果您通过从插件加载一个docx文件来更改另一个docx文件,则该文本在正文中将不可见。

我正在使用office.js 1.1我正在运行的office365是开发人员的评估版本:V 1609(Build 7369.2127)

这是main.js的内容:

 console.log("mains.js is present! ");

(function () {
"use strict";

// Initialize
Office.initialize = function (reason) {
    $(document).ready(function () {
        app.initialize();
        // Use this to check whether the new API is supported in the Word client.
        if (Office.context.requirements.isSetSupported("WordApi", "1.1")) {

            console.log('Den här koden är optimerad för Word 2016.');

            // Load the doc names from the service into the UI. 
            getDocNames();
            console.log("Getting Documents");



            addFooter(); 
            //console.log("Adding Footer");

            addHeader();
            //console.log("Adding Header");

            //getDataFromSelection();
            //getAllContentControls();

            // Setup the event handlers for UI.
            $('#selectDocument').change(selectDocumentHandler);
            $('#changeContent').click(contentControlHandler); //TODO:validateFields
            $('#clearContent').click(clearContent);
            $('#get-data-from-selection').click(getDataFromSelection);

        }
        else {
            console.log('Du måste använda Word 2016 för att det här ska fungera.');
        }
    });
};
function clearContent() {
    $('input[type=text]').val('');
}

        // Function for getting header and footer

function getHeaderFooter(fileName) {

    var myOOXMLRequest = new XMLHttpRequest();

    var myXML;

    myOOXMLRequest.open('GET', fileName, false);

    myOOXMLRequest.send();

    if (myOOXMLRequest.status === 200) {

        myXML = myOOXMLRequest.responseText;
        return myXML;
    }
Office.context.document.setSelectedDataAsync(myXML, { coercionType: 'ooxml' });
    //return "";
}

/* Word JS functions */

function addHeader() {
    // Run a batch operation against the Word object model.
    Word.run(function (context) {

        // Create a proxy sectionsCollection object.
        var sections = context.document.sections;
        //mySections.body.clear();
        // Queue a commmand to load the sections.
        context.load(sections, 'body/style');

        return context.sync().then(function () {

            var header = sections.items[0].getHeader("primary");
            //header.clear();
            var templateHeader = getHeaderFooter('/xml/simrisHeader.xml');

            header.insertOoxml(templateHeader, Word.InsertLocation.replace);

            return context.sync().then(function () {
                console.log("Added a header to the first section.");
            });
        });
    })
        .catch(function (error) {
            console.log('Error: ' + JSON.stringify(error));
            if (error instanceof OfficeExtension.Error) {
                console.log('Debug info: ' + JSON.stringify(error.debugInfo));
            }
        });
}

function addFooter() {
    Word.run(function (context) {

        var sections = context.document.sections;
        //context.document.clear();
        context.load(sections, 'body/style');
        return context.sync().then(function () {

            var footer = sections.items[0].getFooter("primary");
            //context.footer.clear();

            var templateFooter = getHeaderFooter('/xml/simrisFooter.xml');

            footer.insertOoxml(templateFooter, Word.InsertLocation.replace);
            // var contentControls = footer.contentControls;
            //getAllContentControls();

            return context.sync().then(function () {
                console.log("Added a footer to the first section.");
            });
        })
            .catch(function (error) {
                console.log('Error: ' + JSON.stringify(error));
                if (error instanceof OfficeExtension.Error) {
                    console.log('Debug info: ' + JSON.stringify(error.debugInfo))
                }
            });

    });
}

    function displayContents(myBase64) {
        Word.run(function (context) {

            var thisDocument = context.document;

            thisDocument.body.clear();

            var mySelection = thisDocument.getSelection();

            mySelection.insertFileFromBase64(myBase64, "replace");

            return context.sync()
                .then(function () 
                    getAllContentControls();          
                });
        })
            .catch(function (error) {
                app.showNotification('Error: ' + JSON.stringify(error));
                if (error instanceof OfficeExtension.Error) {
                    app.showNotification('Debug info: ' + JSON.stringify(error.debugInfo));
                }
            });
    }

// Using the Word JS API. Gets all of the content controls that are in the loaded document. 
function getAllContentControls() {
    Word.run(function (context) {

        var thisDocument = context.document;

        var contentControls = thisDocument.contentControls;

        contentControls.load('tag, title');

        return context.sync(contentControls).then(function () {

            var uniqueFields = removeDuplicateContentControls(contentControls);

            // Create HTML inputfields based on the content controls.
            createFields(uniqueFields);

        })
    })
        .catch(function (error) {
            app.showNotification('Error: ' + JSON.stringify(error));
            if (error instanceof OfficeExtension.Error) {
                app.showNotification('Debug info: ' + JSON.stringify(error.debugInfo));
            }
        });
}

// Using the Word JS API. Set the values from the INPUT elements into the associated
// content controls to make the doc. 
function contentControlHandler() {

    var entryFields = document.getElementById("entryFields").querySelectorAll("input");

    // Loading the contentcontrols again.
    Word.run(function (context) {

        // Create a proxy object for the document.
        var thisDocument = context.document;

        // Create a proxy object for the contentcontrol collection in the document.
        var contentControls = thisDocument.contentControls;

        // Queue a command to load the contentcontrols collection with the tag and title properties.
        contentControls.load('tag, title');

        return context.sync()
            .then(function () {

                var i, j;

                // Map each input element to the associated content control.
                for (i = 0; i < entryFields.length; i++) {
                    for (j = 0; j < contentControls.items.length; j++) {
                        // Matching content control tag with the tag set as the id on each input element.
                        if (contentControls.items[j].tag === entryFields[i].id && entryFields[i].value != 0) {
                            contentControls.items[j].insertText(entryFields[i].value.trim(), Word.InsertLocation.replace)
                        }
                    }
                }
            })
            .then(context.sync);

    })
        .catch(function (error) {
            app.showNotification('Error: ' + JSON.stringify(error));  //console.log
            if (error instanceof OfficeExtension.Error) {
                app.showNotification('Debug info: ' + JSON.stringify(error.debugInfo)); //console.log
            }
        });
}

// Handles the doc selection in the add-in UI. Results in a call to the service to get
// a docx file that contains a doc. The doc gets displayed in the Word UI.
function selectDocumentHandler() {

    // Form the URL to get the docx file. Need to remove the host information by slicing
    // off the host information beginning at ?_host_Info.
    var fileName = this.value;
    var currentUrl = location.href.slice(0, location.href.indexOf('?'));
    var getFileUrl = currentUrl + 'getfile?filename=' + fileName;

    // Call the helper to get the selected file then insert the file into Word.
    httpGetAsync(getFileUrl, function (response) {
        displayContents(response);
    });
}

/* UI functions */

function getDocNames() {

    // Form the URL to get the docx file list. Need to remove the host information by slicing
    // off the host information beginning at ?_host_Info.
    var currentUrl = location.href.slice(0, location.href.indexOf('?'));
    var getFileNamesUrl = currentUrl + 'getfilenames';

    // Call the helper to get the file list and then create the dropdown listbox from the results.
    httpGetAsync(getFileNamesUrl, function (rawResponse) {

        // Helper that processes the response so that we have an array of filenames.
        var response = processResponse(rawResponse);

        // Get a handle on the empty drop down list box.
        var select = document.getElementById("selectDocument");

        // Populate the drop down listbox.       
        for (var i = 0; i < response.length; i++) {
            var opt = response[i];
            var el = document.createElement("option");
            el.text = opt;
            el.value = opt;
            select.appendChild(el);
        };

        //$(".ms-Dropdown").Dropdown();
    });
}

// Creates HTML inputfields
function createFields(uniqueFields) {

    // Get the DIV where we will add out INPUT-controls.
    var entryFields = document.getElementById("entryFields");

    // Clear the contents in case it has already been populated with INPUT controls.
    while (entryFields.hasChildNodes()) {
        entryFields.removeChild(entryFields.lastChild);
    }

    // Create a unique INPUT element for each unique contentcontrol-tag.
    for (var i = 0; i < uniqueFields.length; i++) {

        var newLabel = document.createElement("label");
        newLabel.appendChild(document.createTextNode(uniqueFields[i].title + ': '));
        document.getElementById('entryFields').appendChild(newLabel);

        var input = document.createElement("input");

        newLabel.className = 'ms-label';

        input.type = "text";

        input.id = uniqueFields[i].tag;

        input.className = 'ms-TextField-field';

        entryFields.appendChild(input); //, input.value

        entryFields.appendChild(document.createElement("br"));

    }

}

// Get data from AAD and displays user information
function getDataFromSelection() {
    var baseEndpoint = 'https://graph.microsoft.com';
    var authContext = new AuthenticationContext(config);

    Office.context.document.getSelectedDataAsync(Office.CoercionType.Text,
        function (result) {
            if (result.status === Office.AsyncResultStatus.Succeeded) {

                authContext.acquireToken(baseEndpoint, function (error, token) {
                    if (error || !token) {
                        app.showNotification("Ingen token: ", "Du får logga in igen."); // + error
                    }
                    var email = authContext._user.userName;
                    var url = "https://graph.microsoft.com/v1.0/" + config.tenant + "/users/" + email;

                    var html = "<ul>";
                    $.ajax({
                        beforeSend: function (request) {
                            request.setRequestHeader("Accept", "application/json");
                        },
                        type: "GET",
                        url: url,
                        dataType: "json",
                        headers: {
                            'Authorization': 'Bearer ' + token,
                        },
                        success: function (response) {
                            console.log('Hämtar inehåll och populerar Kontroller!');
                            //utilize your callback function
                            postDataToContentControlers(response);
                        }
                    }).done(function (response) {
                        html += getPropertyHtml("Namn", response.displayName);
                        html += getPropertyHtml("Titel", response.jobTitle);
                        html += getPropertyHtml("Avdelning", response.officeLocation);
                        html += getPropertyHtml("Telefon jobb", response.businessPhones);
                        $("#results").html(html);
                    }).fail(function (response) {
                        app.showNotification('Inloggningen slutade att fungera!', 'Du får logga ut och prova att logga in igen'); //response.responseText
                    });
                });
            } else {
                app.showNotification('Error:', 'Något gick fel. Du får logga in igen.'); //result.error.message
            }
        }
    );
}

function getPropertyHtml(key, value) {
    return "<li><strong>" + key + "</strong> : " + value + "</li>";
}

function postDataToContentControlers(response) {
    // Loading the contentcontrols again.
    Word.run(function (context) {

        // Create a proxy object for the document.
        var thisDocument = context.document;

        // Create a proxy object for the contentcontrol collection in the document.
        var contentControls = thisDocument.contentControls;

        // Queue a command to load the contentcontrols collection with the tag and title properties.
        contentControls.load('tag, title');

        return context.sync()
            .then(function () {

                var i, j;

                var responseArrayKey = Object.keys(response).map(function (v) { return v });

                // Map each data element to the associated content control.
                for (i = 0; i < responseArrayKey.length; i++) {

                    for (j = 0; j < contentControls.items.length; j++) {

                        console.log("responseArrayKey:  ", responseArrayKey);
                        // Matching content control tag with the index of each responseArray.
                        if (contentControls.items[j].tag === responseArrayKey[i]) {

                            var responseArrayValue = Object.keys(response).map(function (k) { return response[k] });

                            contentControls.items[j].insertText(responseArrayValue[i], Word.InsertLocation.replace)

                        }
                    }
                }
            })
            .then(context.sync);
    })
        .catch(function (error) {
            app.showNotification('Error: ' + JSON.stringify(error));  //console.log
            if (error instanceof OfficeExtension.Error) {
                app.showNotification('Debug info: ' + JSON.stringify(error.debugInfo)); //console.log
            }
        });
}

/* Helper functions */

// Helper that deduplicates the set of contentcontrols.
function removeDuplicateContentControls(contentControls) {

    var i,
        len = contentControls.items.length,
        uniqueFields = [],
        currentContentControl = {};

    for (i = 0; i < len; i++) {
        currentContentControl[contentControls.items[i].tag] = contentControls.items[i].title;
    }

    for (i in currentContentControl) {

        var obj = {
            tag: i,
            title: currentContentControl[i]
        };

        uniqueFields.push(obj);
    }

    return uniqueFields;
}

// Helper for calls to the service. 
function httpGetAsync(theUrl, callback) {
    var request = new XMLHttpRequest();
    request.open("GET", theUrl, false);
    request.onreadystatechange = function () {
        if (request.readyState === 4 && request.status === 200)
            callback(request.responseText);
    }
    request.send(null);
}

    // Function for getting the HeaderTemplate

    function getHeaderTemplate(fileName) {

    var myOOXMLRequest = new XMLHttpRequest();

    var myXML;

    myOOXMLRequest.open('GET', fileName, false);

    myOOXMLRequest.send();

    if (myOOXMLRequest.status === 200) {

        myXML = myOOXMLRequest.responseText;
        return myXML;
    }

    return "";
}

// Helper that processes file names into an array. 
function processResponse(rawResponse) {

    // Remove quotes.
    rawResponse = rawResponse.replace(/"/g, "");

    // Remove opening brackets.
    rawResponse = rawResponse.replace("[", "");

    // Remove closing brackets.
    rawResponse = rawResponse.replace("]", "");

    // Return an array of file names.
    return rawResponse.split(',');
}

// Helper function for treating errors
function errorHandler(error) {
    showNotification(error, JSON.stringify(error.debugInfo));
    console.log("Error: " + error);
    if (error instanceof OfficeExtension.Error) {
        console.log("Debug info: " + JSON.stringify(error.debugInfo));
    }
}

function validateFields() {
    //TODO: validating fields
    console.log('Validating fields');
}

})();

index.html的内容

manifest的内容

使用nodejs

处理文档

希望有人能解决问题。谢谢=)

1 个答案:

答案 0 :(得分:0)

感谢您提供docx文件。

不支持正文中内容控件之前的“Tab”,这会使内容控件不受支持。因此,不允许使用body.clear(),因为内部没有支持。

我建议你删除本地wordclient中的'Tab'并在线上传docx文件。 Body.clear()会以这种方式运作良好。

PS:段落中心可用于帮助调整内容控制中心。