# Commons

Apache Commons是一个非常有用的工具包,解决平时编程经常会遇到的问题,减少重复劳动。
官网网址 (opens new window)

# Commons BeanUtils

针对Bean的一个工具集。

# Commons Codec

是编码和解码组件,提供常用的编码和解码方法,如DES、SHA1、MD5、Base64、URL和Soundx等。

# Commons Collections

是一个集合组件,扩展了Java标准Collections API,对常用的集合操作进行了很好的封装、抽象和补充,在保证性能的同时大大简化代码。

我们先来浏览一下它的包结构。一共是12个:

  • org.apache.commons.collections – CommonsCollections自定义的一组公用的接口和工具类
  • org.apache.commons.collections.bag – 实现Bag接口的一组类
  • org.apache.commons.collections.bidimap – 实现BidiMap系列接口的一组类
  • org.apache.commons.collections.buffer – 实现Buffer接口的一组类
  • org.apache.commons.collections.collection –实现java.util.Collection接口的一组类
  • org.apache.commons.collections.comparators– 实现java.util.Comparator接口的一组类
  • org.apache.commons.collections.functors –Commons Collections自定义的一组功能类
  • org.apache.commons.collections.iterators – 实现java.util.Iterator接口的一组类
  • org.apache.commons.collections.keyvalue – 实现集合和键/值映射相关的一组类
  • org.apache.commons.collections.list – 实现java.util.List接口的一组类
  • org.apache.commons.collections.map – 实现Map系列接口的一组类
  • org.apache.commons.collections.set – 实现Set系列接口的一组类

# Commons Compress

是一个压缩、解压缩文件的组件,可以操作rar、cpio、Unix dump、tar、zip、gzip、XZ、Pack200和bzip2格式的压缩文件。

# Commons Configuration

是一个Java应用程序的配置管理工具,可以从properties或者xml文件中加载配置信息。

# Commons CSV

是一个用来读写各种Comma Separated Value(CSV)格式文件的Java类库。

# Commons Daemon

实现将普通的Java应用变成系统的后台服务,例如 Tomcat 就是利用这个项目来实现作为 Linux 和 Windows 的服务启动和停止的。

# Commons DBCP

数据库连接池。

# Commons DBUtils

是JDBC工具组件,对传统操作数据库的类进行二次封装,可以把结果集转化成List。

# Commons Digester

是XML到Java对象的映射工具集。

# Commons Email

是邮件操作组件,对Java Mail API进行了封装,提供了常用的邮件发送和接收类,简化邮件操作。该组件依赖Java Mail API。

# Commons Exec

提供一些常用的方法用来执行外部进程,如执行exe文件或命令行。

# Commons FileUpload

为Web应用程序或Servlet提供文件上传功能,Struts2和SpringMVC的文件上传组件。

# Commons IO

是处理IO的工具类包,对java.io进行扩展,提供了更加方便的IO操作。

# Commons Lang3

是处理Java基本对象方法的工具类包,该类包提供对字符、数组等基本对象的操作,弥补了java.lang api基本处理方法上的不足。

  • ArrayUtils – 用于对数组的操作,如添加、查找、删除、子数组、倒序、元素类型转换等;
  • BitField – 用于操作位元,提供了一些方便而安全的方法;
  • BooleanUtils – 用于操作和转换boolean或者Boolean及相应的数组;
  • CharEncoding – 包含了Java环境支持的字符编码,提供是否支持某种编码的判断;
  • CharRange – 用于设定字符范围并做相应检查;
  • CharSet – 用于设定一组字符作为范围并做相应检查;
  • CharSetUtils – 用于操作CharSet;
  • CharUtils – 用于操作char值和Character对象;
  • ClassUtils – 用于对Java类的操作,不使用反射;
  • ObjectUtils – 用于操作Java对象,提供null安全的访问和其他一些功能;
  • RandomStringUtils – 用于生成随机的字符串;
  • SerializationUtils – 用于处理对象序列化,提供比一般Java序列化更高级的处理能力;
  • StringEscapeUtils – 用于正确处理转义字符,产生正确的Java、JavaScript、HTML、XML和SQL代码;
  • StringUtils – 处理String的核心类,提供了相当多的功能;
  • SystemUtils – 在java.lang.System基础上提供更方便的访问,如用户路径、Java版本、时区、操作系统等判断;
  • Validate – 提供验证的操作,有点类似assert断言;
  • WordUtils – 用于处理单词大小写、换行等。

