3

I am getting a very strange issue whereby when I try to extract the word document as a compressed file for processing in my MS Word Task Pane MVC app the third time, it will blow up.

Here is the code:

Office.context.document.getFileAsync(Office.FileType.Compressed, function (result) {
if (result.status == "succeeded") {
    var file = result.value;

    file.getSliceAsync(0, function (resultSlice) {
        //DO SOMETHING
    });
} else {
    //TODO: Service fault handling?
}
});

The error code that comes up is 5001. I am not sure how to fix this.

Please let me know if you have any thoughts on this.

Additional Details:

enter image description here

pnuts
  • 58,317
  • 11
  • 87
  • 139
Benjamin Wong
  • 599
  • 1
  • 8
  • 21

4 Answers4

6

From MSDN:

No more than two documents are allowed to be in memory; otherwise the getFileAsync operation will fail. Use the File.closeAsync method to close the file when you are finished working with it.

Make sure you call File.closeAsync before you read the file again - that could explain the issue you are seeing.

More at: https://msdn.microsoft.com/en-us/library/office/jj715284.aspx

Alex Sanséau
  • 8,250
  • 5
  • 20
  • 25
2

I have an example about how to use this API correctly. Actually the current example in the MSDN is not very correct. This code is tested in Word.

// Usually we encode the data in base64 format before sending it to server.
function encodeBase64(docData) {
    var s = "";
    for (var i = 0; i < docData.length; i++)
        s += String.fromCharCode(docData[i]);
    return window.btoa(s);
}

// Call getFileAsync() to start the retrieving file process.
function getFileAsyncInternal() {
    Office.context.document.getFileAsync("compressed", { sliceSize: 10240 }, function (asyncResult) {
        if (asyncResult.status == Office.AsyncResultStatus.Failed) {
            document.getElementById("log").textContent = JSON.stringify(asyncResult);
        }
        else {
            getAllSlices(asyncResult.value);
        }
    });
}

// Get all the slices of file from the host after "getFileAsync" is done.
function getAllSlices(file) {
    var sliceCount = file.sliceCount;
    var sliceIndex = 0;
    var docdata = [];
    var getSlice = function () {
        file.getSliceAsync(sliceIndex, function (asyncResult) {
            if (asyncResult.status == "succeeded") {
                docdata = docdata.concat(asyncResult.value.data);
                sliceIndex++;
                if (sliceIndex == sliceCount) {
                    file.closeAsync();
                    onGetAllSlicesSucceeded(docdata);
                }
                else {
                    getSlice();
                }
            }
            else {
                file.closeAsync();
                document.getElementById("log").textContent = JSON.stringify(asyncResult);

            }
        });
    };
    getSlice();
}

// Upload the docx file to server after obtaining all the bits from host.
function onGetAllSlicesSucceeded(docxData) {
    $.ajax({
        type: "POST",
        url: "Handler.ashx",
        data: encodeBase64(docxData),
        contentType: "application/json; charset=utf-8",
    }).done(function (data) {
        document.getElementById("documentXmlContent").textContent = data;
    }).fail(function (jqXHR, textStatus) {
    });
}

You may find more information from here: https://github.com/pkkj/AppForOfficeSample/tree/master/GetFileAsync

Hope this could help.

Kejing Peng
  • 171
  • 4
  • Welcome to Stack Overflow! While this may answer the question, [it would be preferable](http://meta.stackoverflow.com/q/8259) to include the essential parts of the answer here, and provide the link for reference. – Nathan Tuggy Jan 03 '15 at 03:15
  • @KejingPeng how can I retrieve the Word document in .docx extention? – Ramesh Perera May 21 '21 at 12:01
0

Additional to Keyjing Peng's answer (which I found very helpful, thanks!) I thought I'd share a variation on the encodeBase64, which you don't want to do if you are uploading via REST to SharePoint. In that case you want to convert the byte array to a Uint8Array. Only then could I get it into a SharePoint library without file corruption.

var uArray = new Uint8Array(docdata);

Hope this helps someone, couldn't find this info anywhere else online...

foilage
  • 56
  • 5
-1

See this link http://msdn.microsoft.com/en-us/library/office/jj715284(v=office.1501401).aspx

it contains this example method:

var i = 0;
var slices = 0;

function getDocumentAsPDF() {

Office.context.document.getFileAsync("pdf",{sliceSize: 2097152}, function (result) {
    if (result.status == "succeeded") {
        // If the getFileAsync call succeeded, then
        // result.value will return a valid File Object.
         myFile = result.value;
         slices = myFile.sliceCount;
         document.getElementById("result").innerText = " File size:" + myFile.size + " #Slices: " + slices;

         // Iterate over the file slices.
         for ( i = 0; i < slices; i++) {
             var slice = myFile.getSliceAsync(i, function (result) {
                 if (result.status == "succeeded") {  
                     doSomethingWithChunk(result.value.data);
                     if (slices == i) // Means it's done traversing...
                     {
                         SendFileComplete();
                     }
                 }
                 else
                     document.getElementById("result").innerText = result.error.message;
                 });
         }
         myFile.closeAsync();
    }
    else
        document.getElementById("result2").innerText = result.error.message;
});

}

change "pdf" to "compressed" and the method call doSomethingWithChunk() needs to be created and should probably do something like this:

function base64Encode(str) {
        return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function (match, p1) {
            return String.fromCharCode('0x' + p1);
        }));
    }

I use this technique to successfully save to Azure blob storage.

Obviously you should rename the method as well.

John S
  • 573
  • 8
  • 22
  • This will fail on documents larger than the slice size (having multiple slices) because the `i` value is being declared outside of the `getSliceAsync` function. – Michael Coxon Apr 16 '15 at 17:57