React中如何编辑Strapi获取的Word文件内容并下载可用新文件?
问题描述
我有一个对接Strapi后端的React应用,目标是向Strapi发起请求获取存储在其中的Word文件,对文件内容进行修改后下载。
我尝试了多种方法但均未成功,目前计划先将Word文件转为ArrayBuffer,再转为XML修改后转回ArrayBuffer以实现下载,但这么做会导致内容丢失字符,生成的Word文件因存在不可读字符而无法正常打开。
发起请求的fetch代码
export async function getDocumentsByUrlApi(auth, urlValue) { try { const url = `${API_URL}${urlValue}`; console.log(url); const params = { method: "GET", headers: { "Content-Type": "application/vnd.openxmlformats-officedocument.wordprocessingml.document", Authorization: `Bearer ${auth.token}`, }, }; const response = await fetch(url, params); const resultBuffer = await response.arrayBuffer(); const resultText = new TextDecoder("utf-8").decode(resultBuffer); console.log("result Buffer = ", resultBuffer); console.log("result Text = ", resultText); return resultBuffer; } catch (error) { console.log(error); } }
可正常下载的代码(未修改内容)
const reader = new FileReader(); const file = new Blob([rawDocument], { type: "application/vnd.openxmlformats-officedocument.wordprocessingml.document", }); reader.readAsArrayBuffer(file); const fileConverted = new Blob([file], { type: "application/vnd.openxmlformats-officedocument.wordprocessingml.document", }); const element = document.createElement("a"); element.href = URL.createObjectURL(fileConverted); element.download = "file_Document_to_download.docx"; element.click();
Word模板内容
Hello{{firstname}} {{lastname}}, how are you? amazing lastname: {{lastname}}. see you! regards,
修改内容后导致文件损坏的代码
const reader = new FileReader(); const file = new Blob([rawDocument], { type: "application/vnd.openxmlformats-officedocument.wordprocessingml.document", }); reader.readAsArrayBuffer(file); console.log("raw Document = ", rawDocument); const contentConverted = arrayBufferToContent(rawDocument); console.log("contentConverted = ", contentConverted); const contentToArray = contentToArrayBuffer(contentConverted) const fileConverted = new Blob([contentToArray], { type: "application/vnd.openxmlformats-officedocument.wordprocessingml.document", }); const element = document.createElement("a"); element.href = URL.createObjectURL(fileConverted); element.download = "file_Document_to_download.docx"; element.click();
转换函数
function contentToArrayBuffer(content) { const encoder = new TextEncoder(); const uint8array = encoder.encode(content); const arrayBuffer = uint8array.buffer; return arrayBuffer; } function arrayBufferToContent(arrayBuffer) { const uint8array = new Uint8Array(arrayBuffer); const decoder = new TextDecoder(); const content = decoder.decode(uint8array); return content; }
解决方案
核心问题在于:.docx是压缩的XML格式文件,不是纯文本文件,直接用TextDecoder/TextEncoder处理ArrayBuffer会破坏文件的二进制结构,导致文件损坏。正确做法是先解压docx文件,找到核心内容XML修改后重新打包。
步骤1:安装处理库
前端使用jszip处理docx的zip压缩结构,先安装依赖:
npm install jszip
步骤2:完整修改下载流程代码
import JSZip from 'jszip'; // 保留原接口,移除不必要的Content-Type请求头(GET请求无需设置) export async function getDocumentsByUrlApi(auth, urlValue) { try { const url = `${API_URL}${urlValue}`; const params = { method: "GET", headers: { Authorization: `Bearer ${auth.token}`, }, }; const response = await fetch(url, params); return await response.arrayBuffer(); } catch (error) { console.log(error); } } // 修改docx内容并下载的核心函数 async function modifyAndDownloadDocx(rawDocument) { const zip = new JSZip(); // 加载docx压缩包 await zip.loadAsync(rawDocument); // 获取docx核心内容XML(固定路径:word/document.xml) const contentXml = await zip.file('word/document.xml').async('text'); // 替换模板占位符 const modifiedXml = contentXml .replace(/{{firstname}}/g, 'John') .replace(/{{lastname}}/g, 'Doe'); // 将修改后的XML放回压缩包 zip.file('word/document.xml', modifiedXml); // 重新生成符合规范的docx文件Buffer const modifiedDocxBuffer = await zip.generateAsync({ type: 'arraybuffer', mimeType: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' }); // 触发下载 const blob = new Blob([modifiedDocxBuffer], { type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = 'modified-document.docx'; a.click(); URL.revokeObjectURL(url); } // 使用示例 getDocumentsByUrlApi(auth, urlValue).then(rawDoc => { if (rawDoc) { modifyAndDownloadDocx(rawDoc); } });
关键说明
- 禁止直接用文本解码工具处理docx的ArrayBuffer,docx包含二进制压缩数据,转纯文本会丢失关键结构信息。
- docx的可编辑内容全部存储在
word/document.xml中,修改该文件即可完成占位符替换。 - 重新打包时必须指定正确的MIME类型,否则系统无法识别为Word文件。
内容的提问来源于stack exchange,提问作者Skril349
相关产品推荐
相关产品推荐

