Java文件下载-文件名下划线

15 篇文章 0 订阅
9 篇文章 0 订阅
  • 关键字:Java文件下载HttpServletResponsepoi文件名下划线

问题描述

本来今天高高兴兴,写个 Excel 文件下载,功能实现了,文件名却是 ____.xlsx____.xls,瞬间裂开。

解决方案

  • 惯例,先说解决方案:
    – 其实这个问题是因为文件名字符集的问题,不同浏览器的默认字符集是不一样的:IE或者以IE为内核的浏览器是UTF-8,非IE浏览器是 ISO-8859-1 ,这就导致出现 UTF-8 字符使用 ISO-8859-1 编码读取,ISO-8859-1 使用 UTF8 读取等等。
  • 解决办法:判断一下当前浏览器,再重新对文件名进行转码,核心代码如下:
String userAgent = request.getHeader("User-Agent");
 //针对IE或者以IE为内核的浏览器:
if (userAgent.contains("MSIE") || userAgent.contains("Trident")) {
     fileName = java.net.URLEncoder.encode(fileName, StandardCharsets.UTF_8.toString());
 } else {
     //非IE浏览器:
     fileName = new String(fileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);
}

问题复现

  • 问题代码:

实现功能,读取数据库中的员工信息,写到 Excel 文件中,并下载。

@RequestMapping("/downloadExcel")
@ResponseBody
public void downloadExcel(HttpServletRequest request, HttpServletResponse response) {
    // 1. 从数据库中读取列表数据
    QueryVo vo = new QueryVo();
    vo.setPage(1);
    vo.setRows(10);
    PageListRes pageListRes = employeeService.getAllEmployee(vo);
    List<Employee> employees = (List<Employee>) pageListRes.getRows();
    try {
        // 2. 创建 Excel 写到 Excel 中
        HSSFWorkbook wb = new HSSFWorkbook();
        HSSFCreationHelper creationHelper = wb.getCreationHelper();
        // 创建 Excel 中的一页
        HSSFSheet sheet = wb.createSheet("员工数据");
        HSSFRow sheetRow = sheet.createRow(0);
        // 设置行的每一列数据
        sheetRow.createCell(0).setCellValue("编号");
        sheetRow.createCell(1).setCellValue("用户名");
        sheetRow.createCell(2).setCellValue("入职日期");
        sheetRow.createCell(3).setCellValue("电话");
        sheetRow.createCell(4).setCellValue("邮箱");
        HSSFRow employeeRow = null;
        // 取出每一个员工来去设置数据
        for (int i = 0; i < employees.size(); i++) {
            Employee employee = employees.get(i);
            int rowNum = i + 1;
            employeeRow = sheet.createRow(rowNum);
            employeeRow.createCell(0).setCellValue(employee.getId());
            employeeRow.createCell(1).setCellValue(employee.getUsername());
            // 格式化日期
            String inputTime = employee.getInputtime() == null ? "" :
                    new SimpleDateFormat().format(employee.getInputtime());
            employeeRow.createCell(2).setCellValue(inputTime);
            employeeRow.createCell(3).setCellValue(employee.getTel());
            employeeRow.createCell(4).setCellValue(employee.getEmail());
        }
        // 3. 响应给浏览器
        String fileName = new String("员工数据.xlsx".getBytes(StandardCharsets.UTF_8), StandardCharsets.UTF_8);
        response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
        response.setCharacterEncoding(StandardCharsets.UTF_8.toString());
        wb.write(response.getOutputStream());
    } catch (Exception e) {
        e.printStackTrace();
    }
}
  • 解决完BUG的代码:
@RequestMapping("/downloadExcel")
@ResponseBody
public void downloadExcel(HttpServletRequest request, HttpServletResponse response) {
    // 1. 从数据库中读取列表数据
    QueryVo vo = new QueryVo();
    vo.setPage(1);
    vo.setRows(10);
    PageListRes pageListRes = employeeService.getAllEmployee(vo);
    List<Employee> employees = (List<Employee>) pageListRes.getRows();
    try {
        // 2. 创建 Excel 写到 Excel 中
        HSSFWorkbook wb = new HSSFWorkbook();
        HSSFCreationHelper creationHelper = wb.getCreationHelper();
        // 创建 Excel 中的一页
        HSSFSheet sheet = wb.createSheet("员工数据");
        HSSFRow sheetRow = sheet.createRow(0);
        // 设置行的每一列数据
        sheetRow.createCell(0).setCellValue("编号");
        sheetRow.createCell(1).setCellValue("用户名");
        sheetRow.createCell(2).setCellValue("入职日期");
        sheetRow.createCell(3).setCellValue("电话");
        sheetRow.createCell(4).setCellValue("邮箱");
        HSSFRow employeeRow = null;
        // 取出每一个员工来去设置数据
        for (int i = 0; i < employees.size(); i++) {
            Employee employee = employees.get(i);
            int rowNum = i + 1;
            employeeRow = sheet.createRow(rowNum);
            employeeRow.createCell(0).setCellValue(employee.getId());
            employeeRow.createCell(1).setCellValue(employee.getUsername());
            // 格式化日期
            String inputTime = employee.getInputtime() == null ? "" :
                    new SimpleDateFormat().format(employee.getInputtime());
            employeeRow.createCell(2).setCellValue(inputTime);
            employeeRow.createCell(3).setCellValue(employee.getTel());
            employeeRow.createCell(4).setCellValue(employee.getEmail());
        }
        // 3. 响应给浏览器
        String fileName = new String("员工数据.xlsx".getBytes(StandardCharsets.UTF_8), StandardCharsets.UTF_8);
        String userAgent = request.getHeader("User-Agent");
        // 针对IE或者以IE为内核的浏览器:
        if (userAgent.contains("MSIE") || userAgent.contains("Trident")) {
            fileName = java.net.URLEncoder.encode(fileName, StandardCharsets.UTF_8.toString());
        } else {
            //非IE浏览器:
            fileName = new String(fileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);
        }
        response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
        response.setCharacterEncoding(StandardCharsets.UTF_8.toString());
        wb.write(response.getOutputStream());
    } catch (Exception e) {
        e.printStackTrace();
    }
}

如果能帮到您,麻烦来个一键三连,谢谢。

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值