加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – Spring MVC,Excel文件下载,破坏文件

发布时间:2020-12-15 04:23:43 所属栏目:Java 来源:网络整理
导读:我在我的一个webapps中处理excel导出功能.我设置了一个小测试用例并使下载工作,但xlsx文件已损坏,不知道我还能尝试什么.如果我写excel文件它打开没有问题,所以下载时必须发生错误. 设置: spring-mvc 3.2.7 poi 3.10.1 Tomcat 8.0 控制器方法: @RequestMapp
我在我的一个webapps中处理excel导出功能.我设置了一个小测试用例并使下载工作,但xlsx文件已损坏,不知道我还能尝试什么.如果我写excel文件它打开没有问题,所以下载时必须发生错误.

设置:

spring-mvc 3.2.7
poi 3.10.1
Tomcat 8.0

控制器方法:

@RequestMapping(value = "/download",method = RequestMethod.GET)
public ModelAndView downloadExcel() {
    // create some sample data
    List<Book> listBooks = new ArrayList<Book>();
    listBooks.add(new Book("Effective Java","Joshua Bloch","0321356683","May 28,2008",38.11F));
    listBooks.add(new Book("Head First Java","Kathy Sierra & Bert Bates","0596009208","February 9,2005",30.80F));
    listBooks.add(new Book("Java Generics and Collections","Philip Wadler","0596527756","Oct 24,2006",29.52F));
    listBooks.add(new Book("Thinking in Java","Bruce Eckel","February 20,43.97F));
    listBooks.add(new Book("Spring in Action","Craig Walls","1935182358","June 29,2011",31.98F));

    // return a view which will be resolved by an excel view resolver
    return new ModelAndView(new ExcelBuilder(listBooks));
}

抽象自定义视图:

public abstract class AbstractPOIExcelView extends AbstractView {

private static final String CONTENT_TYPE_XLSX = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";

public AbstractPOIExcelView() {
}

@Override
protected boolean generatesDownloadContent() {
    return true;
}

@Override
protected final void renderMergedOutputModel(Map<String,Object> model,HttpServletRequest request,HttpServletResponse response) throws Exception {
    XSSFWorkbook workbook = new XSSFWorkbook();
    buildExcelDocument(model,workbook,request,response);
    ByteArrayOutputStream baos = createTemporaryOutputStream();
    response.setHeader("Content-Disposition","attachment;filename=filename.xlsx");
    response.setContentType(CONTENT_TYPE_XLSX);
    workbook.write(baos);

    writeToResponse(response,baos);

}

protected abstract void buildExcelDocument(Map<String,XSSFWorkbook workbook,HttpServletResponse response) throws Exception;

}

ExcelBuilder:

public class ExcelBuilder extends AbstractPOIExcelView {

private List<Book> listBooks;

public ExcelBuilder(List<Book> books) {
    this.listBooks = books;
}

@Override
protected void buildExcelDocument(Map<String,HttpServletResponse response) throws Exception {
    Sheet sheet = workbook.createSheet("Java Books");
    sheet.setDefaultColumnWidth(30);

    Row header = sheet.createRow(0);
    header.createCell(0).setCellValue("Book Title");
    header.createCell(1).setCellValue("Author");
    header.createCell(2).setCellValue("ISBN");
    header.createCell(3).setCellValue("Published Date");
    header.createCell(4).setCellValue("Price");

    // create data rows
    int rowCount = 1;

    for (Book aBook : listBooks) {
        Row aRow = sheet.createRow(rowCount++);
        aRow.createCell(0).setCellValue(aBook.getTitle());
        aRow.createCell(1).setCellValue(aBook.getAuthor());
        aRow.createCell(2).setCellValue(aBook.getIsbn());
        aRow.createCell(3).setCellValue(aBook.getPublishedDate());
        aRow.createCell(4).setCellValue(aBook.getPrice());
    }
}
}

响应标题:

Cache-Control:private,must-revalidate
 Content-Disposition:attachment;filename="filename.xlsx"
 Content-Language:de-DE
 Content-Length:3778
 Content-Type:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=ISO-8859-1
 Date:Wed,19 Nov 2014 12:52:05 GMT
 Expires:Thu,01 Jan 1970 00:00:00 GMT
 Pragma:private
 Set-Cookie:JSESSIONID=07F50FF2B63D4003311DE222782C4E89; Path=/abc/; HttpOnly
 X-Content-Type-Options:nosniff
 X-Frame-Options:DENY
 X-XSS-Protection:1; mode=block

当这是二进制数据时,我会混淆charset的设置.这可能是问题吗?

解决方法

不要返回ModelAndView,只需将excel文件写入响应的outputStream即可

@RequestMapping(value = "/download",method = RequestMethod.GET)
@ResponseBody
public Object downloadExcel(HttpServletResponse response) {
        response.setContentType("application/vnd.ms-excel");
        response.setHeader("Content-disposition","attachment; filename=" + theFileNameString + ".xls");
        try {
            generateExcel(response.getOutputStream());
        } catch (IOException e) {
            System.out.println("ERROR: " + e);
        }
    return null;
}

检查所有刷新/关闭的流

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读