springboot优雅的实现excel的导出(自适应列宽实现,中文也行),复制可用

简介: springboot优雅的实现excel的导出(自适应列宽实现,中文也行),复制可用

springboot实现excel的导出(自适应列宽实现)

【说明】废话不多说,直接就是干,⛳️

首先是环境准备

1️⃣:这里我就直接贴出用到的相关maven坐标了

<dependency>
  <groupId>cn.hutool</groupId>
  <artifactId>hutool-all</artifactId>
  <version>5.3.8</version>
</dependency>
<dependency>
  <groupId>org.apache.poi</groupId>
  <artifactId>poi</artifactId>
  <version>4.1.2</version>
</dependency>
<dependency>
  <groupId>org.apache.poi</groupId>
  <artifactId>poi-ooxml</artifactId>
  <version>4.1.2</version>
</dependency>

【警告】这里根据自己的需求确定版本号

接下来就是上正餐了

【说明】首先对于excel的导出,前端调用接口最后的响应类型要为blob,不然你导出的excel会显示损坏以及打不开

1️⃣: 直接贴代码如下:

public void exportFundOutExcel(HttpServletResponse response, @RequestBody Map<String, Object> data) {
  ExcelWriter writer = ExcelUtil.getBigWriter();
  // 设置默认的行高
  writer.setDefaultRowHeight(20);
  try {
    // 获取数据
    List<Map<String, Object>> list = service.getList(data);
    String messages = "这是excel的第一行(内容自己看)";
    // 这里正常情况是要放到常量类中的,这里为了大家看清楚,或者复制直接用,这里的key要对应上面查出来的Map中的key,这里的value对应的就是你的excel表头了
    public static final Map<String,String> FUNDS_OUT_EXCEL_MAP = new LinkedHashMap<>(3);
    static {
      FUNDS_OUT_EXCEL_MAP.put("projectName","所属项目");
      FUNDS_OUT_EXCEL_MAP.put("managementUnit","建设单位");
      FUNDS_OUT_EXCEL_MAP.put("constructionUnit","施工单位");
    }
    // 表头信息
    writer.merge(FUNDS_OUT_EXCEL_MAP.size() - 1
                 , messages
                 , true);
    FUNDS_OUT_EXCEL_MAP.forEach(writer::addHeaderAlias);
    // 仅仅获取取别名的字段
    writer.setOnlyAlias(true);
    // 一定要先进性写入数据,再设置列宽
    writer.write(list, true);
    // 获取当前工作表,需要注意的是,SXSSFSheet 在处理大数据量的 Excel 文件时非常有用,但对于小型文件,使用 XSSFSheet(基于内存)可能更为合适。
    SXSSFSheet sheet = (SXSSFSheet) writer.getSheet();
    // 这里的代码就是实现自适应列宽
    //--------------------------------
    writer.setSheet(sheet);
    // 这里默认会只显示后100行数据,所以在设置的时候会Row row = this.sheet.getRow(rownum);row为null
    //            writer.setRowHeight(3,30000);
    response.resetBuffer();
    response.setContentType("application/octet-stream;charset=utf-8");
    response.setHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode("测试.xlsx", "UTF-8"));
    writer.flush(response.getOutputStream());
  } catch (Exception e) {
    // 异常处理
  } finally {
    // 关闭writer,释放内存
    writer.close();
  }
}

下面的两种方式都可以放到上面的代码的// 这里的代码就是实现自适应列宽

//--------------------------------这个下

2️⃣:如果是excel中没有涉及到中文的话,那么可以用这种方式实现

// 这里不进行追踪的话会报错,Could not auto-size column. Make sure the column was tracked prior to auto-sizing the column.
// 跟踪所有列
sheet.trackAllColumnsForAutoSizing();
for (int i = 0; i < LotConstants.FUNDS_OUT_EXCEL_MAP.size(); i++) {
  sheet.autoSizeColumn(i);
}
int columnCount = LotConstants.FUNDS_OUT_EXCEL_MAP.size();

上面的代码我也都做了注释,大致就是必须要先执行追踪,然后再执行下面的,这个对于非中文的excel还是能做到列宽自适应的,已验证

但是对于大部分的情况下,都是含有中文的,那么就需要自己去实现了,目前我还没发现有自带的,具体实现如下

