Skip to content
标签
文档
报表
字数
2086 字
阅读时间
10 分钟

一、概述

POI在导出导出excel、导出csv、word时代码有点过于繁琐,Easypoi的目标不是替代poi,而是让一个不懂导入导出的快速使用poi完成Excel和word的各种操作,而不是看很多api才可以完成这样工作。

easyPOI不能完全替代POI!

二、使用Demo

2.1 依赖

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

<!-- springboot整合依赖 -->
<dependency>
    <groupId>cn.afterturn</groupId>
    <artifactId>easypoi-spring-boot-starter</artifactId>
    <version>4.1.0</version>
</dependency>

2.2 注解使用

注解方式主要用到的注解是@Excel注解,注解说明:

属性类型类型说明
nameStringnull列名
needMergebooleanfasle纵向合并单元格
orderNumString"0"列的排序,支持name_id
replaceString[]{}值得替换 导出是{a_id,b_id} 导入反过来
savePathString"upload"导入文件保存路径
typeint1导出类型 1 是文本 2 是图片,3 是函数,10 是数字 默认是文本
widthdouble10列宽
heightdouble10列高,后期打算统一使用@ExcelTarget的height,这个会被废弃,注意
isStatisticsbooleanfasle自动统计数据,在追加一行统计,把所有数据都和输出这个处理会吞没异常,请注意这一点
isHyperlinkbooleanfalse超链接,如果是需要实现接口返回对象
isImportFieldbooleantrue校验字段,看看这个字段是不是导入的Excel中有,如果没有说明是错误的Excel,读取失败,支持name_id
exportFormatString""导出的时间格式,以这个是否为空来判断是否需要格式化日期
importFormatString""导入的时间格式,以这个是否为空来判断是否需要格式化日期
formatString""时间格式,相当于同时设置了exportFormat 和 importFormat
databaseFormatString"yyyyMMddHHmmss"导出时间设置,如果字段是Date类型则不需要设置 数据库如果是string类型,这个需要设置这个数据库格式,用以转换时间格式输出
numFormatString""数字格式化,参数是Pattern,使用的对象是DecimalFormat
imageTypeint1导出类型 1 从file读取 2 是从数据库中读取 默认是文件 同样导入也是一样的
suffixString""文字后缀,如% 90 变成90%
isWrapbooleantrue是否换行 即支持\n
mergeRelyint[]{}合并单元格依赖关系,比如第二列合并是基于第一列 则{1}就可以了
mergeVerticalbooleanfasle纵向合并内容相同的单元格

创建实体类

创建实体类,添加注解。dto必须要有空构造函数,否则会报错“对象创建错误”

java
import cn.afterturn.easypoi.excel.annotation.Excel;

import java.util.Date;
@Data
public class User {

    @Excel(name = "编号", orderNum = "0", width = 5)
    private Long id;         //主键
    @Excel(name = "入职日期",  format = "yyyy-MM-dd",orderNum = "6", width = 15)
    private Date hireDate;
    private String deptId;
    @Excel(name = "出生日期",  format = "yyyy-MM-dd",orderNum = "7", width = 15)
    private Date birthday; 
    @Excel(name = "照片", orderNum = "10",width = 15,type = 2,isImportField="true",savePath = "D:\\ftp")
    private String photo;    
    @Excel(name = "现在居住地址", orderNum = "9", width = 30)
    private String address;  
}

注解导出

java
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import com.lly.model.User;
import org.apache.poi.ss.usermodel.Workbook;

import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class ExportDemo {

    public static void main(String[] args) throws IOException {
        List<User> userList = new ArrayList<>();

        for (int i = 0; i < 10; i++) {
            User user = new User((long) i, new Date(), "科室id" + i, new Date(), "tupian" + i, "dizhi" + i);
            userList.add(user);
        }
        //指定导出的格式是高版本的格式
        ExportParams exportParams = new ExportParams("员工信息", "数据", ExcelType.XSSF);
        //        直接使用EasyPOI提供的方法
        Workbook workbook = ExcelExportUtil.exportExcel(exportParams, User.class, userList);
        String filename = "员工信息.xlsx";
        //文件流
        FileOutputStream fos = new FileOutputStream("E:\\" + filename);
        workbook.write(fos);
        fos.close();
    }
}

注解导入

java

import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import com.lly.model.User;

import java.io.FileInputStream;
import java.util.List;

public class ImportDemo {

    public static void main(String[] args) throws Exception {
        String filename = "员工信息.xlsx";
        //文件流
        FileInputStream file = new FileInputStream("E:\\" + filename);
        ImportParams importParams = new ImportParams();
        //importParams.setStartSheetIndex(0); //指定sheet页
        //importParams.setSheetNum(1);  //从指定sheet开始,读取几个sheet页
        importParams.setTitleRows(1); //有多少行的标题
        importParams.setHeadRows(1);//有多少行的头
        List<User> userList = ExcelImportUtil.importExcel(file,User.class,importParams);

        for (User user : userList) {
            System.out.println(user.toString());
        }
        file.close();
    }
}

2.3 模板方式导出数据

模板是处理复杂Excel的简单方法,复杂的Excel样式,可以用Excel直接编辑,完美的避开了代码编写样式的雷区,同时指令的支持,也提了模板的有效性 采用的写法是代表表达式,然后根据表达式里面的数据取值。easypoi不会改变excel原有的样式

content

