将后端resources中的文件返给前端下载的方法

//后端

java 复制代码
@GetMapping("getmoban")
// 下载模板
    public AppResult<String> getmoban(HttpServletResponse response) {
        // 尝试-with-resources确保流会被自动关闭
        try (InputStream resourceAsStream = this.getClass().getResourceAsStream("/excelTemplates/importQualificationAbilityExcel.xlsx");
             ServletOutputStream out = response.getOutputStream()) {

            if (resourceAsStream == null) {
                return AppResultBuilder.error(500, "模板文件不存在");
            }

            // 设置响应头信息
            response.setContentType("application/vnd.ms-excel");
            response.setHeader("Content-Disposition", "attachment; filename=\"" +
                    URLEncoder.encode("导入excel模板.xlsx", "UTF-8") + "\"");
            // 有些浏览器需要此头信息
            response.setHeader("filename", URLEncoder.encode("导入excel模板.xlsx", "UTF-8"));

            byte[] buffer = new byte[1024];
            int len;
            while ((len = resourceAsStream.read(buffer)) > 0) {
                out.write(buffer, 0, len);
            }
            out.flush(); // 确保所有数据都被写出

            return AppResultBuilder.success("下载成功.");

        } catch (UnsupportedEncodingException e) {
            return AppResultBuilder.error(500, "编码错误: " + e.getMessage());
        } catch (IOException e) {
            return AppResultBuilder.error(500, "文件读写错误: " + e.getMessage());
        }
    }

前端

html 复制代码
/**
 * 二进制文件下载工具(优化版)
 * @param binFile 二进制文件流(Blob对象)
 * @param fileName 保存的文件名
 * @param blobType MIME类型,默认为excel类型
 */
export const downloadBinaryFile = (
  binFile: Blob,
  fileName: string,
  blobType = 'application/vnd.ms-excel',
) => {
  // 确保传入的是Blob对象,避免类型错误
  if (!(binFile instanceof Blob)) {
    console.error('无效的二进制文件流')
    return
  }

  // 创建URL对象
  const url = window.URL.createObjectURL(new Blob([binFile], { type: blobType }))
  const a = document.createElement('a')
  a.href = url
  a.download = fileName // 设置文件名(支持中文)

  // 触发下载
  document.body.appendChild(a)
  a.click()

  // 清理资源
  document.body.removeChild(a)
  window.URL.revokeObjectURL(url) // 释放URL对象,避免内存泄漏
}
html 复制代码
import { downloadBinaryFile } from '@/utils/helpUtils.ts'

/**
 * 下载模板文件(修改后的版本)
 * @returns 无返回值,直接触发浏览器下载
 */
export const downloadimportFile = async () => {
  try {
    // 关键:设置responseType为blob,告知axios接收二进制流
    const result: AxiosResponse<Blob> = await axios({
      method: 'get',
      url: '/api/job/qualification/getmoban',
      responseType: 'blob', // 必须设置,否则会解析为JSON导致乱码
      timeout: 60000, // 加大超时时间,避免大文件下载超时
    })

    // 从响应头获取文件名(后端设置的filename)
    const contentDisposition = result.headers['content-disposition'] || ''
    let fileName = '' // 默认文件名

    // 解析响应头中的文件名(处理编码问题)
    if (contentDisposition) {
      const match = contentDisposition.match(/filename="(.*?)"/)
      if (match && match[1]) {
        fileName = decodeURIComponent(match[1]) // 解码URLEncoded的文件名
      }
    }
    // 调用下载工具方法处理二进制流
    downloadBinaryFile(result.data, fileName)
    return { success: true } // 返回成功状态给调用方
  } catch (error: any) {
    if (isCustomAxiosError(error)) {
      console.error('文件下载失败:', error.message)
    } else {
      console.error('文件下载异常:', error)
    }
    return { success: false, msg: '文件下载失败' }
  }
}
相关推荐
霸王蟹2 分钟前
Uni-app 跨端开发框架Unibest快速体验
前端·笔记·微信·uni-app·unibest
zihan03213 分钟前
element-plus, el-table 表头按照指定字段升降序的功能实现
前端·vue.js·状态模式
三翼鸟数字化技术团队7 分钟前
watchEffect的两种错误用法
前端·javascript·vue.js
局外人LZ10 分钟前
Decimal.js 完全指南:解决前端数值精度痛点的核心方案
开发语言·前端·javascript
郑州光合科技余经理1 小时前
同城配送调度系统实战:JAVA微服务
java·开发语言·前端·后端·微服务·中间件·php
一只小bit1 小时前
Qt 绘图核心教程:从基础绘制到图像操作全解析
前端·c++·qt·gui
乾元1 小时前
绕过艺术:使用 GANs 对抗 Web 防火墙(WAF)
前端·网络·人工智能·深度学习·安全·架构
HWL56791 小时前
一个CSS属性will-change: transform
前端·css
Y淑滢潇潇1 小时前
WEB 作业 即时内容发布前端交互案例
前端·javascript·交互
比特森林探险记1 小时前
后端开发者快速入门react
开发语言·前端·javascript