【问题标题】:getFileAsync causing Excel to crashgetFileAsync 导致 Excel 崩溃
【发布时间】:2018-12-30 15:23:34
【问题描述】:

我正在为 Excel 构建一个 office-js 插件。我需要将当前工作簿上传到后端服务器。我已经从 Micrsoft 文档中实现了一个示例,它在我第一次调用它时似乎工作正常,但在随后的调用中,它会导致 Excel 崩溃。我正在使用 Excel 365 版本 1812(内部版本 11126.20132)

这是 MS 文档中示例的链接: https://docs.microsoft.com/en-us/javascript/api/office/office.document

此页面上有很多示例,要找到我正在使用的搜索“以下示例获取 Office Open XML 中的文档”,我已包含以下示例以方便参考。

代码只是获取当前文件并将字符转储到控制台的日志中。它第一次运行良好,但第二次使 Excel 崩溃——在它显示了 FileContent 的长度之后。

export function getDocumentAsCompressed() {
    Office.context.document.getFileAsync(Office.FileType.Compressed, { sliceSize: 65536 /*64 KB*/ },
        function (result) {
            if (result.status == "succeeded") {
                // If the getFileAsync call succeeded, then
                // result.value will return a valid File Object.
                var myFile = result.value;
                var sliceCount = myFile.sliceCount;
                var slicesReceived = 0, gotAllSlices = true, docdataSlices = [];
                console.log("File size:" + myFile.size + " #Slices: " + sliceCount);

                // Get the file slices.
                getSliceAsync(myFile, 0, sliceCount, gotAllSlices, docdataSlices, slicesReceived);
            }else {
                console.log("Error:", result.error.message);
            }
    });
}

function getSliceAsync(file, nextSlice, sliceCount, gotAllSlices, docdataSlices, slicesReceived) {
    file.getSliceAsync(nextSlice, function (sliceResult) {
        if (sliceResult.status == "succeeded") {
            if (!gotAllSlices) { // Failed to get all slices, no need to continue.
                return;
            }

            // Got one slice, store it in a temporary array.
            // (Or you can do something else, such as
            // send it to a third-party server.)
//            console.log("file part",sliceResult.value.data)
            docdataSlices[sliceResult.value.index] = sliceResult.value.data;
            if (++slicesReceived == sliceCount) {
              // All slices have been received.
              file.closeAsync();
              onGotAllSlices(docdataSlices);
            }
            else {
                getSliceAsync(file, ++nextSlice, sliceCount, gotAllSlices, docdataSlices, slicesReceived);
            }
        }
            else {
                gotAllSlices = false;
                file.closeAsync();
                console.log("getSliceAsync Error:", sliceResult.error.message);
            }
    });
}

function onGotAllSlices(docdataSlices) {
    var docdata = [];
    for (var i = 0; i < docdataSlices.length; i++) {
        docdata = docdata.concat(docdataSlices[i]);
    }

    var fileContent = new String();
    for (var j = 0; j < docdata.length; j++) {
        fileContent += String.fromCharCode(docdata[j]);
    }

   console.log("fileContent.length",fileContent.length)

    // Now all the file content is stored in 'fileContent' variable,
    // you can do something with it, such as print, fax...
}

这是结果

File size:21489 #Slices: 1
fileContent.length 21489

Microsoft 文档中的原始示例 (https://docs.microsoft.com/en-us/javascript/api/office/office.document)

// The following example gets the document in Office Open XML ("compressed") format in 65536 bytes (64 KB) slices.
// Note: The implementation of app.showNotification in this example is from the Visual Studio template for Office Add-ins.
function getDocumentAsCompressed() {
    Office.context.document.getFileAsync(Office.FileType.Compressed, { sliceSize: 65536 /*64 KB*/ }, 
        function (result) {
            if (result.status == "succeeded") {
            // If the getFileAsync call succeeded, then
            // result.value will return a valid File Object.
            var myFile = result.value;
            var sliceCount = myFile.sliceCount;
            var slicesReceived = 0, gotAllSlices = true, docdataSlices = [];
            app.showNotification("File size:" + myFile.size + " #Slices: " + sliceCount);

            // Get the file slices.
            getSliceAsync(myFile, 0, sliceCount, gotAllSlices, docdataSlices, slicesReceived);
            }
            else {
            app.showNotification("Error:", result.error.message);
            }
    });
}

function getSliceAsync(file, nextSlice, sliceCount, gotAllSlices, docdataSlices, slicesReceived) {
    file.getSliceAsync(nextSlice, function (sliceResult) {
        if (sliceResult.status == "succeeded") {
            if (!gotAllSlices) { // Failed to get all slices, no need to continue.
                return;
            }

            // Got one slice, store it in a temporary array.
            // (Or you can do something else, such as
            // send it to a third-party server.)
            docdataSlices[sliceResult.value.index] = sliceResult.value.data;
            if (++slicesReceived == sliceCount) {
              // All slices have been received.
              file.closeAsync();
              onGotAllSlices(docdataSlices);
            }
            else {
                getSliceAsync(file, ++nextSlice, sliceCount, gotAllSlices, docdataSlices, slicesReceived);
            }
        }
            else {
                gotAllSlices = false;
                file.closeAsync();
                app.showNotification("getSliceAsync Error:", sliceResult.error.message);
            }
    });
}

function onGotAllSlices(docdataSlices) {
    var docdata = [];
    for (var i = 0; i < docdataSlices.length; i++) {
        docdata = docdata.concat(docdataSlices[i]);
    }

    var fileContent = new String();
    for (var j = 0; j < docdata.length; j++) {
        fileContent += String.fromCharCode(docdata[j]);
    }

    // Now all the file content is stored in 'fileContent' variable,
    // you can do something with it, such as print, fax...
}

// The following example gets the document in PDF format.
Office.context.document.getFileAsync(Office.FileType.Pdf,
    function(result) {
        if (result.status == "succeeded") {
            var myFile = result.value;
            var sliceCount = myFile.sliceCount;
            app.showNotification("File size:" + myFile.size + " #Slices: " + sliceCount);
            // Now, you can call getSliceAsync to download the files,
            // as described in the previous code segment (compressed format).

            myFile.closeAsync();
        }
        else {
            app.showNotification("Error:", result.error.message);
        }
}
);

【问题讨论】:

  • 我很乐意提供帮助,但我不知道如何前进。我认为事件查看器中没有错误消息和日志可能没有提供任何有价值的信息。这使它更像是一场猜谜游戏,我的建议是将其发布在issue page for office.js。
  • Flous:感谢您的关注和推荐。你是对的,没有错误信息。我不确定事件查看器是什么,但我会追踪它,看看是否有任何有用的东西。

标签: excel office-js


【解决方案1】:

由于您使用的是 Excel,您是否尝试过 CreateWorkbork API?如果 Document API 有 bug,可能是一个很好的解决方法,就像前面提到的玄舟。

Here's a CreateDocument snippet,您可以将其加载到Script Lab。它展示了如何基于现有文件创建工作簿副本。

希望对您有所帮助。

【讨论】:

    【解决方案2】:

    我们现在已经解决了这个问题。但修复仍需要一些时间才能投入生产。请在几天后尝试,如果问题仍然存在,请告诉我。谢谢。

    【讨论】:

    • 能否分享一下修复方法。我也面临同样的问题。
    猜你喜欢
    • 2016-12-23
    • 1970-01-01
    • 2013-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-06
    • 1970-01-01
    • 2018-01-23
    相关资源
    最近更新 更多