使用easypoi优雅进行数据导出到excel

       最近公司有好几个需求都是关于导出统计报表到excel,并发送邮件到对应负责人,纠缠了一番之后,也对导出数据到excel有了一定经验,不至于每做一个导出功能就要写一大堆重复代码。以下是最近几天对easypoi的一些使用经验和心得。

      首先是依赖的问题,我们需要添加以下三个easypoi的包,具体的作用也就见名思意了,不做解释。


    cn.afterturn
    easypoi-base
    4.0.0


    cn.afterturn
    easypoi-web
    4.0.0


    cn.afterturn
    easypoi-annotation
    4.0.0


在使用之前先来介绍一下相关的easypoi注解:

  1. @Excel  作用在bean的属性上面,可以定义属性的排列顺序,列宽,行高,格式化等。
  2. @ExcelTarget  作用在bean上面,可以定义行高,文字的大小,主要是用来针对一个bean做不同的导出逻辑。
  3. @ExcelEntity  表示可以继续深入导出这个对象的相关字段。
  4. @ExcelIgnore  看名字就清楚什么意思了
  5. @ExcelCollection  表示一个集合,导出一对多的关系。

 

其中上面我使用最多的就是@Excel,接下来就是详细介绍一下这个注解要如何使用,先来看到这个注解里面可以使用属性:

属性 类型 默认值 功能
name String null 列名,支持name_id
needMerge boolean fasle 是否需要纵向合并单元格(用于含有list中,单个的单元格,合并list创建的多个row)
orderNum String "0" 列的排序,支持name_id
replace String[] {} 值的替换 导出是{0男,1女} 导入反过来
savePath String "upload" 导入文件保存路径
type int 1 导出类型: 1 是文本 2 是图片,3 是函数,10 是数字 默认是文本
width double 10 列宽
height double 10 列高,后期会统一使用@ExcelTarget的height
isStatistics boolean fasle 自动统计数据,再追加一行统计
isHyperlink boolean false 超链接,如果是需要实现接口返回对象
isImportField boolean true 校验字段,看看这个字段是不是导入的Excel中有,如果没有说明是错误的Excel,读取失败,支持name_id
exportFormat String "" 导出的时间格式,以这个是否为空来判断是否需要格式化日期
importFormat String "" 导入的时间格式,以这个是否为空来判断是否需要格式化日期
format String "" 时间格式,相当于同时设置了exportFormat 和 importFormat
databaseFormat String "yyyyMMddHHmmss" 导出时间设置,如果字段是Date类型则不需要设置 数据库如果是string 类型,这个需要设置这个数据库格式,用以转换时间格式输出
numFormat String "" 数字格式化,参数是Pattern,使用的对象是DecimalFormat
imageType int 1 导出类型 1 从file读取 2 是从数据库中读取 默认是文件 同样导入也是一样的
suffix String "" 文字后缀,如"¥" 9 变成9¥
isWrap boolean true 是否换行 即支持\n
mergeRely int[] {} 合并单元格依赖关系,比如第二列合并是基于第一列 则{0}就可以了
mergeVertical boolean fasle 纵向合并内容相同的单元格
fixedIndex int -1 对应excel的列,忽略名字
isColumnHidden boolean false 导出隐藏列

其余几个注解暂不做解释,先来进行实操,首先看到我们需要导出数据效果,如图:

使用easypoi优雅进行数据导出到excel_第1张图片

然后我们看到对应的对象Bean,如下,这里需要注意第一列和第二列,首先needMerge和mergeVertical都是需要改为true,如果第二列需要在第一列的基础上进行合并就添加mergeRely={0},0就是第一列的意思。

import cn.afterturn.easypoi.excel.annotation.Excel;
import lombok.Data;
import lombok.experimental.Accessors;

import java.io.Serializable;

@Data
@Accessors(chain = true)
public class ExportProductShiftItemDetailDTO implements Serializable {
    @Excel(name = "FBOX or SFT",width = 30, orderNum = "0",needMerge = true,mergeVertical = true)
    private String productShitItemCode;

    @Excel(name = "运输方式",width = 12, orderNum = "1",needMerge = true,mergeVertical = true, mergeRely = {0})
    private String shipType;

    @Excel(name = "分箱号",width = 20, orderNum = "2")
    private String productShiftBoxCode;

    @Excel(name = "SKU/POA",width = 12, orderNum = "3",height = 15.0D)
    private String productCode;

    @Excel(name = "三方条码",width = 20, orderNum = "4")
    private String amazonCustomerLabel;

    @Excel(name = "店铺",width = 15, orderNum = "5")
    private String amazonShop;

    @Excel(name = "每箱数量",width = 12, orderNum = "6")
    private String quantity;

    @Excel(name = "体积",width = 20, orderNum = "7")
    private String volume;

    @Excel(name = "重量",width = 12, orderNum = "8")
    private String weight;
}

然后就是导出数据到excel部分,这里做一下封装,用起来就得心应手,看自己需要,先把数据组装成ExportParams

/**
*@title  表格的顶头标题
*@sheetName  表脚
*@dataList    数据源
*@tClass     数据源的bean模式
*/
public static  Map getExcelSheetParam(String title, String sheetName, List dataList, Class tClass) throws SkbException {
   Map excelParam = new HashMap<>();
   ExportParams params = new ExportParams();
   if(StringUtils.isNotBlank(title)){
       params.setTitle(title);
   }
   params.setSheetName(sheetName);
   params.setType(ExcelType.XSSF);
   excelParam.put("title", params);
   excelParam.put("entity", tClass);
   excelParam.put("data", dataList);
   return excelParam;
}

导出到workbook并输出到response

/**
     *
     * @param list   数据集
     * @param excelType  文件类型ExcelType.HSSF/XSSF
     * @return
     * @throws SkbException
     */
    public static void exportExcel(List> list, ExcelType excelType, String fileName, HttpServletResponse response) throws SkbException{
        try {
            //设置响应
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName + ".xlsx", "UTF-8"));
            response.setContentType("application/vnd.ms-excel");
            Workbook workbook = ExcelExportUtil.exportExcel(list, excelType);
            if (workbook != null) {
                // 打开流
                OutputStream outputStream = response.getOutputStream();
                list.clear();
                workbook.write(outputStream);
                // 刷新流
                outputStream.flush();
                // 关闭流
                outputStream.close();
            }
        }catch (IOException e){
            throw new SkbException("导出表格数据失败");
        }
    }

最后是调用部分

public void exportProductShiftBoxDetail(List productShiftItemIdList, HttpServletResponse response) throws SkbException {
        List result = productShiftItemMapper.exportProductShiftBoxDetail(productShiftItemIdList);
        if(org.apache.commons.collections.CollectionUtils.isNotEmpty(result)){
            List> excelParamList = new ArrayList<>();
            excelParamList.add(ExportExcelUtil.getExcelSheetParam("调拨装箱信息","sheet1", result, ExportProductShiftItemDetailDTO.class));
            ExportExcelUtil.exportExcel(excelParamList, ExcelType.XSSF, "调拨装箱明细", response);
        }else {
            AssertUtils.success(Boolean.FALSE,"没有要导出的数据");
        }
    }

打完收工,你们也赶紧去试一下吧。

你可能感兴趣的:(使用easypoi优雅进行数据导出到excel)