# Commons Logging

提供统一的日志接口,同时兼顾轻量级和不依赖于具体的实现。类包给中间件/日志工具开发者一个简单的日志操作抽象,允许程序开发人员使用不同的具体日志实现工具。

# Commons Math

轻量级自容器的数学和统计计算方法类包,包含大多数常用的数值算法。

# Commons Net

封装了各种网络协议的客户端,支持FTP、NNTP、SMTP、POP3、Telnet等协议。

# Commons Validator

提供了一个简单的、可扩展的框架来在一个XML文件中定义校验器(校验方法)和校验规则。支持校验规则的和错误消息的国际化。

# Apache HttpClient

曾经是Apache Commons的子项目,后来独立出来。HttpClient简化HTTP客户端与服务器的各种通讯,实现HTTP客户端程序(也就是浏览器程序)的功能。

# Hutool

Hutool (opens new window) = Hu + tool,是原公司项目底层代码剥离后的开源库,"Hu"是公司名称的表示,tool表示工具。Hutool谐音"糊涂"。

在pom文件中添加以下内容,最新的版本可以去官网查看

<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.8.16</version>
</dependency>

# 目前已包含的组件

  • hutool-aop:JDK动态代理封装,提供非IOC下的切面支持
  • hutool-bloomFilter:布隆过滤,提供一些Hash算法的布隆过滤
  • hutool-cache:简单缓存实现
  • hutool-core:核心,包括Bean操作、日期、各种Util等
  • hutool-cron:定时任务模块,提供类Crontab表达式的定时任务
  • hutool-crypto:加密解密模块,提供对称、非对称和摘要算法封装
  • hutool-db:JDBC封装后的数据操作,基于ActiveRecord思想
  • hutool-dfa:基于DFA模型的多关键字查找
  • hutool-extra:扩展模块,封装第三方(模板引擎、邮件、Servlet、二维码、Emoji、FTP、分词等)
  • hutool-http:基于HttpUrlConnection的Http客户端封装
  • hutool-log:自动识别日志实现的日志门面
  • hutool-script:脚本执行封装,例如Javascript
  • hutool-setting:功能更强大的Setting配置文件和Properties封装
  • hutool-system:系统参数调用封装(JVM信息等)
  • hutool-json:JSON实现
  • hutool-captcha:图片验证码实现
  • hutool-poi:针对POI中Excel和Word的封装
  • hutool-socket:基于Java的NIO和AIO的Socket封装
  • hutool-jwt:JSON Web Token (JWT)封装实现

# Lombok

是一个在Java开发过程中用注解的方式,简化了 JavaBean 的编写,避免了冗余和样板式代码而出现的插件,让编写的类更加简洁

# Lombok的安装

  • 先在idea中安装Lombok插件,File —> Settings —> Plugins —> Browse repositories —> 搜索lombok
  • 在项目pom.xml中添加相关依赖
<dependency>
  <groupId>org.projectlombok</groupId>
  <artifactId>lombok</artifactId>
  <version>1.16.10</version>
</dependency>

# 注解简介

@NonNull:用在成员方法或构造方法的参数前面,会自动检查此参数是否为空,如果为空,则抛出空指针异常
@CleanUp:自动资源管理,不用再在finally中添加资源的close方法

