Office.js:Document.getFileAsync文件对象上传服务器后生成空白文档问题
解决Word Office Add-in上传文件后服务器得到空白文档的问题
你遇到的问题核心是错误处理了Office.File对象——直接把myFile(Office.File实例)转成Uint8Array是无效的,Office.File需要通过切片读取的方式获取真实文件内容。
前端代码修正方案
下面是修复后的上传函数,关键是通过sliceAsync读取文件的所有切片并拼接成完整的文件数据:
async function upload() { try { Office.context.document.getFileAsync(Office.FileType.Compressed, async (result) => { if (result.status !== "succeeded") { console.error("获取文件失败:", result.error); return; } const myFile = result.value; const fileData = []; const totalSlices = myFile.sliceCount; // 读取所有文件切片 for (let i = 0; i < totalSlices; i++) { await new Promise((resolve, reject) => { myFile.getSliceAsync(i, (sliceResult) => { if (sliceResult.status === "succeeded") { fileData.push(sliceResult.value.data); resolve(); } else { reject(sliceResult.error); } }); }); } // 拼接所有切片为ArrayBuffer,生成Blob const combinedBuffer = new Uint8Array([].concat(...fileData)); const blob = new Blob([combinedBuffer], { type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' }); const data = new FormData(); data.append('file', blob, "document.docx"); const config = { onUploadProgress: (progressEvent) => { const percentCompleted = Math.round((progressEvent.loaded * 100) / progressEvent.total); console.log("上传进度:", percentCompleted); }, // Axios会自动处理multipart/form-data的Content-Type,无需手动设置 headers: { "Accept": "application/json" } }; console.log("开始上传"); try { const res = await axios.post('http://localhost:5000/upload', data, config); console.log("上传成功:", res); } catch (err) { console.error("上传失败:", err); } finally { // 无论成功失败都关闭文件对象,避免资源泄漏 myFile.closeAsync(); } }); } catch (error) { console.error("全局错误:", error); } }
关键修正点说明
- 切片读取逻辑:Office.File对象无法直接转换为二进制数据,必须通过
getSliceAsync逐个读取切片,每个切片的data属性才是真实的文件二进制片段 - 数据拼接:将所有切片的二进制数据拼接成完整的Uint8Array,再生成符合要求的Blob对象
- Axios配置优化:移除手动设置的
multipart/form-data请求头,Axios会自动根据FormData生成包含boundary的正确请求头 - 资源回收:在finally块中调用
myFile.closeAsync(),确保无论上传成功或失败都能释放Office文件资源
服务器端补充检查
你的服务器代码逻辑正常,但需要确保项目根目录下的uploads文件夹已存在,否则multer会抛出文件写入错误。可以在服务器代码开头添加目录检查:
const fs = require('fs'); const uploadDir = './uploads/'; if (!fs.existsSync(uploadDir)) { fs.mkdirSync(uploadDir); }
内容的提问来源于stack exchange,提问作者Shiv Yadav
相关产品推荐
相关产品推荐

