Spring MVC 文件导出

背景:

最近有一个小需求需要将数据导出excel,一直纠结于怎么打开路径选择窗口。百度也搜了很长时间,各种说法都有,这里不一一举例了,这里记录下导出这个功能。

这里有一个误区:文件保存路径的选择窗口,并不是靠前台来完成的,而是由后台返回的数据流客户端(浏览器)捕获到后,根据不同浏览器的机制完成路径选择(有的浏览器不支持保存文件路径选择,比如谷歌执行下载到默认的路径中,只有对文件操作的权限),根据不同浏览器放几张不同的效果图:

谷歌浏览器:

在浏览器输入接口后执行文件的下载,并不会有路径的选择

Spring MVC 文件导出

换一个可以出现选择保存路径的浏览器:

这个浏览器就可以选择文件的保存路径。

Spring MVC 文件导出

所以前面走了很大的弯路,一直以为路径选择的窗口是前台实现的,查了半天没有一点头绪。。。。

后台代码:

import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;

@RestController
@RequestMapping("interface")
public class InterfaceController {

    @RequestMapping("index")
    public String index() {
        return "index";
    }

    @RequestMapping("uploadFile")
    @ResponseBody
    //@RequestBody List<Map<String,Object>> list,
    public ResponseEntity<byte[]> uploadFile( HttpServletRequest request, HttpServletResponse response)
            throws Exception {
        //http 返回请求头信息
        HttpHeaders headers = new HttpHeaders();
        String fileName=new String("test.xlsx".getBytes("UTF-8"),"iso-8859-1");//为了解决中文名称乱码问题
        headers.setContentDispositionFormData("attachment", fileName);
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);

        //生成一个excel
        XSSFWorkbook workbook = new XSSFWorkbook();
        XSSFSheet sheet = workbook.createSheet("TC");
        XSSFRow headerRow = sheet.createRow(0);
        XSSFCell cell0 = headerRow.createCell(0);
        cell0.setCellValue("编号");
        //将生成的excel 写入到流中
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        workbook.write(baos);
        //返回
        return new ResponseEntity<byte[]>(baos.toByteArray(),
                headers, HttpStatus.CREATED);
    }

}

可以直接使用,

前台的话 用一个a标签 调用这个接口就行了。