@Setter/@Getter:自动生成set和get方法
@ToString:自动生成toString方法
@EqualsAndHashcode:从对象的字段中生成hashCode和equals的实现
@NoArgsConstructor/@RequiredArgsConstructor/@AllArgsConstructor:自动生成构造方法
@Data:自动生成set/get方法,toString方法,equals方法,hashCode方法,不带参数的构造方法

@Value:用于注解final@Builder:产生复杂的构建器api类

@SneakyThrows:异常处理(谨慎使用)

@Synchronized :同步方法安全的转化

@Getter(lazy=true)@Log:支持各种logger对象,使用时用对应的注解,如:@Log4j

# fastjson

在 Fastjson 2.x 版本中,默认情况下是不支持下划线(“_”)和驼峰式命名的自动匹配的。这是由于 Fastjson 2.x 的命名策略发生了改变,它采用了新的命名规则,使用了更严格的名称匹配方法

# fastjson2中Json下划线转Java驼峰命名

  • 方案一: JsonField
public class ConvertConfig {
    @JSONField(name = "server_type")
    public String serverType;

    @JSONField(name = "client_type")
    public String clientType;
}
  • 方案二:Feature,解析时传入特性,支持智能匹配
JSONObject.parseObject(Files.readString(path), clazz, Feature.SupportSmartMatch);

# fastjson序列化

  • JsonObject序列化:JsonObject是一种键值对的集合,可以将Java对象转换成JSON字符串
JsonObject json = new JsonObject();
json.put('name', 'zhangsan');
json.put('age', 20);
String str = json.toString();
  • JavaBean序列化
User user = new User();
user.setName('zhangsan');
user.setAge(20);
String str = JSON.toJSONString(user);
  • JsonArray序列化:JsonArray是一个集合对象,它可以将对象、数组等对象放到JsonArray集合中,然后将其转换成JSON字符串
JsonArray jsonArray = new JsonArray();
List<User> list = getUserList();
//将List集合放入jsonArray中
jsonArray.addAll(list);
String str = jsonArray.toString();

# JSON反序列化

  • JsonObject反序列化:可以将JSON字符串反序列化成JsonObject对象,用以获取相关信息
String str = '{name'zhangsan',age:20}';
JsonObject json = JSON.parseObject(str);
String name = json.getString('name');
int age = json.getIntValue('age');
  • JavaBean反序列化:可以将JSON字符串反序列化成JavaBean对象
String str = '{name:'zhangsan',age:20}';
User user = JSON.parseObject(str, User.class);
  • JsonArray反序列化:可以将JSON字符串反序列化成JsonArray对象,然后获取相关的内容
String str = '[{na 'zhangsan', age: 20},{na 'lisi', age: 21}]';
JsonArray jsonArray = JSON.parseArray(str);
for(Object obj : jsonArray){
    JSONObject jsonObject = (JSONObject)obj;
    String name = jsonObject.getString('name');
    int age = jsonObject.getIntValue('age');
    System.out.println('na' + name + 'age:' + age);
}

解决jackson反序列化抽象类属性时报错

使用springboot的@RequestBody接收参数时,遇到报错abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information。 接收的参数含有接口类型的字段,导致jackson不知道反序列化成什么实例

# log4j

  • 引入日志包
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.15</version>
</dependency>
  • 创建日志文件log4j.properties
### direct log messages to stdout ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### direct messages to file mylog.log ###
log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=c:/mylog.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### set log levels - for more verbose logging change 'info' to 'debug' ###

log4j.rootLogger=info, stdout
  • 在mybatis-config.xml中添加如下配置开启日志
<settings>
   <setting name="logImpl" value="LOG4J" />
</settings>

# Thumbnails

Thumbnails导入依赖

<dependency>
 <groupId>net.coobird</groupId>
 <artifactId>thumbnailator</artifactId>
 <version>0.4.8</version>
</dependency>

# 指定大小进行缩放

//size(int width, int height) 按比例,使原图撑满size大小;
 
