Office task pane app: how to get the whole documen

2019-08-10 08:29发布

问题:

I'm developing an Office Task Pane app that needs to access the whole document. I know there is an API getFileAsync() https://msdn.microsoft.com/en-us/library/office/jj220084.aspx

Office.context.document.getFileAsync(fileType [, options], callback);

However,the fileType can only be three values: compressed, pdf, text.

compressed

Returns the entire document (.pptx or .docx) in Office Open XML (OOXML) format as a byte array.

pdf

Returns the entire document in PDF format as a byte array.

text

Returns only the text of the document as a string. (Word only)

When it is compressed, the returned value is a byte array. How can I get an OOXml string?

Or is there an API to select all content in a document so that I can use the getSelectedDataAsync() API?

回答1:

In case someone finds this thread, I managed to solve this using zip.js.

var dataByteArray = [];

function getDocumentAsOoxml() {
    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
            };
            getSlice(state);
        }
    });
}

function getSlice(state) {
    state.file.getSliceAsync(state.counter, function (result) {
        if (result.status == Office.AsyncResultStatus.Succeeded) {
            readSlice(result.value, state);
        }
    });
}

function readSlice(slice, state) {
    var data = slice.data;
    // If the slice contains data, create an HTTP request.
    if (data) {
        dataByteArray = dataByteArray.concat(data);
        state.counter++;
        if (state.counter < state.sliceCount) {
            getSlice(state);
        } else {
            closeFile(state);
        }
    }
}

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

    // convert from byte array to blob that can bre read by zip.js
    var byteArray = new Uint8Array(dataByteArray);
    var blob = new Blob([byteArray]);

    // Load zip.js library
    $.getScript("/Scripts/zip.js/zip.js", function () {
        zip.workerScriptsPath = "/Scripts/zip.js/";
        // use a BlobReader to read the zip from a Blob object
        zip.createReader(new zip.BlobReader(blob), function (reader) {
            // get all entries from the zip file
            reader.getEntries(function (entries) {
                if (entries.length > 0) {
                    for (var i = 0; i < entries.length; i++) {
                        var entry = entries[i];
                        // find the file you are looking for
                        if (entry.filename == 'word/document.xml') {
                            entry.getData(new zip.TextWriter(), function (text) {

                                // text contains the entry data as a String
                                doSomethingWithText(text);

                                // close the zip reader
                                reader.close(function () {
                                    // onclose callback
                                });
                            }, function (current, total) {
                                // onprogress callback
                            });
                            break;
                        }
                    }
                }
            });
        }, function (error) {
            // onerror callback
        });
    });
}

Hopefully there will be a easier way in the future.



回答2:

this is a little late.

I've been working with Task Pane apps lately and, as it turns out, OOXML is natively compressed (unless I'm grossly mistaken).

My best advice would be to figure out the encoding that the string is encoded at, and decode with that encoding type. I'm willing to bet that it's UTF-8.