Squ*_*ler 7 javascript ms-word ms-office angularjs
我正在使用 Office Javascript API 来使用 Angular 编写 Word 插件。
我想通过 API 检索 Word 文档,然后将其转换为文件并通过 POST 上传到服务器。
我使用的代码与 Microsoft 为此用例提供的文档代码几乎相同:https ://dev.office.com/reference/add-ins/shared/document.getfileasync#example---get-a-办公室文档开放 xml 压缩格式
服务器端点要求通过多部分表单进行上传,因此我在创建 $http 调用时创建一个 FormData 对象,在该对象上附加文件(blob)以及一些元数据。
文件正在传输到服务器,但是当我打开它时,它已损坏,并且无法再用 Word 打开。
根据文档,Office.context.document.getFileAsync 函数返回一个字节数组。但是,生成的 fileContent 变量是一个字符串。当我 console.log 这个字符串时,它似乎是压缩数据,就像它应该的那样。
我的猜测是,在将字符串转换为 Blob 之前,我需要进行一些预处理。但是哪个预处理呢?通过 atob 进行 Base64 编码似乎没有做任何事情。
let sendFile = (fileContent) => {
let blob = new Blob([fileContent], {
type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
}),
fd = new FormData();
blob.lastModifiedDate = new Date();
fd.append('file', blob, 'uploaded_file_test403.docx');
fd.append('case_id', caseIdReducer.data());
$http.post('/file/create', fd, {
transformRequest: angular.identity,
headers: {
'Content-Type': undefined
}
})
.success(() => {
console.log('upload succeeded');
})
.error(() => {
console.log('upload failed');
});
};
function onGotAllSlices(docdataSlices) {
let docdata = [];
for (let i = 0; i < docdataSlices.length; i++) {
docdata = docdata.concat(docdataSlices[i]);
}
let fileContent = new String();
for (let 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...
sendFile(fileContent);
}
function getSliceAsync(file, nextSlice, sliceCount, gotAllSlices, docdataSlices, slicesReceived) {
file.getSliceAsync(nextSlice, (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();
console.log(`getSliceAsync Error: ${sliceResult.error.message}`);
}
});
}
// User clicks button to start document retrieval from Word and uploading to server process
ctrl.handleClick = () => {
Office.context.document.getFileAsync(Office.FileType.Compressed, {
sliceSize: 65536 /*64 KB*/
},
(result) => {
if (result.status === 'succeeded') {
// If the getFileAsync call succeeded, then
// result.value will return a valid File Object.
let myFile = result.value,
sliceCount = myFile.sliceCount,
slicesReceived = 0,
gotAllSlices = true,
docdataSlices = [];
// Get the file slices.
getSliceAsync(myFile, 0, sliceCount, gotAllSlices, docdataSlices, slicesReceived);
} else {
console.log(`Error: ${result.error.message}`);
}
}
);
};
Run Code Online (Sandbox Code Playgroud)
Squ*_*ler 11
我最终使用 fileContent 字符串执行此操作:
let bytes = new Uint8Array(fileContent.length);
for (let i = 0; i < bytes.length; i++) {
bytes[i] = fileContent.charCodeAt(i);
}
Run Code Online (Sandbox Code Playgroud)
然后我继续使用这些字节构建 Blob:
let blob = new Blob([bytes], { type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' });
Run Code Online (Sandbox Code Playgroud)
如果我随后通过 POST 请求发送此文件,则该文件不会被破坏并且可以由 Word 正确打开。
我仍然觉得这可以通过更少的麻烦/更少的步骤来实现。如果有人有更好的解决方案,我很有兴趣学习。