/* 
 * 若图片横比200小,高比300小,不变 
 * 若图片横比200小,高比300大,高缩小到300,图片比例不变 
 * 若图片横比200大,高比300小,横缩小到200,图片比例不变 
 * 若图片横比200大,高比300大,图片按比例缩小,横为200或高为300 
 */ 
Thumbnails.of("images/a380_1280x1024.jpg") 
 .size(200, 300) 
 .toFile("c:/a380_200x300.jpg"); 
 
Thumbnails.of("images/a380_1280x1024.jpg") 
 .size(2560, 2048) 
 .toFile("c:/a380_2560x2048.jpg");

# 按照比例进行缩放

File file = new File("c:\\test.png");
//3.0是一个double类型的数字,缩放比例,大于1就是变大,小于1就是缩小
Thumbnails.of(new FileInputStream(file)).scale(3.0).toFile(new File("c:\\yyyyy.png"));

.width(int width) //设置宽,高按比例;
.height(int height) //设置高,宽按比例;
.forceSize(int width, int height) //设置宽高,不按比例,会按照设置的宽高拉伸;
.scale(double scale) //按比例缩放,0~1缩小,1原比例,>1放大;
.scale(double scaleWidth, double scaleHeight) //长宽各自设置比例,会拉伸;
  • 不按照比例,指定大小进行缩放
//keepAspectRatio(false) 默认是按照比例缩放的 
Thumbnails.of("images/aah.jpg").size(200, 200).keepAspectRatio(false).toFile("c:/aa.jpg");

.scalingMode(ScalingMode config) ScalingMode缩放模式(BICUBIC、BILINEAR、PROGRESSIVE_BILINEAR)
.keepAspectRatio(boolean keep) 设置是否按比例,false不按比例

注意

size、width/height、scale、forceSize不能并用;size相当于width+height;forceSize相当于设置长款+keepAspectRatio=false,所以forceSize不能跟其他设置长款属性、keepAspectRatio并用

# 生成缩略图

//批量产生缩略图
Thumbnails.of(new File("D:\\pics").listFiles()).scale(0.2).outputFormat("png")
 .toFiles(Rename.PREFIX_DOT_THUMBNAIL);
 
//控制图片质量,图片尺寸不变
File fromPic = new File("C:\\Users\\Administrator\\Desktop\\1531741954688.jpeg");
File toPic =new File("C:\\Users\\Administrator\\Desktop\\987136936_08.jpeg");
Thumbnails.of(fromPic).scale(1f).outputQuality(0.25f).toFile(toPic);

# 旋转

//rotate(double angle) 旋转角度,顺时针为正;
Thumbnails.of(fromPic).scale(0.5).rotate(90).toFile(toPic);

# 水印

//fromPic是原图,waterPic是水印图片,toPic是生成后的图片
Thumbnails.of(fromPic).scale(0.8)
 .watermark(Positions.BOTTOM_RIGHT, ImageIO.read(waterPic), 0.5f)
 .outputQuality(0.8f).toFile(toPic);
 
//watermark(位置,水印图,透明度) 
Thumbnails.of("images/a380_1280x1024.jpg") 
 .size(1280, 1024) 
 .watermark(Positions.BOTTOM_RIGHT, ImageIO.read(new File("images/watermark.png")), 0.5f) 
 .outputQuality(0.8f) 
 .toFile("c:/a380_watermark_bottom_right.jpg"); 

# 裁剪

//sourceRegion() 
Thumbnails.of(fromPic).sourceRegion(Positions.CENTER, 300, 300).scale(1.0).toFile(toPic);
 
//图片中心400*400的区域 
Thumbnails.of("images/a380_1280x1024.jpg") 
 .sourceRegion(Positions.CENTER, 400,400) 
 .size(200, 200) 
 .keepAspectRatio(false) 
 .toFile("c:/a380_region_center.jpg"); 
 
