java使用easypoi导出动态列excel

1 篇文章 0 订阅
1 篇文章 0 订阅

简介

asypoi功能如同名字easy,主打的功能就是让一个没见接触过poi的人员就可以方便的写出Excel导出,Excel模板导出,Excel导入,Word模板导出,通过简单的注解和模板语言(熟悉的表达式语法),完成以前复杂的写法。


一、场景描述

客户要求导出一张结算报表,报表的列头是选择结算的日期区间,也就是需要根据日期分组,然后计算这个日期下的结算金额和笔数,最后再计算合计。针对这个场景,我整理了下代码,如下:

二、使用步骤

1.引入Jar包

这是针对导出Excel的,如果是Word还需要自行拷贝其他包(示例):

       <dependency>
            <groupId>cn.afterturn</groupId>
            <artifactId>easypoi-base</artifactId>
            <version>4.2.0</version>
        </dependency>
        <dependency>
            <groupId>cn.afterturn</groupId>
            <artifactId>easypoi-web</artifactId>
            <version>4.2.0</version>
        </dependency>
        <dependency>
            <groupId>cn.afterturn</groupId>
            <artifactId>easypoi-annotation</artifactId>
            <version>4.2.0</version>
        </dependency>

2.代码实现

代码如下(示例):

    public void exportReport(Map<String, Object> params, HttpServletRequest request,
                                         HttpServletResponse response) {
        ModelMap modelMap = new ModelMap();
        Map<String, Object> dataMap = Maps.newHashMap();
		//模板存放路径,在你项目的Resource下随便建个文件夹,把模板放进去就好
        TemplateExportParams tempParams = new TemplateExportParams("TemplateFiles/test.xlsx");
        // 获取结算数据
        List<TestEntity> list = baseDao.getAllSummaryList(params);
        // 把数据转成excel数据
        List<TestExcel> dataList = ConvertUtils.sourceToTarget(list, TestExcel.class);
        //按照结算日期分组(获取动态列头)
        Map<Object, List<TestExcel>> listTwo = new HashMap<>();
        //根据商户分组(获取行)
        Map<Object, List<TestExcel>> listOne = dataList.stream().collect(Collectors.groupingBy(TestExcel::getSubMerchantAccNo));
		//创建列和行集合
        List<Map<String, Object>> colList = new ArrayList<Map<String, Object>>();
        List<Map<String, Object>> valList = new ArrayList<Map<String, Object>>();
        Map<String, Object> value = new HashMap<String, Object>();
		//序列号(报表要用)
        int seq= 0;
        for(Object subNO : listOne.keySet()){
            seq+=1;
            //获取这个商户下的交易明细
            List<TestExcel> detailList=listOne.get(subNO);
            for(int i = 0;i<detailList.size();i++){
                //获取结算时间
                String paymentTime = detailList.get(i).getSettlementtime();
                for (Object time : listTwo.keySet()) {
                    Map<String, Object> map = new HashMap<String, Object>();
                    //先处理表头
                  if (paymentTime.equals(time)) {
                      if(colList.size()>0){
					      //这里是判断列集合里有没有重复的,去重
                          boolean flag = false;
                          for(int j =0 ; j < colList.size();j++){
                             if(colList.get(j).get("paymentTime").equals(paymentTime)){
                                flag = true;
                                break;
                             }
                          }
                          if(flag == false){
                            map.put("paymentTime", time);
                            map.put("bs", "笔数");
                            map.put("je", "金额");
							// t.这是easypoi的语法,后面拼接时间是为了区分这个笔数和金额是属于哪个日期下的
                            map.put("transCount", "t.transCount"+time); 
                            map.put("transAmount", "t.transAmount"+time);
                            colList.add(map);
                           }
                      }else{
                          map.put("paymentTime", time);
                          map.put("bs", "笔数");
                          map.put("je", "金额");
                          map.put("transCount", "t.transCount"+time);
                          map.put("transAmount", "t.transAmount"+time);
                          colList.add(map);
                      }
                      break;
                    }
                }
            }
            //行添加
            Map<String, Object> map1 = new HashMap<String, Object>();
			//计算这个商户在某个日期区间内的金额和笔数的合计
            int totalCnt = detailList.parallelStream().filter(e -> StringKit.notBlank(e.getTransCount()))
                    .mapToInt(TestExcel::getTransCount).sum();
            double totalAmt = detailList.parallelStream().filter(e -> StringKit.notBlank(e.getTransAmount()))
                    .mapToDouble(e -> e.getTransAmount().doubleValue()).sum();

            map1.put("subMerchantAccNo", detailList.get(0).getSubMerchantAccNo()); //subMerchantAccNo 商户号
            map1.put("subMerchantName", detailList.get(0).getSubMerchantName());  //subMerchantName  商户名
			map1.put("totalCnt", totalCnt);  //合计笔数 2020
            map1.put("totalAmt", totalAmt);  //合计金额 2020
            map1.put("seqNum", seq);  //合计金额 2020
            for(int a = 0;a<detailList.size();a++){
                //笔数
                int transCount = detailList.get(a).getTransCount();
                //金额
                BigDecimal transAmount = detailList.get(a).getTransAmount();
                //结算时间
                map1.put("transCount"+detailList.get(a).getTranstime(), transCount);     
                map1.put("transAmount"+detailList.get(a).getTranstime(), transAmount); 
				//这里的key对应上面列的value,根据这个找到某个笔数和金额的值,一个商户肯定对应多个日期,那有几个日期就要put几个
            }
            valList.add(map1);
        }
		//根据结算日期排序
        colList.sort((t1, t2) -> t1.get("paymentTime").toString().compareTo(t2.get("paymentTime").toString()));
        dataMap.put("valList", valList);
        dataMap.put("colList", colList);
        tempParams.setColForEach(true);//这个必须要加
        // 日期类型
        dataMap.put("dateTypeName", params.get("dateTypeName"));
        // 数据类型
        dataMap.put("dataTypeName", params.get("dataTypeName"));
        // 结算周期
        dataMap.put("settlementCycle", params.get("startDate") + "至" + params.get("endDate"));
        // sheet页名称
        tempParams.setSheetName(Convert.toStrArray("结算表"+ DateUtils.getMillisecond()));
		//导出excel
        modelMap.put(TemplateExcelConstants.FILE_NAME, "结算表" + DateUtils.getMillisecond());
        modelMap.put(TemplateExcelConstants.PARAMS, tempParams);
        modelMap.put(TemplateExcelConstants.MAP_DATA, dataMap);
        PoiBaseView.render(modelMap, request, response, TemplateExcelConstants.EASYPOI_TEMPLATE_EXCEL_VIEW);
    }

