前端导出 Word/Excel/PDF 文件

核心思路是:后端返回文件二进制流 → 前端接收并转换为 Blob → 创建下载链接触发保存

一、核心实现步骤(通用逻辑)

  1. 后端接口需返回 文件二进制流(Content-Type 对应文件类型),而非 JSON。
  2. 前端请求时设置 responseType: 'blob',确保接收二进制数据。
  3. 将 Blob 转换为临时下载链接,模拟点击实现文件保存。
  4. 清理临时链接,避免内存泄漏。

二、完整代码实现(Axios 版本,最常用)

1. 导出 Excel 文件(.xlsx)

javascript 复制代码
// 安装依赖:npm install axios
import axios from 'axios';

/**
 * 导出Excel文件
 * @param {string} apiUrl - 接口地址
 * @param {object} params - 接口参数(如筛选条件)
 * @param {string} fileName - 自定义文件名(无需后缀)
 */
export const exportExcel = async (apiUrl, params, fileName = '导出数据') => {
  try {
    // 1. 发送请求,指定接收二进制流
    const response = await axios({
      url: apiUrl,
      method: 'GET', // 也可POST,根据后端接口调整
      params: params, // POST请用data: params
      responseType: 'blob', // 关键:指定返回Blob类型
      headers: {
        'Content-Type': 'application/json', // 根据后端要求调整
        // 如有token,添加认证:
        // 'Authorization': `Bearer ${localStorage.getItem('token')}`
      }
    });

    // 2. 处理返回的Blob数据
    const blob = new Blob([response.data], {
      type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' // Excel MIME类型
    });

    // 3. 创建临时下载链接
    const downloadUrl = window.URL.createObjectURL(blob);
    const link = document.createElement('a');
    link.href = downloadUrl;
    link.download = `${fileName}.xlsx`; // 文件名+后缀
    document.body.appendChild(link);

    // 4. 触发下载
    link.click();

    // 5. 清理资源
    document.body.removeChild(link);
    window.URL.revokeObjectURL(downloadUrl);

    console.log('Excel文件导出成功');
  } catch (error) {
    console.error('Excel导出失败:', error);
    alert('文件导出失败,请重试');
  }
};

// 调用示例
// exportExcel('/api/export/user', { department: '技术部' }, '技术部用户列表');

2. Blob的type值

  • 如果你的接口返回的是 .xls 格式(旧版二进制),就用:

    go 复制代码
    const type = 'application/vnd.ms-excel';
    const blob = new Blob([response.data], { type: type });

    下载时文件名后缀用 .xls。

  • 如果接口返回的是 .xlsx 格式(新版 XML),就用:

    go 复制代码
    const type = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
    const blob = new Blob([response.data], { type: type });

    下载时文件名后缀用 .xlsx。

⚠️ 注意:MIME 类型必须和实际文件格式一致,否则可能导致下载的文件无法打开。

3. 导出 Word 文件(.docx)

仅需修改 Blob 的 type 和文件名后缀,核心逻辑完全一致:

go 复制代码
// 新版 文件格式.docx
    const blob = new Blob([response.data], {
      type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' // Word MIME类型
    });
    
// 旧版 文件格式.doc
const blob = new Blob([response.data], {
      type: 'application/msword' 
    });

  

4. 导出 PDF 文件(.pdf)

go 复制代码
    // 创建 Blob,指定 PDF 类型
    const blob = new Blob([response.data], {
      type: 'application/pdf'
    });
相关推荐
莪_幻尘18 分钟前
Skill 体检:30 个 Skill 全凭感觉?体检器先自曝了 8 个“假 0 分
前端·人工智能·llm
风骏时光牛马19 分钟前
AI模型综合能力评测:性能、指令遵循与多场景实测对比
前端
Frag0ut23 分钟前
Chrome与Chromium内核浏览器在Windows 11上的新特性全景解析
前端·chrome·windows·web安全·chromium·gemini ai·playready drm
hiahiahia1231 小时前
实现完整 Tool Dispatcher
开发语言·前端
IT_陈寒1 小时前
Java线程池这破玩意,差点让我周末加班排查到凌晨
前端·人工智能·后端
Mr_Mao2 小时前
告别选型困难!集 VueUse、ahooks、Mantine 于一身:286 个 Hook 的 ReaUse 来了
前端·javascript·react.js
泡海椒3 小时前
趋势分析报表:jquick-pdf折线图PDF生成实战
java·大数据·运维·服务器·前端·pdf
默_笙3 小时前
🚙 一条腿走路会摔:ES 关键词检索、混合召回与 ReRank 裁判
前端·javascript
YIAN3 小时前
从跨域代理到 WebSocket:梳理前端实时通信的底层逻辑与完整实践
前端·websocket
一曲终散3 小时前
创建 SVG 图标预览页面:从零实现到解决 CORS 问题
前端