//图片右下400*400的区域 
Thumbnails.of("images/a380_1280x1024.jpg") 
 .sourceRegion(Positions.BOTTOM_RIGHT, 400,400) 
 .size(200, 200) 
 .keepAspectRatio(false) 
 .toFile("c:/a380_region_bootom_right.jpg"); 
 
//指定坐标 
Thumbnails.of("images/a380_1280x1024.jpg") 
 .sourceRegion(600, 500, 400, 400) 
 .size(200, 200) 
 .keepAspectRatio(false) 
 .toFile("c:/a380_region_coord.jpg");

# 转化图像格式

//outputFormat(图像格式) 
Thumbnails.of("images/a380_1280x1024.jpg") 
 .size(1280, 1024) 
 .outputFormat("png") 
 .toFile("c:/a380_1280x1024.png"); 
 
Thumbnails.of("images/a380_1280x1024.jpg") 
 .size(1280, 1024) 
 .outputFormat("gif") 
 .toFile("c:/a380_1280x1024.gif");

# 输出到OutputStream

某些应用上传的图片可能质量比较高,但是用户在列表浏览的时候,又不想原图展示,因为带宽要求较高,此时可以降低图片质量(上面提到的outputQuality),以outputstream输出流的方式response给浏览器去展示

@RequestMapping("/getImages")
public void getImages(HttpServletRequest request, HttpServletResponse response) throws IOException {
	Thumbnails.of("images/a380_1280x1024.jpg").
	scale(1f).
	outputQuality(0.5f).
	outputFormat("jpg").toOutputStream(response.getOutputStream());
}

# 输出到BufferedImage

//asBufferedImage() 返回BufferedImage 
BufferedImage thumbnail = Thumbnails.of("images/a380_1280x1024.jpg") 
 .size(1280, 1024) 
 .asBufferedImage(); 
 
ImageIO.write(thumbnail, "jpg", new File("c:/a380_1280x1024_BufferedImage.jpg"));

# 输出到ByteArrayOutputStream(OutputStream)

ByteArrayOutputStream thumbnailOutputStream = new ByteArrayOutputStream();
Thumbnails.of("images/a380_1280x1024.jpg").
   scale(1f).
   outputQuality(0.5f).
   outputFormat("jpg").toOutputStream(thumbnailOutputStream);

# 输出到ByteArrayInputStream(InputStream)

ByteArrayOutputStream thumbnailOutputStream = new ByteArrayOutputStream();
Thumbnails.of("images/a380_1280x1024.jpg").
   scale(1f).
   outputQuality(0.5f).
   outputFormat("jpg").toOutputStream(thumbnailOutputStream);
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(thumbnailOutputStream.toByteArray());

# 输出到byte[]

ByteArrayOutputStream handlerOutputStream = new ByteArrayOutputStream();
  Thumbnails.of(inputStream).
   scale(1f).
   outputQuality(0.25f).
   outputFormat("jpg").toOutputStream(handlerOutputStream);
byte[] bytes = handlerOutputStream.toByteArray();

# Excel

poi有两个不同的jar包,分别是处理excel2003和excel2007+的,对应的是poi和poi-ooxml。毕竟poi-ooxml是poi的升级版本,处理的单页数据量也是百万级别的,所以我们选择的也是poi-ooxml。

<!--poi对excel2007以上版本的支持-->
<dependency>
	<groupId>org.apache.poi</groupId>
	<artifactId>poi-ooxml</artifactId>
	<version>3.12</version>
</dependency>

# 注解参数说明