3.模板创建

在这里插入图片描述
模板里的字段都对应着代码里的字段,可自行调整。模板主要分为四部分,一是行循环【valList】,这里得到了序列号,商户号和商户名。二是列循环【colList】,这里得到的是日期列头。三是内部的子循环,得到的是一个商户对应的全部日期的集合,对应代码最后一个循环体部分,这里的语法也不一样,用的是【v_fe】。最后是合计部分,这里是单独一列,并且必须放在日期循环体的前面,也就是合计部分不能在最后一列,这是因为easypoi会覆盖掉循环体外的列,网上说的什么隔开一列,试过无法解决,所以只能放在前面。

4.结果展示

在这里插入图片描述

三、 总结

以上就是今天要讲的内容,本文主要是介绍一种easypoi的复杂Excel导出的方法,它还可以快速导出word等,有不清楚的欢迎留言,觉得写的不错的,可以点赞收藏鼓励哟!

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
以下是使用EasyPoi导出ExcelJava代码示例[^1]: 1. 首先,确保你已经引入了EasyPoi的依赖库。 2. 创建一个实体类,用于存储导出的数据。例如,创建一个名为"ExcelExport"的类,并使用@Excel注解来指定Excel中的名和属性名。 ```java import cn.afterturn.easypoi.excel.annotation.Excel; import lombok.Data; @Data public class ExcelExport { @Excel(name = "姓名") private String name; @Excel(name = "年龄") private int age; // 其他属性... } ``` 3. 编写导出方法,使用EasyPoi提供的工具类进行导出操作。例如,创建一个名为"ExcelUtils"的工具类,并在其中编写导出方法。 ```java import cn.afterturn.easypoi.excel.ExcelExportUtil; import cn.afterturn.easypoi.excel.entity.ExportParams; import cn.afterturn.easypoi.excel.entity.enmus.ExcelType; import org.apache.poi.ss.usermodel.Workbook; import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.List; public class ExcelUtils { public static void exportExcel() throws IOException { // 创建导出的数据表 List<ExcelExport> dataList = new ArrayList<>(); dataList.add(new ExcelExport("张三", 20)); dataList.add(new ExcelExport("李四", 25)); dataList.add(new ExcelExport("王五", 30)); // 创建导出参数 ExportParams exportParams = new ExportParams(); exportParams.setType(ExcelType.XSSF); // 导出Excel文件 Workbook workbook = ExcelExportUtil.exportExcel(exportParams, ExcelExport.class, dataList); FileOutputStream fos = new FileOutputStream("导出文件路径"); workbook.write(fos); fos.close(); } } ``` 4. 调用导出方法进行导出操作。 ```java public class Main { public static void main(String[] args) { try { ExcelUtils.exportExcel(); System.out.println("导出成功!"); } catch (IOException e) { e.printStackTrace(); } } } ``` 请注意,上述代码中的"导出文件路径"需要替换为你希望导出Excel文件的路径。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值