关于文件下载的问题,如何解决?

springboot word文件下载,没有下载文件,前端responesbody里的是xml格式的数据

img


前端vue代码

 xiazai () {
           this.$http.get('/admin/abc/xiazai/word').then(res => {
          console.log(1)
        }, err => {
          console.log(2)
        });

      },

后端代码

@Controller
@RequestMapping("/abc" )
@Api(value = "文件下载", tags = "下载")
public class WrodDownLoadController {

    @GetMapping("/xiazai/word")
    public void download(HttpServletRequest request, HttpServletResponse response, String word) throws IOException {
        File file  = new File("D:\\360\\20230307.docx");
        InputStream fin = null;
        ServletOutputStream out = null;
        try {
            // 调用工具类WordGenerator的createDoc方法生成Word文档
            fin = new FileInputStream(file);

            response.setCharacterEncoding("utf-8");
            response.setContentType("application/msword");
            // 设置浏览器以下载的方式处理该文件默认名为resume.doc
            response.addHeader("Content-Disposition","attachment;filename=resume.doc");

            out = response.getOutputStream();
            byte[] buffer = new byte[512]; // 缓冲区
            int bytesToRead = -1;
            // 通过循环将读入的Word文件的内容输出到浏览器中
            while ((bytesToRead = fin.read(buffer)) != -1) {
                out.write(buffer, 0, bytesToRead);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (fin != null) {
                fin.close();
            }
            if (out != null) {
                out.close();
            }
        }
    }
}


直接把你的前端代码改成这样试试:

xiazai() {
  this.$http.get('/admin/abc/xiazai/word', { responseType: 'blob' })
    .then(res => {
      // 将 response 中的 blob 类型数据转换成一个 URL 对象
      const url = window.URL.createObjectURL(new Blob([res.data]))
      // 创建一个链接,模拟用户点击下载
      const link = document.createElement('a')
      link.style.display = 'none'
      link.href = url
      link.setAttribute('download', 'resume.doc')
      document.body.appendChild(link)
      link.click()
      document.body.removeChild(link)
    })
    .catch(err => {
      console.log(err)
    })
}

我认为是前端代码出现问题啦
当请求成功时并没有对响应做任何处理,因此无法得到文件下载。可以在返回的响应中使用Blob对象获取文件内容并进行下载.

SpringBoot实现下载文件的几种方式
https://blog.csdn.net/user2025/article/details/107300831

该回答引用GPTᴼᴾᴱᴺᴬᴵ
根据您提供的代码,可能是因为前端没有正确处理文件流而导致的问题。您可以尝试以下更改:

1.在前端的xiazai()函数中,使用axios库并将responseType设置为'blob',以便正确处理文件流。

xiazai () {
  this.$http({
    method: 'get',
    url: '/admin/abc/xiazai/word',
    responseType: 'blob'
  }).then(res => {
    let blob = new Blob([res.data])
    let filename = 'resume.doc'
    let link = document.createElement('a')
    link.href = URL.createObjectURL(blob)
    link.download = filename
    link.click()
  }, err => {
    console.log(2)
  });
},


2.在后端的download()方法中,使用Files.copy()方法将文件内容写入输出流中,而不是使用缓冲区一次性写入。

@GetMapping("/xiazai/word")
public void download(HttpServletRequest request, HttpServletResponse response, String word) throws IOException {
    File file = new File("D:\\360\\20230307.docx");
    InputStream fin = null;
    try {
        fin = new FileInputStream(file);

        response.setCharacterEncoding("utf-8");
        response.setContentType("application/msword");
        response.setHeader("Content-Disposition", "attachment; filename=\"resume.doc\"");

        Files.copy(file.toPath(), response.getOutputStream());
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        if (fin != null) {
            fin.close();
        }
    }
}


请注意,这里使用了Java 7中的Files.copy()方法,它接受源文件和输出流作为参数,并自动处理缓冲区和流的关闭。如果您的项目使用的是较早版本的Java,您可以使用其他方法来实现类似的功能。

“Devil组”引证GPT后的撰写:

  • 从后端代码和前端代码来看,下载文件的逻辑看起来是没有问题的。但是,你可以试着在后端的方法中加上日志打印,看看是否真的有进入到这个方法里。同时,可以尝试在浏览器地址栏输入下载文件的链接,看看是否能够正常下载。如果不能正常下载,就需要检查一下服务器的网络配置是否有问题,或者是防火墙等安全设置是否阻止了文件下载。如果能够正常下载,那么问题可能出在前端代码中。你可以尝试使用浏览器的开发者工具查看网络请求的返回值,以确定问题的具体原因。