// 获取最大列宽
for (int i = 0; i < columnCount; i++) {
  final int[] maxColumnWidth = {0};
  int finalI = i;
  // 流处理,异步设置最大列宽
  IntStream.range(0, sheet.getLastRowNum() + 1).parallel().forEach(rowIndex -> {
    Row row = sheet.getRow(rowIndex);
    Cell cell = row.getCell(finalI);
    if (cell != null) {
      // 这里选择将所有格式的都转化为String类型,防止报错->Cannot get a STRING value from a NUMERIC cell
      DataFormatter dataFormatter = new DataFormatter();
      String cellValue = dataFormatter.formatCellValue(cell);
      // String cellValue = cell.getStringCellValue();
      int cellWidth = cellValue.getBytes(StandardCharsets.UTF_8).length;
      if (cellWidth > maxColumnWidth[0]) {
        maxColumnWidth[0] = cellWidth;
      }
    }
  });
  // 设置列宽,这里之所以要乘256,点进去这个方法可以看到Set the width (in units of 1256th of a character width) The maximum column width for an individual cell is 255 characters.
  // 至于200就是偏移量
  sheet.setColumnWidth(i, maxColumnWidth[0] * 256 + 200);
}

完事收工,亲测可用,如果不行请call我,一定是你哪里cv错了

补充一下上面的FUNDS_OUT_EXCEL_MAP常量,这个其实就是为了设置excel的表头,以及对应我们查询出来的字段名,大致如下:

public static final Map<String,String> FUNDS_OUT_EXCEL_MAP = new LinkedHashMap<>(3);
static {
  FUNDS_OUT_EXCEL_MAP.put("projectName","所属项目");
  FUNDS_OUT_EXCEL_MAP.put("managementUnit","建设单位");
  FUNDS_OUT_EXCEL_MAP.put("constructionUnit","施工单位");
}
相关文章
|
2月前
|
前端开发
实现Excel文件和其他文件导出为压缩包,并导入
实现Excel文件和其他文件导出为压缩包,并导入
32 1
|
2月前
|
数据格式 UED
记录一次NPOI库导出Excel遇到的小问题解决方案
【11月更文挑战第16天】本文记录了使用 NPOI 库导出 Excel 过程中遇到的三个主要问题及其解决方案:单元格数据格式错误、日期格式不正确以及合并单元格边框缺失。通过自定义单元格样式、设置数据格式和手动添加边框,有效解决了这些问题,提升了导出文件的质量和用户体验。
213 3
|
2月前
|
前端开发 Java easyexcel
SpringBoot操作Excel实现单文件上传、多文件上传、下载、读取内容等功能
SpringBoot操作Excel实现单文件上传、多文件上传、下载、读取内容等功能
133 8
|
2月前
|
Java API Apache
|
2月前
|
存储 Java API
Java实现导出多个excel表打包到zip文件中,供客户端另存为窗口下载
Java实现导出多个excel表打包到zip文件中,供客户端另存为窗口下载
87 4
|
2月前
|
存储 easyexcel Java
SpringBoot+EasyExcel轻松实现300万数据快速导出!
本文介绍了在项目开发中使用Apache POI进行数据导入导出的常见问题及解决方案。首先比较了HSSFWorkbook、XSSFWorkbook和SXSSFWorkbook三种传统POI版本的优缺点,然后根据数据量大小推荐了合适的使用场景。接着重点介绍了如何使用EasyExcel处理超百万数据的导入导出,包括分批查询、分批写入Excel、分批插入数据库等技术细节。通过测试,300万数据的导出用时约2分15秒,导入用时约91秒,展示了高效的数据处理能力。最后总结了公司现有做法的不足,并提出了改进方向。
|
3月前
|
JavaScript 前端开发 数据处理
Vue导出el-table表格为Excel文件的两种方式
Vue导出el-table表格为Excel文件的两种方式
125 6
|
3月前
|
easyexcel Java UED
SpringBoot中大量数据导出方案:使用EasyExcel并行导出多个excel文件并压缩zip后下载
在SpringBoot环境中,为了优化大量数据的Excel导出体验,可采用异步方式处理。具体做法是将数据拆分后利用`CompletableFuture`与`ThreadPoolTaskExecutor`并行导出,并使用EasyExcel生成多个Excel文件,最终将其压缩成ZIP文件供下载。此方案提升了导出效率,改善了用户体验。代码示例展示了如何实现这一过程,包括多线程处理、模板导出及资源清理等关键步骤。
|
3月前
|
Java BI API
spring boot 整合 itextpdf 导出 PDF,写入大文本,写入HTML代码,分析当下导出PDF的几个工具
这篇文章介绍了如何在Spring Boot项目中整合iTextPDF库来导出PDF文件,包括写入大文本和HTML代码,并分析了几种常用的Java PDF导出工具。
704 0
spring boot 整合 itextpdf 导出 PDF,写入大文本,写入HTML代码,分析当下导出PDF的几个工具
|
3月前
|
前端开发 JavaScript Java
导出excel的两个方式:前端vue+XLSX 导出excel,vue+后端POI 导出excel,并进行分析、比较
这篇文章介绍了使用前端Vue框架结合XLSX库和后端结合Apache POI库导出Excel文件的两种方法,并对比分析了它们的优缺点。
1045 0