最近根据公司需求,写一个导出Excel的功能,我使用的是POI,没有选择easyPOI,这里根据POI的基本功能,自己写了一个工具类,可以大大减少工作量,分享到这里,希望能帮到有需要的小伙伴。

先上结果

1.使用的是postman

说明:这里是根据时间段来查询数据的。

2.controller层的代码就不贴了,直接上service层的

@Overridepublic void Settlement(Map<String, Object> map, HttpServletResponse response) {ReportBaseReq req;req = new ReportBaseReq();req.setEndTime(map.get("endTime").toString());req.setStartTime(map.get("startTime").toString());List<SybxCntTimeSettlementResp> obj = rfAccountService.sybxCntTimeSettlement(req.getStartTime(), req.getEndTime());if (obj==null){return;}String filePath = "excelTemplate/reportformaccount/sybx_cntTimeSettlementD.xls";//添加表格数据HSSFWorkbook workbook = ExportUtils.structureExcel(obj, filePath, 4);      //合并单元格ExportUtils.mergeCells(obj,workbook,4,0,1);//下载表格ExportUtils.downLoadTable(workbook,response);}

2.1 请求参数:

map是接收startTime和endTime这两个参数的

2.2 添加表格数据

obj:是查询出来的数据对象

filePath:这里我使用的是模板,只使用了表头的部分,filePath为加载模板的路径

rowBegin:是开始添加数据的行数,4:为从第4行开始添加数据

2.3 合并单元格

obj:查询数据的对象

workbook:工作薄对象

mergeRowBegin:和之前的rowBegin值时一样的,但这里的意思是:开始合并的行数

columns:是需要合并的列数,0,1:合并第0 列和第1列

2.4 下载表格,固定写法

3. 然后就是下载的工具类

package com.mbf.tianjin.common.utils;import com.mbf.tianjin.common.enums.*;
import com.mbf.tianjin.common.po.bigDataAnalysis.InsuPopKpiCntD;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.ss.util.CellRangeAddress;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.net.URLEncoder;
import java.time.LocalDate;
import java.util.List;
import java.util.Map;
import java.util.Set;/*** @Author: sniper* @Date: 2021/06/18* @Description: 导出表格工具类*/
@Slf4j
public class ExportUtils {/*** 构造Excel表* @param obj* @param filePath* @param rowBegin* @param <T>* @return*/public static <T> HSSFWorkbook structureExcel(List<T> obj,String filePath,int rowBegin){Resource resource = new ClassPathResource(filePath);HSSFWorkbook workbook = null;try {InputStream inputStream = resource.getInputStream();POIFSFileSystem fspoi=new POIFSFileSystem(inputStream);//创建工作薄对象workbook=new HSSFWorkbook(fspoi);//获取工作表对象HSSFSheet sheet=workbook.getSheet("sheet1");//定义单元格格式HSSFCellStyle cellStyle = CellStyleUtils.createCellStyle(workbook,sheet, (short) 9,false,true,false,false,12,false,true);//填写报表数据int r = rowBegin;for(T resp :obj){Field[] field = resp.getClass().getDeclaredFields();HSSFRow  row = sheet.createRow(r);//行for (int i = 0; i < resp.getClass().getDeclaredFields().length; i++) {field[i].setAccessible(true);//设置字段可访问, 否则无法访问private修饰的变量值HSSFCell cell = row.createCell(i);//列cell.setCellValue(field[i].get(resp)+"");//如果使用.toString可能会报空指针异常cell.setCellStyle(cellStyle);}r++;}//修改报表日期LocalDate now = LocalDate.now();HSSFRow row = sheet.createRow(r);HSSFCell cell = row.createCell(0);cell.setCellValue("下载日期:"+now);CellRangeAddress cellAddresses = new CellRangeAddress(r , r, 0, 2);sheet.addMergedRegion(cellAddresses);} catch (IOException e) {e.printStackTrace();}catch (Exception e) {log.info("获取属性值失败:"+e);}return workbook;}/*** 合并单元格* @param workbook* @param mergeRowBegin 开始合并的行* @param columns 需要合并的列*/public static <T> void mergeCells(List<T> obj,HSSFWorkbook workbook,int mergeRowBegin,Integer... columns){HSSFSheet sheet = workbook.getSheet("sheet1");String[] str = new String[obj.size()];for (Integer column : columns) {int rowBegin = mergeRowBegin;//获取指定列,不同行的单元格值try {for (int i = 0; i < obj.size(); i++) { //遍历行HSSFRow row = sheet.getRow(rowBegin);HSSFCell cell = row.getCell(column);String value = cell.getStringCellValue();str[i] = value;rowBegin++;}} catch (Exception e) {log.info("获取单元格值失败:" + e);}//合并try {int index = 0;//计数器for (int i = 0; i < str.length - 1; i++) {index++;//1 2 3//判断单元格值是否相同if (!str[i].equals(str[i + 1])) {if (1 - index != 0) { //如果只有一个单元格,不合并CellRangeAddress cellAddresses = new CellRangeAddress(i + 1 - index + mergeRowBegin, i + mergeRowBegin, column, column);sheet.addMergedRegion(cellAddresses);index = 0;}}//判断是否循环到最后一行if (i + 1 == str.length - 1) {if ( index != 0) {//如果只有一个单元格,不合并CellRangeAddress cellAddresses = new CellRangeAddress(i + 1 - index + mergeRowBegin, i + 1 + mergeRowBegin, column, column);sheet.addMergedRegion(cellAddresses);}}}} catch (Exception e) {log.info("合并单元格失败:" + e);}}}/*** 添加维度值* @param obj* @param workbook* @param rowBegin 行* @param map  key:维度类型  value:需要合并的列* @param <T>* @return*/public static <T> HSSFWorkbook replaceValue(List<T> obj, HSSFWorkbook workbook, int rowBegin, Map<String,Integer> map){HSSFSheet sheet = workbook.getSheet("sheet1");Set<Map.Entry<String, Integer>> entries = map.entrySet();for (Map.Entry<String, Integer> entry : entries) {int r = rowBegin;//医疗类别('0':住院,'1':门诊,'2':门特) MED_TYPEif (AllDimension.MedType.getName().equals(entry.getKey())){for (int i = 0; i < obj.size(); i++) {HSSFRow row = sheet.getRow(r);HSSFCell cell = row.getCell(entry.getValue());String value = cell.getStringCellValue();cell.setCellValue("0".equals(value)? MedType.MedType0.getName():"1".equals(value)?MedType.MedType1.getName():MedType.MedType2.getName());r++;}}
}/*** 下载* @param workbook* @param response*/public static void downLoadTable(HSSFWorkbook workbook, HttpServletResponse response){try {workbook.write(response.getOutputStream());response.setCharacterEncoding("UTF-8");response.setHeader("content-Type", "application/vnd.ms-excel");response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode( "test.xls", "UTF-8"));}catch (Exception e){log.info("下载失败:"+e);}}
}

工具类里的方法,如何调用上面已经说过了,里面有一个方法:添加维度值,后面再说

看一下此时的效果:

已经实现了合并,但是和第一张图的结果不一样呢?这里是因为,纬度值没有添加进去

这里用到了枚举类,放一个枚举类

@Getter
@AllArgsConstructor
@NoArgsConstructor
public enum AllDimension {InsuType("insuType"),//险种类型(0:城镇职工,1:城乡居民) INSU_TYPEprivate String name;
}

参数介绍:

AllDimension.MedType.getName():险种的name
0:需要替换纬度值的第0列,

obj:查询的数据对象

workbook:工作薄对象

rowBegin:开始替换纬度值的行数

m:map对象

吧这个方法加上就可以替换维度了。

纯属原创分享,希望各路大神指点。

POI导出Excel,并合并单元格相关推荐

  1. java poi导出excel,合并单元格

    java导出excel一般都是2种情况,一种是依赖一个实体类进行导出,或者把数据查询出来当成一个视图,对视图进行创建实体:另一种方式就是通过数据还要计算,然后一块统计,那么就不是很好处理了,我采用的是 ...

  2. poi 导出Excel 动态 合并单元格

    public String arrearagePeriodExport(ArrearageParam param) {param.setPageNo(1);param.setPageSize(Inte ...

  3. poi 导出excel 中合并单元格

    参数说明 CellRangeAddress(int firstRow, int lastRow, int firstCol, int lastCol) CellRangeAddress(起始行号,终止 ...

  4. Springboot导出excel,合并单元格示例

    原文链接:Springboot导出excel,合并单元格示例 更多文章,欢迎访问:Java知音,一个专注于技术分享的网站 以下用一个示例来说明springboot如何导出数据到excel. 首先引入M ...

  5. Java 利用hutool工具实现导出excel并合并单元格

    Java 利用hutool工具实现导出excel并合并单元格 controller层调用service,就一个核心方法,没错就下面这个代码就能实现了.前提是项目里面要引用hutool包.把我这个复制到 ...

  6. POI进行Excel的合并单元格数据处理

    POI进行Excel的合并单元格数据处理 近日接到一个要处理合并Excel单元格的上料表的需求,就到网上找了一些模板,发现有的技术大牛还是挺厉害的,对他们致以敬意. 合并单元格工具类 在这个类中将传入 ...

  7. JAVA导出excel 动态合并单元格

    JAVA excel合并单元格原生poi 合并后的效果 直接上代码 (该方法为如果指定行的单元格里面的值一致则进行合并,直接粘贴使用即可) ** @param sheet* @param colIdx ...

  8. jxls导出excel,合并单元格的两种方式

    1.引入maven依赖: <dependency><groupId>org.projectlombok</groupId><artifactId>lom ...

  9. easyexcel导出excel自定义合并单元格【动态表头和动态数据均可以自由合并】

    网上合并单元格的博客还是很多的,大家自行舍取吧.本文主要讲解固定与不固定的表头和内容如何合并 参考官网 https://easyexcel.opensource.alibaba.com/docs/cu ...

  10. java excel导出 jxl_java使用JXL导出Excel及合并单元格

    jxl是一个韩国人写的java操作excel的工具,在开源世界中,有两套比较有影响的API可供使用,一个是POI,一个是jExcelAPI.其中功能相对POI比较弱一点.但jExcelAPI对中文支持 ...

最新文章

  1. 清华大学、腾讯发布新书 详解产业互联网的中国路径
  2. Z 字形变换 C++实现 java实现 leetcode系列(六)
  3. 微信小游戏开发教程-游戏实现1
  4. vscode更改编码_装上后这 10个扩展后,VSCode 真的是无敌的存在
  5. Mysql中的行级锁、表级锁、页级锁
  6. 全面系统地总结Linux的基本操作(上)
  7. JEECG第二期深入使用培训(报名截止2014-06-21)
  8. leveldb登山之路——cache
  9. 如何评价,为何程序员被骂立马就辞职呢?
  10. MJRefresh上拉刷新下拉加载
  11. 电脑W7系统怎样安装鸿蒙系统,家用电脑升级win7系统的操作方法
  12. 3dmax 计算机中丢失,3dmax材质丢失怎么快速找回-解决3dmax材质不见了的方法 - 河东软件园...
  13. java服务器动态打包apk
  14. 大数据Spark面试题
  15. centos 7.5 内核升级
  16. 互斥锁(mutex)的使用
  17. mysql定时任务简单例子
  18. 让所有网站都支持深色主题 - Dark Reader
  19. 计算机网络分布线图学校,【案例分享】某学院新校区综合布线系统拓扑图
  20. 【善待朋友,珍惜拥有】

热门文章

  1. 第一天-1-markdown笔记学习
  2. 什么是幂等性?四种接口幂等性方案详解
  3. Android:Preference
  4. FusionCharts的使用方法(超详细)
  5. spring jsm(一)
  6. python 小写金额转化为大写金额
  7. docker删除无用容器、镜像
  8. 单元测试与E2E测试
  9. 02. Docker安装记录卸载
  10. yolov3代码详解(七)