将后端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: '文件下载失败' }
  }
}
相关推荐
weixin_382395234 小时前
为小工厂量身打造:本地部署的物料管理系统带缺料计算
前端·制造
__zRainy__4 小时前
解决pnpm v10+不自动构建
前端·pnpm·工程化
猫猫不是喵喵.5 小时前
Vue3 Props 属性
前端·javascript·vue.js
醉城夜风~6 小时前
CSS元素显示模式(display)
前端·css
AI大模型-小华6 小时前
Codex 三方充值快速入门指南
java·前端·数据库·chatgpt·ai编程·codex·chatgpt pro
做前端的娜娜子9 小时前
同一链接实现 PC Web 与移动 H5 自适应
前端·掘金·金石计划
小帅不太帅9 小时前
架构没变、规模没变,DeepSeek V4 Flash 正式版凭什么暴涨 47 分?
前端·aigc·deepseek
jarvisuni9 小时前
DeepSeekFlash前端依旧拉垮,而且变慢了很多!
前端·javascript·算法
卷福同学10 小时前
AI编程出海第二步:验证关键词能否做站
前端·人工智能·后端