Skip to content

22.SpringMVC文件下载的两种方式

江南一点雨 edited this page Jan 17, 2018 · 1 revision

servlet里边的下载很多小伙伴应该都很熟悉,用HttpServletResponse往出写即可,当然更多时候我们使用apache上的开源工具类commons-io来实现,核心代码如下:

protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    String fileName = req.getParameter("file");
    String downloadFolder = req.getServletContext().getRealPath("/WEB-INF/download");
    File file = new File(downloadFolder, fileName);
    resp.addHeader("content-disposition",
            "attachment;filename=" + new String(fileName.getBytes("UTF-8"), "ISO-8859-1"));
    IOUtils.copy(new FileInputStream(file), resp.getOutputStream());
}

由于SpringMVC默认支持的参数类型就有HttpServletResponse,因此我们也可以利用上面的代码来实现在SpringMVC中的下载,即在Controller中定义一个方法,返回值为void,方法有一个参数为HttpServletResponse,方法内容和上面代码类似,这种方式整体来说还是换汤不换药,还是Servlet中的老一套,SpringMVC中针对下载有专门的方案,即ResponseEntity。使用ResponseEntity,我们可以向前端返回一段二进制数据,代码如下:

@RequestMapping(value = "/exportEmp", method = RequestMethod.GET)
public ResponseEntity<byte[]> exportEmp() {
    return PoiUtils.exportEmp2Excel(empService.getAllEmployees());
}
public class PoiUtils {

    public static ResponseEntity<byte[]> exportEmp2Excel(List<Employee> emps) {
        HttpHeaders headers = null;
        ByteArrayOutputStream baos = null;
        try {
            //生成Excel,出于篇幅考虑,这里省略掉,小伙伴可以直接在源码中查看
            headers = new HttpHeaders();
            headers.setContentDispositionFormData("attachment", new String("员工表.xls".getBytes("UTF-8"), "iso-8859-1"));
            headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
            baos = new ByteArrayOutputStream();
            workbook.write(baos);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return new ResponseEntity<byte[]>(baos.toByteArray(), headers, HttpStatus.CREATED);
    }
}

在返回给前端的ResponseEntity中指明返回的数据类型,然后告诉浏览器这个数据以下载的方式处理等等,为了防止乱码,需要对文件名进行编码。