赞
踩
使用POI在导出导出excel、导出csv、word时代码有点过于繁琐,好消息是近两年在开发市场上流行一种简化POI开发的类库:easyPOI。从名称上就能发现就是为了简化开发。
能干什么?
Excel的快速导入导出,Excel模板导出,Word模板导出,可以仅仅5行代码就可以完成Excel的导入导出,修改导出格式简单粗暴,快速有效。
为谁而开发?
不太熟悉poi的
不想写太多重复太多的
只是简单的导入导出的
喜欢使用模板的
都可以使用easypoi
目标是什么?
Easypoi的目标不是替代poi,而是让一个不懂导入导出的快速使用poi完成Excel和word的各种操作,而不是看很多api才可以完成这样工作。
再次强调一下easyPOI完全替代不了POI!
需要的依赖
把项目中的poi的依赖去除
<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>
第一步:修改实体类,添加注解
其中主要用到的注解是@Excel注解,更详细的说明请看这里 (按住ctrl点击)
此处注意必须要有空构造函数,否则会报错“对象创建错误”
package com.itheima.pojo;
import cn.afterturn.easypoi.excel.annotation.Excel;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.opencsv.bean.CsvBindByName;
import lombok.Data;
import tk.mybatis.mapper.annotation.KeySql;
import javax.persistence.Id;
import javax.persistence.Table;
import java.util.Date;
import java.util.List;
/**
* 员工
*/
@Data
@Table(name="tb_user")
public class User {
@Id
@KeySql(useGeneratedKeys = true)
@Excel(name = "编号", orderNum = "0", width = 5)
private Long id; //主键
@Excel(name = "员工名", orderNum = "1", width = 15)
private String userName; //员工名
@Excel(name = "手机号", orderNum = "2", width = 15)
private String phone; //手机号
@Excel(name = "省份名", orderNum = "3", width = 15)
private String province; //省份名
@Excel(name = "城市名", orderNum = "4", width = 15)
private String city; //城市名
@Excel(name = "工资", orderNum = "5", width = 10)
private Integer salary; // 工资
@JsonFormat(pattern="yyyy-MM-dd")
@Excel(name = "入职日期", format = "yyyy-MM-dd",orderNum = "6", width = 15)
private Date hireDate; // 入职日期
private String deptId; //部门id
@Excel(name = "出生日期", format = "yyyy-MM-dd",orderNum = "7", width = 15)
private Date birthday; //出生日期
@Excel(name = "照片", orderNum = "10",width = 15,type = 2)
private String photo; //一寸照片
@Excel(name = "现在居住地址", orderNum = "9", width = 30)
private String address; //现在居住地址
private List<Resource> resourceList; //办公用品
}
第二步:UserController添加方法
@GetMapping(value = "/downLoadWithEasyPOI",name = "使用EasyPOI下载Excel")
public void downLoadWithEasyPOI(HttpServletRequest request,HttpServletResponse response) throws Exception{
userService.downLoadXlsxWithEayPoi(request,response);
}
第三步:UserService实现方法
public void downLoadXlsxWithEayPoi(HttpServletRequest request, HttpServletResponse response) throws Exception {
// 查询用户数据
List<User> userList = userMapper.selectAll();
//指定导出的格式是高版本的格式
ExportParams exportParams = new ExportParams("员工信息", "数据",ExcelType.XSSF);
// 直接使用EasyPOI提供的方法
Workbook workbook = ExcelExportUtil.exportExcel(exportParams, User.class, userList);
String filename="员工信息.xlsx";
// 设置文件的打开方式和mime类型
ServletOutputStream outputStream = response.getOutputStream();
response.setHeader( "Content-Disposition", "attachment;filename=" + new String(filename.getBytes(),"ISO8859-1"));
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
workbook.write(outputStream);
}
有导出就应该有导入,我们就把刚才导出的数据库导入到表中
Excel导入时需要的参数类ImportParams常用设置说明
有图片的导出就有图片的导入,导入的配置和导出是一样的,但是需要设置保存路径 1.设置保存路径saveUrl 默认为"upload/excelUpload" 可以手动修改 ImportParams 修改下就可以了
第一步:修改实体类,表明哪些需要导入
package com.itheima.pojo;
import cn.afterturn.easypoi.excel.annotation.Excel;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import tk.mybatis.mapper.annotation.KeySql;
import javax.persistence.Id;
import javax.persistence.Table;
import java.util.Date;
import java.util.List;
/**
* 员工
*/
@Data
@Table(name="tb_user")
public class User {
@Id
@KeySql(useGeneratedKeys = true)
@Excel(name = "编号", orderNum = "0", width = 5)
private Long id; //主键
@Excel(name = "员工名", orderNum = "1", width = 15,isImportField="true")
private String userName; //员工名
@Excel(name = "手机号", orderNum = "2", width = 15,isImportField="true")
private String phone; //手机号
@Excel(name = "省份名", orderNum = "3", width = 15,isImportField="true")
private String province; //省份名
@Excel(name = "城市名", orderNum = "4", width = 15,isImportField="true")
private String city; //城市名
@Excel(name = "工资", orderNum = "5", width = 10, type=10, isImportField="true") //type=10表示会导出数字
private Integer salary; // 工资
@JsonFormat(pattern="yyyy-MM-dd")
@Excel(name = "入职日期", format = "yyyy-MM-dd",orderNum = "6", width = 15,isImportField="true")
private Date hireDate; // 入职日期
private String deptId; //部门id
@Excel(name = "出生日期", format = "yyyy-MM-dd",orderNum = "7", width = 15,isImportField="true")
private Date birthday; //出生日期
@Excel(name = "照片", orderNum = "10",width = 15,type = 2,isImportField="true",savePath = "D:\\java_report\\workspace\\user_management\\src\\main\\resources\\static\\user_photos\\")
private String photo; //一寸照片
@Excel(name = "现在居住地址", orderNum = "9", width = 30,isImportField="true")
private String address; //现在居住地址
private List<Resource> resourceList; //办公用品
}
第二步:修改UserController中的导入方法
@PostMapping(value = "/uploadExcle", name = "上传用户数据")
public void uploadExcle(MultipartFile file) throws Exception{
// userService.uploadExcle(file);
userService.uploadExcleWithEasyPOI(file);
}
第三步:在UserService中添加使用easyPOI导入的方法
public void uploadExcleWithEasyPOI(MultipartFile file) throws Exception {
ImportParams importParams = new ImportParams();
importParams.setTitleRows(1); //有多少行的标题
importParams.setHeadRows(1);//有多少行的头
List<User> userList = ExcelImportUtil.importExcel(file.getInputStream(),User.class,importParams);
System.out.println(userList);
for (User user : userList) {
user.setId(null);
userMapper.insertSelective(user);
}
}
模板是处理复杂Excel的简单方法,复杂的Excel样式,可以用Excel直接编辑,完美的避开了代码编写样式的雷区,同时指令的支持,也提了模板的有效性
采用的写法是{{}}代表表达式,然后根据表达式里面的数据取值
关于样式问题
easypoi不会改变excel原有的样式
需求:导出用户的详细信息,这个功能我们做过,今天我们使用easyPOI的方式再做一次
第一步:制作模板
这个模板和我们做的userInfo2.xlsx模板一样,只是这个变量使用了{{}}包起来了
第二步:放到项目中
第三步:改写UserController中导出用户信息的方法
@GetMapping(value = "/download",name = "导出用户详细信息")
public void downLoadUserInfoWithTempalte(Long id,HttpServletRequest request,HttpServletResponse response) throws Exception{
// userService.downLoadUserInfoWithTempalte(id,request,response);
// userService.downLoadUserInfoWithTempalte2(id,request,response);
userService.downLoadUserInfoWithEastPOI(id,request,response);
}
第四步:完成UserService中的方法
public void downLoadUserInfoWithEastPOI(Long id, HttpServletRequest request, HttpServletResponse response) throws Exception {
// 获取模板的路径
File rootPath = new File(ResourceUtils.getURL("classpath:").getPath()); //SpringBoot项目获取根目录的方式
File templatePath = new File(rootPath.getAbsolutePath(),"/excel_template/userInfo3.xlsx");
// 读取模板文件
TemplateExportParams params = new TemplateExportParams(templatePath.getPath(),true);
// 查询用户,转成map
User user = userMapper.selectByPrimaryKey(id);
Map<String, Object> map = EntityUtils.entityToMap(user);
ImageEntity image = new ImageEntity();
// image.setHeight(640); //测试发现 这里设置了长度和宽度在合并后的单元格中没有作用
// image.setWidth(380);
image.setRowspan(4);//向下合并三行
image.setColspan(2);//向右合并两列
image.setUrl(user.getPhoto());
map.put("photo", image);
Workbook workbook = ExcelExportUtil.exportExcel(params, map);
// 导出的文件名称
String filename="用户详细信息数据.xlsx";
// 设置文件的打开方式和mime类型
ServletOutputStream outputStream = response.getOutputStream();
response.setHeader( "Content-Disposition", "attachment;filename=" + new String(filename.getBytes(),"ISO8859-1"));
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
workbook.write(outputStream);
}
csv的导出基本上和excel的导出一致,大体参数也是一致的
CsvExportParams 的参数描述如下
属性 | 类型 | 默认值 | 功能 |
---|---|---|---|
encoding | String | UTF8 | 文件编码 |
spiltMark | String | , | 分隔符 |
textMark | String | “ | 字符串识别,可以去掉,需要前后一致 |
titleRows | int | 0 | 表格头,忽略 |
headRows | int | 1 | 标题 |
exclusions | String[] | 0 | 忽略的字段 |
需求:改写之前使用OpenCSV导出csv文件
第一步:修改UserController方法
@GetMapping(value = "/downLoadCSV",name = "导出用户数据到CSV文件中")
public void downLoadCSV(HttpServletResponse response) throws Exception{
// userService.downLoadCSV(response);
userService.downLoadCSVWithEasyPOI(response);
}
第二步:完成UserService方法
public void downLoadCSVWithEasyPOI(HttpServletResponse response) throws Exception {
ServletOutputStream outputStream = response.getOutputStream();
// 文件名
String filename="百万数据.csv";
// 设置两个头 一个是文件的打开方式 一个是mime类型
response.setHeader( "Content-Disposition", "attachment;filename=" + new String(filename.getBytes(),"ISO8859-1"));
response.setContentType("application/csv");
// 创建一个用来写入到csv文件中的writer
CsvExportParams params = new CsvExportParams();
// 设置忽略的列
params.setExclusions(new String[]{"照片"}); //这里写表头 中文
List<User> list = userMapper.selectAll();
CsvExportUtil.exportCsv(params, User.class, list, outputStream);
}
说明:从上述的代码中你会发现,如果需要导出几百万数据时不可能全部加载到一个List中的,所以easyPOI的方式导出csv是支持不了太大的数据量的,如果导出几百万条数据还是得选择OpenCSV方式导出。
Excel注解详细
属性 | 类型 | 类型 | 说明 |
---|---|---|---|
name | String | null | 列名 |
needMerge | boolean | fasle | 纵向合并单元格 |
orderNum | String | “0” | 列的排序,支持name_id |
replace | String[] | {} | 值得替换 导出是{a_id,b_id} 导入反过来 |
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 | “” | 文字后缀,如% 90 变成90% |
isWrap | boolean | true | 是否换行 即支持\n |
mergeRely | int[] | {} | 合并单元格依赖关系,比如第二列合并是基于第一列 则{1}就可以了 |
mergeVertical | boolean | fasle | 纵向合并内容相同的单元格 |
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。