参数 类型 默认值 描述
sort int Integer.MAX_VALUE 导出时在excel中排序,值越小越靠前
name String 导出到Excel中的名字
dateFormat String 日期格式, 如: yyyy-MM-dd
dictType String 如果是字典类型,请设置字典的type值 (如: sys_user_sex)
readConverterExp String 读取内容转表达式 (如: 0=男,1=女,2=未知)
separator String , 分隔符,读取字符串组内容
scale int -1 BigDecimal 精度 默认:-1(默认不开启BigDecimal格式化)
roundingMode int BigDecimal
.ROUND_HALF_EVEN
BigDecimal 舍入规则 默认:BigDecimal.ROUND_HALF_EVEN
celltype Enum Type.STRING 导出类型(0数字 1字符串 2图片)
height String 14 导出时在excel中每个列的高度 单位为字符
width String 16 导出时在excel中每个列的宽 单位为字符
suffix String 文字后缀,如% 90 变成90%
defaultValue String 当值为空时,字段的默认值
prompt String 提示信息
combo String Null 设置只能选择不能输入的列内容
header
BackgroundColor
Enum IndexedColors
.GREY_50_PERCENT
导出列头背景色IndexedColors.XXXX
headerColor Enum IndexedColors.WHITE 导出列头字体颜色IndexedColors.XXXX
backgroundColor Enum IndexedColors.WHITE 导出单元格背景色IndexedColors.XXXX
color Enum IndexedColors.BLACK 导出单元格字体颜色IndexedColors.XXXX
targetAttr String 另一个类中的属性名称,支持多级获取,以小数点隔开
isStatistics boolean false 是否自动统计数据,在最后追加一行统计数据总和
type Enum Type.ALL 字段类型(0:导出导入;1:仅导出;2:仅导入)
align Enum HorizontalAlignment
.CENTER
导出对齐方式HorizontalAlignment.XXXX
handler Class ExcelHandlerAdapter
.class
自定义数据处理器
args String[] {} 自定义数据处理器参数

# 导出方法

@PostMapping("/export")
@ResponseBody
public AjaxResult export(User user)
{
	List<User> list = userService.selectUserList(user);
	ExcelUtil<User> util = new ExcelUtil<User>(User.class);
	return util.exportExcel(list, "用户数据");
	
	//导出用户管理表格新增标题(用户列表)
	return util.exportExcel(list, "用户数据", "用户列表");
}

# 导入方法

@PostMapping("/importData")
@ResponseBody
public AjaxResult importData(MultipartFile file) throws Exception
{
	ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class);
	List<SysUser> userList = util.importExcel(file.getInputStream());
	//导入表格包含标题处理方式,其中1表示标题占用行数
	List<SysUser> userList = util.importExcel(file.getInputStream(), 1);
	
	String message = userService.importUser(userList);
	return AjaxResult.success(message);
}

# 自定义数据处理器

  • 在实体类用Excel注解handler属性指定自定义的数据处理器
public class User extends BaseEntity
{
    @Excel(name = "用户名称", handler = MyDataHandler.class, args = { "aaa", "bbb" })
    private String userName;
}
  • 编写数据处理器MyDataHandler继承ExcelHandlerAdapter,返回值为处理后的值
public class MyDataHandler implements ExcelHandlerAdapter
{
    @Override
    public Object format(Object value, String[] args, Cell cell, Workbook wb)
    {
        // value 为返回单元格显示内容值
		// args 为excel注解传递的args数组值
		// cell 为单元格对象
		// wb 为工作簿对象
		return value;
    }
}
  • 编写示例,用户名为"若依"则单元格文字设置为红色
public class MyDataHandler implements ExcelHandlerAdapter
{
    @Override
    public Object format(Object value, String[] args, Cell cell, Workbook wb)
    {
        if ("若依".equals(value))
        {
            // 自定义用户名为若依/单元格文字设置为红色
            CellStyle style = wb.createCellStyle();
            style.setAlignment(HorizontalAlignment.CENTER);
            style.setVerticalAlignment(VerticalAlignment.CENTER);
            style.setBorderRight(BorderStyle.THIN);
            style.setRightBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
            style.setBorderLeft(BorderStyle.THIN);
            style.setLeftBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
            style.setBorderTop(BorderStyle.THIN);
            style.setTopBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
            style.setBorderBottom(BorderStyle.THIN);
            style.setBottomBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
            Font dataFont = wb.createFont();
            dataFont.setFontName("Arial");
            dataFont.setFontHeightInPoints((short) 10);
            dataFont.setColor(IndexedColors.RED.index);
            style.setFont(dataFont);
            cell.setCellStyle(style);
        }
        return value;
    }
}
  • 导出文件结果

