问题
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:

回答1:
From MSDN:
No more than two documents are allowed to be in memory; otherwise the
getFileAsyncoperation will fail. Use theFile.closeAsyncmethod 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
回答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.
回答3:
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...
回答4:
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.
来源:https://stackoverflow.com/questions/25931764/office-context-document-getfileasync-throwing-errors