从报表导出到excel文件小工具的java实现

最近工作上有一个小需求,需要将内部管控平台上的报表增加数据导出功能,工程内部没有找到现成可用的工具包,于是决定自己手动实现一个。本次实现主要借鉴了网上现有的一些excel导出的代码,并对其进行了一些改动,使其满足用于不需要去关心怎么在excel中填装对象,只需要为数据报表的行定义一个对象,将数据报表以列表的形式传参进去,就可以直接生成通用的excel格式的数据文件。

首先,我们需要导入依赖的包

<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>3.12</version>
</dependency>

这里我们通过java的反射功能,从对象中获取它的字段,将字段的字段名作为excel的列名,然后遍历每个对象,通过反射将对象中的每个字段值取出来填进excel对象中,这里我们不对java的反射原理做过多的介绍,感兴趣的同学可以自行查阅相关的资料,这里直接给出相关的代码:

public class ExcelUtil<T> {

    public static <T> HSSFWorkbook export(List<T> list, String sheetName){
        if(CollectionUtils.isEmpty(list)){
            return null;
        }

        T item = list.get(0);
        Class clazz = item.getClass();
        //取出所有的字段
        List<Field> fieldList = Lists.newArrayList(clazz.getDeclaredFields());
        //没有有效声明字段
        if(CollectionUtils.isEmpty(fieldList)){
            return null;
        }

        HSSFWorkbook wb = new HSSFWorkbook();
        sheetName = sheetName == null ? clazz.getSimpleName() : sheetName;
        HSSFSheet sheet = wb.createSheet(sheetName);
        HSSFRow row = sheet.createRow(0);
        //取字段名作为excel的列名
        for(int i = 0; i < fieldList.size(); i++){
            HSSFCell cell = row.createCell(i);
            cell.setCellValue(fieldList.get(i).getName().toUpperCase());
            sheet.autoSizeColumn(i);
        }
        //遍历行对象
        for(int i = 0; i < list.size(); i++){
            row = sheet.createRow(i + 1);
            T obj = list.get(i);
            //遍历字段,通过反射获取对象对应字段的值,填入excel对象中
            for(int j = 0; j < fieldList.size();j++){
                Field field = fieldList.get(j);
                String value = "";
                try{
                    field.setAccessible(true);
                    Object o = field.get(obj);
                    if(o == null){
                        value = "";
                    }else{
                        value = o.toString();
                    }

                }catch (IllegalAccessException e){
                    LogHolder.RUN_LOG.error("[ExcelUtil] unhandled object, obj:" + obj.getClass());
                }

                row.createCell(j).setCellValue(value);
            }
        }
        return wb;
    }

}

这里list中的对象的字段类型只支持java的基本数据类型,不支持复杂的复合类型,在使用时,以excel的行作为对象的数据结果即可。

这里给出一个excel样例,报表的形式如下图:

对应的java数据类型如下:

public class SmsStatisExcelMeta {

    private String msgDate;

    private String msgTypeTitle;

    private Integer sourceType;

    private String sourceTypeName;

    private Integer suc;

    private Integer fail;

    private Integer error;

    private Integer sucPhoneNum;

    private Integer failPhoneNum;

    private Integer errorPhoneNum;
    
    private Double fee;
}

在生成excel文件之后,我们还希望在前端可以直接一件点击下载,这里我们给出前后端的代码。

前端构建请求参数,发送请求:

dlexcel:function () {
     var data = this.data;
     var _add2 = {};
     _add2.searchType = $("#searchType").val();
     _add2.appType = $("#appType").val();
     _add2.sourceType = $("#sourceType").val();
     _add2.msgType = $("#msgType").val();
     _add2.startDate = data.condition.startDate;
     _add2.endDate = data.condition.endDate;
     var url = "sms/export?"
     var count = 0;
     Object.keys(_add2).forEach(function(key){
         if(_add2[key] != ""){
             if(count == 0){
             url = url + key + "=" + _add2[key];
         }else{
             url = url + "&" + key + "=" + _add2[key];
         }
             count++;
         }
     });
     location.href = url;
}

后端接收请求,查库,生成excel文件,并返回文件:

@RequestMapping("export")
    public void exportExcel(String searchType, Integer appType,
                            Integer sourceType, Integer msgType,
                            String startDate, String endDate,
                            HttpServletResponse response) throws Exception{
        SmsStatisticsSearchParam param = createSearchParam(searchType,appType,sourceType,msgType,startDate,endDate);
        ResultObj<List<SmsStatisticsSearchResult>> searchResult = smsStatisticsFacade.searchAll(param);
        HSSFWorkbook wb;
        if(!searchResult.hasException()){
            List<SmsStatisticsSearchResult> list = searchResult.getObj();
            List<SmsStatisExcelMeta> metas = convertExcelMeta(list);
            wb = ExcelUtil.export(metas,null);
        }else{
            wb = new HSSFWorkbook();
            wb.createSheet("smsStatis");
        }
        response.setContentType("application/vnd.ms-excel");
        response.setHeader("Content-disposition", "attachment;filename=smsStatis.xls");
        OutputStream ouputStream = response.getOutputStream();
        wb.write(ouputStream);
        ouputStream.flush();
        ouputStream.close();
    }

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值