导出文件结果

# 自定义隐藏属性列

对用户进行条件判断,符合条件则隐藏属性。导出的文件则不会显示此列信息

@PostMapping("/export")
public void export(HttpServletResponse response, SysUser user)
{
	List<SysUser> list = userService.selectUserList(user);
	ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class);
	if (条件A) {
	  // 不显示用户ID(单个)
	  util.hideColumn("userId");
	} else if (条件B) {
	  // 不显示用户名称、用户手机(多个)
	  util.hideColumn("userId", "phonenumber");
	} } else if (条件C) {
	  // 不显示用户邮箱、部门名称(子对象)
	  util.hideColumn("email", "dept.deptName");
	}
	util.exportExcel(response, list, "用户数据");
}

# 导入对象的子对象

有时候我们导入对象里面还包含对象,例如用户管理包含部门需要导入,那么我们可以进行如下处理

public class SysUser extends BaseEntity
{
    ...............

	/** 部门对象 */
	@Excels({
	@Excel(name = "部门名称", targetAttr = "deptName"),
	@Excel(name = "部门负责人", targetAttr = "leader"),
	@Excel(name = "部门状态", targetAttr = "status", dictType = "sys_normal_disable")
	})
	private SysDept dept = new SysDept();
}

# 导出对象的子列表

有时候对象里面还包含集合列表,例如用户管理包含多个角色需要导出,那么我们可以进行如下处理

//SysUser.java
public class SysUser
{
    @Excel(name = "用户编号", cellType = ColumnType.NUMERIC, width = 20, needMerge = true)
    private String userId;

    @Excel(name = "用户名称", width = 20, needMerge = true)
    private String userName;

    @Excel(name = "邮箱", width = 20, needMerge = true)
    private String email;

    @Excel(name = "角色")
    private List<SysRole> roles;
}

//SysRole.java
public class SysRole
{
    @Excel(name = "角色编号", cellType = ColumnType.NUMERIC)
    private String roleId;

    @Excel(name = "角色名称")
    private String roleName;

    @Excel(name = "角色字符")
    private String roleKey;
}

//测试验证
public class Test
{
    public static void main(String[] args) throws IOException
    {
        List<SysUser> userList = new ArrayList<SysUser>();

        SysUser user1 = new SysUser();
        List<SysRole> roles1 = new ArrayList<SysRole>();

        SysRole role1 = new SysRole();
        role1.setRoleId("1");
        role1.setRoleName("超级管理员");
        role1.setRoleKey("admin_key");

        SysRole role2 = new SysRole();
        role2.setRoleId("2");
        role2.setRoleName("普通角色");
        role2.setRoleKey("common_key");
        
        SysRole role3 = new SysRole();
        role3.setRoleId("3");
        role3.setRoleName("测试角色");
        role3.setRoleKey("test_key");
        
        SysRole role4 = new SysRole();
        role4.setRoleId("4");
        role4.setRoleName("查询角色");
        role4.setRoleKey("query_key");

        roles1.add(role1);
        roles1.add(role2);
        roles1.add(role3);
        roles1.add(role4);

        user1.setUserId("1");
        user1.setUserName("admin");
        user1.setEmail("ry@qq.com");
        user1.setRoles(roles1);

        userList.add(user1);
		
        ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class);
        AjaxResult ajax = util.exportExcel(userList, "用户数据", "用户数据");
        System.out.println(ajax.toString());
    }
}

导出文件结果

导出文件结果