300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > Hutool Java 工具类库导出 Excel并合并数据 全网最详细!

Hutool Java 工具类库导出 Excel并合并数据 全网最详细!

时间:2020-07-08 15:50:24

相关推荐

Hutool Java 工具类库导出 Excel并合并数据 全网最详细!

ps:基于HuTool工具类ExcelWriter合并单元格并且使用 jdk1.8 lambda表达式

一、原始数据模板

二、合并后的数据

按照班级名称、班级分数、小组名称、小组得分、人物名称、人物总分进行单元格合并

合并后效果:

三、导入依赖

ps:pom依赖版本不合适可以换其他版本

导出是项目中最常见的功能,例如考勤记录导出,账单明细导出,订单记录导出等等。导出的工具类有许多种,目前常见的有poi,easypoi,poi...,今天我要说的是基于hutool-poi的导出,hutool-poi是将poi做了封装,简化了大量的代码编写。使用方式:maven在项目的pom.xml中引入<dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>4.5.1</version></dependency>gradle在项目的build.gradle中引入compile 'cn.hutool:hutool-all:5.7.3'

四、代码逻辑

1.查找数据库返回数据voList;

2.设置导出表头数据;

3.用lambda表达式获取字段分组数据;

4.遍历数据,设置合并规则;

5.将数据保存在list中;

6.ExcelWriter导出excel文件

五、代码

1.需实现将人物信息导出到excel文件中并且还要按照班级名称,小组名称,人物名称动态合并单元格,所以先创建人物对象:

@Data@AllArgsConstructor //生成所有参数的构造器public class Person {//班级名称private String className;//班级分数private double classScore;//小组名称private String groupName;//小组分数private double groupScore;//人物姓名private String personName;//人物总分private double personScore;//学科名称private String subjectName;//学科分数private double subjectScore;}

2.导出核心代码:

