首页 文章

Spring - 使用POI下载excel

提问于
浏览
1

我有这个控制器创建一个空表,我想将excel文件返回到导航器 . 问题是,excel文件已损坏 .

如果我在计算机上创建文件,文件没有损坏,所以我的HSSFWorkbook有效 . 似乎 spring 环境增加了编码/封装的问题?

@Controller
public class ExportController {

@RequestMapping(value = "/export/test/excel", method = RequestMethod.POST)
public void downloadExcelTestFile(
        HttpServletRequest request, 
        HttpServletResponse response) throws IOException {

    HSSFWorkbook wb = new HSSFWorkbook();

    wb.createSheet("Sheet1");

    //response.reset();
    //response.setStatus(HttpServletResponse.SC_OK);
    response.setContentType("application/vnd.ms-excel");
    response.setHeader("Content-Disposition", "attachment; filename=test.xls");

    OutputStream out = response.getOutputStream();
    wb.write(out); 

    out.flush();
    out.close();
    wb.close();
}

下载开始很好,我收到文件test.xls,但我无法打开它 . 是否有一种Spring方法可以在@Controller中实现正确的下载?

我使用Spring 4.2.4

UPDATE 1

我试过Spring方式,但效果不好

HSSFWorkbook wb = new HSSFWorkbook();

    wb.createSheet("Sheet1");

    ByteArrayOutputStream bos = new ByteArrayOutputStream();

    try {
        wb.write(bos);
    } finally {
        bos.close();
    }

    byte[] bytes = bos.toByteArray();

    HttpHeaders headers = new HttpHeaders();

    headers.set("Content-Type", "application/vnd.ms-excel;");
    headers.set("content-length",Integer.toString(bytes.length));
    headers.set("Content-Disposition", "attachment; filename=test.xls");

    return  new ResponseEntity<byte[]>(bytes, headers, HttpStatus.CREATED);

UPDATE 3

我找到了一个理由,但我不明白为什么 .

如果我构建我的war文件并在同一个tomcat 7.0.70中手动部署它就可以了 . 我的Excel没有损坏 .

如果我从eclipse中的dev环境下载,它就不起作用了 . 似乎是一个tomcat eclipse问题 .

2 回答

  • 0

    好吧,这不是一个Spring问题,甚至不是一个tomcat问题 .

    问题来自我的grunt-connect-proxy,当我通过localhost:9000运行我的前端时:我下载的文件已损坏 . 如果我在war文件中构建项目或从localhost:8080(与服务器相同的端口)运行前端没有“grunt serve”,所以没有代理它可以工作 .

    我没有用grunt解决这个问题......我只是忽略它,但这个答案可以节省你的时间 .

  • 0

    Sample Spring Backed Code to create an excel and return it using Spring REST. The input parameters may change as per your requirement

    @RequestMapping(value = "/convertFlatFileToExcel.do", method = RequestMethod.POST)
    public HttpEntity<byte[]> convertFlatFileToExcel(@RequestParam(value="file") MultipartFile file,@RequestParam(value="jobid") String jobid) {
            ByteArrayOutputStream archivo = new ByteArrayOutputStream();
            XSSFWorkbook workbook = new XSSFWorkbook();
            workbook.write(archivo);
            if(null!=workbook && null!=archivo) {
                workbook.close();
                            archivo.close();
            }
        byte[] documentContent = archivo.toByteArray();
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.parseMediaType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"));
        headers.set(HttpHeaders.CONTENT_DISPOSITION, "inline; filename=\"myexcelfile.xls\"");
        headers.setContentLength(documentContent.length);
        response = new ResponseEntity<byte[]>(documentContent, headers, HttpStatus.OK);
    }
    

    **示例UI代码:下面是使用Angular JS调用Rest Service的示例代码 . 使用https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/2014-11-29/FileSaver.min.js导入FileSaver js文件这将使用saveAs()方法保存给定名称的给定excel blob数据 . **

    $http.post(urlBase+'/convertFlatFileToExcel.do', formData,{
                    transformRequest : angular.identity,
                    responseType: 'arraybuffer',
                    headers : {
                        'Content-Type' : undefined,
                        'Accept': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
                    }})
                    .then(
                        function (response) {
                            $window.sessionStorage.showProgress = "";
                            var file = new Blob([response.data], { type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"});
                            saveAs(file, jobid.toUpperCase()+'.xlsx');
                        },
                        function (errResponse) {
                            $window.sessionStorage.showProgress = "";
                            $mdDialog.show($mdDialog.alert({title: 'Invalid Job ID!',textContent: 'Please enter a valid Job ID. For any issues, please contact the admin!',ok: 'GOT IT!'}));
                            deferred.reject(errResponse);
                        });
    

相关问题