java
import cn.afterturn.easypoi.entity.ImageEntity;
import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.TemplateExportParams;
import org.apache.poi.ss.usermodel.Workbook;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ExportTemplatDemo {

    public static void main(String[] args) throws IOException {
        //        获取模板的路径
        File templatePath = new File("E:\\模板1.xlsx" );
        //        读取模板文件
        TemplateExportParams params = new TemplateExportParams(templatePath.getPath(),true);

        Map<String, Object> map = new HashMap<>();
        List<Object> list = new ArrayList<>();
        for (int i = 0;i< 5 ; i++){
            Map<String, Object> ll = new HashMap<>();
            ll.put("id",i);
            ll.put("hireDate","2023-11-0"+i);
            ll.put("birthday","2023-11-"+i*2);
            ll.put("address","测试地址"+i);
            list.add(ll);
        }
        map.put("list",list);
        ImageEntity image = new ImageEntity();
//                    image.setHeight(640); //测试发现 这里设置了长度和宽度在合并后的单元格中没有作用
//                    image.setWidth(380);
        // 不合并就会有问题
        image.setRowspan(3);//向下合并三行
        image.setColspan(2);//向右合并两列
        image.setUrl("D:\\ftp\\1.jpg");
        map.put("photo",image);

        Workbook workbook = ExcelExportUtil.exportExcel(params, map);
        //            导出的文件名称
        String filename="导出模板测试.xlsx";
        //文件流
        FileOutputStream fos = new FileOutputStream("E:\\" + filename);
        workbook.write(fos);
        fos.close();

    }
}

2.4 导出csv

csv的导出基本上和excel的导出一致,大体参数也是一致的

如果需要导出几百万数据时不可能全部加载到一个List中的,所以easyPOI的方式导出csv是支持不了太大的数据量的,如果导出几百万条数据还是得选择OpenCSV方式导出。

CsvExportParams 的参数描述如下

属性类型默认值功能
encodingStringUTF8文件编码
spiltMarkString,分隔符
textMarkString字符串识别,可以去掉,需要前后一致
titleRowsint0表格头,忽略
headRowsint1标题
exclusionsString[]0忽略的字段
java
import cn.afterturn.easypoi.csv.CsvExportUtil;
import cn.afterturn.easypoi.csv.entity.CsvExportParams;
import com.lly.model.User;

import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class ExportCsvDemo {

    public static void main(String[] args) throws IOException {
        //            创建一个用来写入到csv文件中的writer
        CsvExportParams params = new CsvExportParams();
        //        设置忽略的列
        params.setExclusions(new String[]{"照片"}); //这里写表头 中文
        List<User> userList = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            User user = new User((long) i, new Date(), "科室id" + i, new Date(), "tupian" + i, "dizhi" + i);
            userList.add(user);
        }
        FileOutputStream fos = new FileOutputStream("E:\\csv测试.csv");
        CsvExportUtil.exportCsv(params, User.class, userList, fos);
        fos.close();
    }
}

2.5 导出word

Word模板和Excel模板用法基本一致,支持的标签也是一致的,仅仅支持07版本的word也是只能生成后缀是docx的文档,poi对doc支持不好所以easyPOI中就没有支持doc

EasyPoi支持的指令以及作用

properties
三元运算 {{test ? obj:obj2}}
n: 表示 这个cell是数值类型 {{n:}}
le: 代表长度{{le:()}} 在if/else 运用{{le:() > 8 ? obj1 : obj2}}
fd: 格式化时间 {{fd:(obj;yyyy-MM-dd)}}
fn: 格式化数字 {{fn:(obj;###.00)}}
fe: 遍历数据,创建row
!fe: 遍历数据不创建row
$fe: 下移插入,把当前行,下面的行全部下移.size()行,然后插入
#fe: 横向遍历
v_fe: 横向遍历值
!if: 删除当前列 {{!if:(test)}}
单引号表示常量值 ‘’ 比如’1’ 那么输出的就是 1
&NULL& 空格
&INDEX& 表示循环中的序号,自动添加
]] 换行符 多行遍历导出
sum: 统计数据

模板示例:

content

代码逻辑:

java

import cn.afterturn.easypoi.entity.ImageEntity;
import cn.afterturn.easypoi.word.WordExportUtil;
import org.apache.poi.xwpf.usermodel.XWPFDocument;

import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ExportWordDemo {

    public static void main(String[] args) throws Exception {
        File templatePath = new File("E:\\easypoi模板.docx");

        //        把需要的数据放到map中,方便替换
        Map<String,Object> params = new HashMap<String,Object>();
        params.put("userName","张三");
        params.put("hireDate","2023-10-01");
        params.put("address","阿尔卑斯山");

        //        下面是表格中需要的数据
        List<Map> maplist = new ArrayList<>();
        Map<String,Object> map = null;
        for (int i = 0;i< 3 ;i++) {
            map = new HashMap<String,Object>();
            map.put("name","名称"+i);
            map.put("price",100*i);
            map.put("need",i%2 == 0?"需要":"不需要");
            ImageEntity image = new ImageEntity();
            image.setHeight(180);
            image.setWidth(240);
            image.setUrl("D:\\ftp\\1.jpg");
            map.put("pic",image);
            maplist.add(map);
        }
        //        把组建好的表格需要的数据放到大map中
        params.put("list",maplist);
        //        根据模板+数据 导出文档
        XWPFDocument xwpfDocument = WordExportUtil.exportWord07(templatePath.getPath(), params);
        FileOutputStream fos = new FileOutputStream("E:\\模板导出.docx" );
        xwpfDocument.write(fos);
        fos.close();
    }
}

导出效果:

content