You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 05:35:18