java导出excel数据类型处理,日期格式化,避免Long型长数字转科学计数法失去精度,以及设置隐藏列

发布于:2025-07-01 ⋅ 阅读:(16) ⋅ 点赞:(0)

        java导出excel常见的两个问题,一个是日期格式转换,另一个是Long型长数字导出变成了科学计数法导致失去精度。本文记录了这两个问题的解决方案,以及将主键等关键字段设置为隐藏列的处理方式。

1.基本excel导出和数据类型处理

    public void exportData(String tableName,List<Map<String, Object>> dataList,String outPath) {
        Workbook wb = new SXSSFWorkbook(500);
        Sheet sheet = wb.createSheet();
        wb.setSheetName(0, tableName);
        //查询所有属性
        List<String> titleKeyList = commonTableService.selectTableColumn(tableName);
        //构建表头
        Row titleRow = sheet.createRow(0);
        sheet.setDefaultColumnWidth(30);
        titleRow.setHeightInPoints(30);
        for (int i = 0; i < titleKeyList.size(); i++) {
            Cell titleCell = titleRow.createCell(i);
            titleCell.setCellValue(titleKeyList.get(i));
        }
        //构建数据体
        for (int i = 0; i < dataList.size(); i++) {
            Row row = sheet.createRow(i + 1);
            int num = 0;
            Map<String, Object> map = dataList.get(i);
            for (String key : titleKeyList) {
                Cell cell = row.createCell(num);
                Object param = map.get(key);
                if (param == null) {
                    cell.setCellValue("");
                } else if (param instanceof Integer) {
                    Integer value = (Integer) param;
                    cell.setCellValue(value);
                } else if (param instanceof Long) {
                    Long value = (Long) param;
                    cell.setCellValue(value);
                } else if (param instanceof Double) {
                    Double value = (Double) param;
                    cell.setCellValue(value);
                } else if (param instanceof Float) {
                    Float value = (Float) param;
                    cell.setCellValue(value);
                } else if (param instanceof Boolean) {
                    Boolean value = (Boolean) param;
                    cell.setCellValue(value ? 1 : 0);
                } else if (param instanceof LocalDateTime) {
                    ZoneId zoneId = ZoneId.systemDefault();
                    ZonedDateTime zonedDateTime = ((LocalDateTime) param).atZone(zoneId);
                    Instant instant = zonedDateTime.toInstant();
                    Date value = Date.from(instant);
                    cell.setCellValue(value);
                } else {
                    String value = param.toString();
                    cell.setCellValue(value);
                }
                num++;
            }
        }
        //输出文件
        Path exportPath = Paths.get(outPath, tableName + ".xlsx");
        try (FileOutputStream outputStream = new FileOutputStream(exportPath.toFile())) {
            wb.write(outputStream);
            log.info("导出项目数据表============================={}",exportPath.toString());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                wb.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

        上面代码导出的数据文件如下图所示,其中Long型id因为超过了excel默认数字显示长度,转换成了科学计数法,导致失去精度,并且,日期也不是常见的可读格式。需要通过设置单元格的样式,转换日期和Long型字段的格式,以达到期望效果。

2.日期格式化

    //定义日期格式
    CellStyle cellStyle = wb.createCellStyle();
    CreationHelper creationHelper = wb.getCreationHelper();
    cellStyle.setDataFormat(creationHelper.createDataFormat().getFormat("yyyy-MM-dd HH:mm:ss"));
    cell.setCellStyle(cellStyle);

        注意:样式只声明一遍,写在循环外,否则数据量大会报错单元格样式超出限制,一个excel最多可定义64000个样式。The maximum number of Cell Styles was exceeded. You can define up to 64000 style in a .xlsx Workbook.

3.Long型格式化

        对于Long型的处理,不做数据类型转换,直接以字符串形式作为文本导出即可。

    String value = param.toString();//Long型长数字转字符串,避免变成科学计数法失去精度
    cell.setCellValue(value);

4.处理隐藏字段

        为了更好的用户体验,像id这类字段通常不展示给用户,但作为标识字段又常常被用到,可以通过设置隐藏列的方式实现,导入时隐藏列正常读取即可,不需要做特殊处理。

        for (int i = 0; i < titleKeyList.size(); i++) {
            Cell titleCell = titleRow.createCell(i);
            titleCell.setCellValue(englishChineseTitleKey.get(titleKeyList.get(i)));
            if(projectId != null){
                if("id".equals(titleKeyList.get(i)) || "data_lib_version".equals(titleKeyList.get(i))){
                    sheet.setColumnHidden(i,true);
                }
            }
        }

至此,问题解决。

以上为个人观点,仅供学习记录,欢迎交流讨论。


网站公告

今日签到

点亮在社区的每一天
去签到