@Slf4j@RestController@RequestMapping("/person")public class PersonController {/*** 将页面的数据导出并合并单元格* @param response*/@ApiOperation(value = "导出数据到excel")@ApiImplicitParams({@ApiImplicitParam(name = "response", value = "响应体对象", dataType = "HttpServletResponse")})@GetMapping("/export")public void export(HttpServletResponse response)throws Exception{//1.模拟一些人物对象数据(工作中从数据库查出来)List<Person> list = new ArrayList<>();list.add(new Person("一班",90,"一组",89,"孙悟空",89,"语文",89));list.add(new Person("一班",90,"一组",89,"孙悟空",89,"数学",98));list.add(new Person("一班",90,"一组",89,"唐僧",78,"语文",98));list.add(new Person("一班",90,"一组",89,"唐僧",78,"数学",78));list.add(new Person("一班",90,"二组",90,"沙悟净",90,"语文",90));list.add(new Person("一班",90,"二组",90,"沙悟净",90,"数学",90));list.add(new Person("二班",91,"一组",97,"鲁智深",98,"语文",89));list.add(new Person("二班",91,"一组",97,"鲁智深",98,"数学",98));list.add(new Person("二班",91,"二组",89,"宋江",89,"语文",98));list.add(new Person("二班",91,"二组",89,"宋江",89,"数学",78));list.add(new Person("二班",91,"二组",89,"林冲",88,"语文",90));list.add(new Person("二班",91,"二组",89,"林冲",88,"数学",90));//2.定义基础数据List<String> rowHead = CollUtil.newArrayList("班级名称","班级分数","小组名称","小组分数","角色姓名","角色总分","学科名称","学科分数");//3.通过ExcelUtil.getBigWriter()创建Writer对象,BigExcelWriter用于大数据量的导出,不会引起溢出;ExcelWriter writer = ExcelUtil.getBigWriter();//4.写入标题writer.writeHeadRow(rowHead);ServletOutputStream out = null;//5.实现核心逻辑try {//6.定义容器保存人物数据List<List<Object>> rows = new LinkedList<>();//7.按照班级进行分组LinkedHashMap<String, List<Person>> classList = list.stream().collect(Collectors.groupingBy(item -> item.getClassName(),LinkedHashMap::new, Collectors.toList()));//8.定义起始行(方便分组后合并时从哪一行开始)//因为标题已经占了一行,所以数据从第二行开始写(excel第一行索引为0)//因需要合并到人物分数单元格所以需定义如下起始坐标int indexClassName = 1; //班级名称起始行int indexClassScore = 1;int indexGroupName = 1;int indexGroupScore = 1;int indexPersonName = 1;int indexPersonScore = 1;//9.遍历按班级名分组后的list(用entrySet效率比keySet效率高)for (Map.Entry<String, List<Person>> classNameListEntry : classList.entrySet()) {//10.获取按照班级名分组后的集合List<Person> classValue = classNameListEntry.getValue();//11.计算此集合的长度int classSize = classValue.size();//12.如果只有一行数据不能调用merge方法合并数据,否则会报错if (classSize == 1){indexClassName += classSize;indexClassScore += classSize;indexGroupName += classSize;indexGroupScore += classSize;indexPersonName += classSize;indexPersonScore += classSize;}else{//13.根据班级名称进行合并单元格//合并行,第一个参数是合并行的开始行号(行号从0开始),第二个参数是合并行的结束行号,第三个参数是合并的列号开始(列号从0开始),//第四个参数是合并的列号结束,第五个参数是合并后的内容,null不设置,第六个参数指是否支持设置样式,true指的是。writer.merge(indexClassName, indexClassName + classSize - 1, 0, 0, null, true);//14.合并完后起始索引移到下一个合并点indexClassName += classSize;//15.因为班级分数与班级名称相关联,所以不需要对班级分数分组,直接在此基础上对班级分数合并writer.merge(indexClassScore, indexClassScore + classSize - 1, 1, 1, null, true);indexClassScore += classSize;//16.按照小组名进行分组(以下分组与班级名合并类似)LinkedHashMap<String, List<Person>> groupList = classValue.stream().collect(Collectors.groupingBy(item -> item.getGroupName(),LinkedHashMap::new, Collectors.toList()));for (Map.Entry<String, List<Person>> groupListEntry : groupList.entrySet()) {List<Person> groupValue = groupListEntry.getValue();int groupSize = groupValue.size();if (groupSize == 1){indexGroupName += groupSize;indexGroupScore += groupSize;indexPersonName += groupSize;indexPersonScore += groupSize;}else{//合并小组writer.merge(indexGroupName, indexGroupName + groupSize - 1, 2, 2, null, true);indexGroupName += groupSize;//合并小组分数writer.merge(indexGroupScore, indexGroupScore + groupSize - 1, 3, 3, null, true);indexGroupScore += groupSize;//17.按照人物名称进行分组LinkedHashMap<String, List<Person>> personList = groupValue.stream().collect(Collectors.groupingBy(item -> item.getPersonName(),LinkedHashMap::new, Collectors.toList()));for (Map.Entry<String, List<Person>> personListEntry : personList.entrySet()) {List<Person> personValue = personListEntry.getValue();int personSize = personValue.size();if (personSize == 1){indexPersonName += personSize;indexPersonScore += personSize;}else{//合并人物writer.merge(indexPersonName, indexPersonName + personSize - 1, 4, 4, null, true);indexPersonName += personSize;//合并人物总分writer.merge(indexPersonScore, indexPersonScore + personSize - 1, 5, 5, null, true);indexPersonScore += personSize;}}}}}//18.保存数据classValue.forEach(sList->{List<Object> rowA = null;rowA = CollUtil.newArrayList(sList.getClassName(),sList.getClassScore(),sList.getGroupName(),sList.getGroupScore(),sList.getPersonName(),sList.getPersonScore(),sList.getSubjectName(),sList.getSubjectScore());rows.add(rowA);});}//19.导出数据//logger.info("导出数据:{}",rows.toString());// 一次性写出内容,使用默认样式,强制输出标题writer.write(rows, true);//response为HttpServletResponse对象response.setContentType("application/vnd.ms-excel;charset=utf-8");//获取当前日期作为文件名Date currentDate = new Date();SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");String date = sdf.format(currentDate);//test.xls是弹出下载对话框的文件名,不能为中文,中文请自行编码//response.setHeader("Content-Disposition", "attachment;filename=file.xlsx");response.setHeader("Content-Disposition", "attachment;filename=report_"+date+".xlsx");out = response.getOutputStream();writer.flush(out, true);}finally {//关闭输出Servlet流IoUtil.close(out);//关闭writer,释放内存writer.close();}}}

六、测试

1.使用postman测试

2.结果:

借鉴地址

借鉴地址

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。