概念
转换器
将java的数据类型(含自定义的类)转为excel数据类型
将excel的数据类型转为java数据类型
思路
在开发中遇到我们需要将实体类中自定义的数据类型转化为excel中的格式,因为不能将自定义的类输出到excel中,只能用基本数据类型,所以需要转换(以下代码转换到excel为string类型,可以控制输出到excel中为某种基本数据类型)
将excel中的格式转化为我们实体类中的自定义数据类型,因为在用户修改excel数据时,可能会更改excel单元格式,所以我们需要判断单元格的格式,转为为我们实体类的固定的基本数据类型
步骤
在属性上加转换器类
写自定义转换器类,实现Converter <\AdditionalConfig> ,AdditionalConfig是自定义的数据类型
写转换代码
实体类:
public class DeviceInfoExcel {
/**
* 设备id
*/
@ExcelProperty(value="设备id",index=0)
@ColumnWidth(45)
private String deviceid;
/**
* 品牌名称
*/
@ExcelProperty(value="品牌名称",index=1)
@ColumnWidth(15)
private String brandName;
/**
* 价格
*/
@ExcelProperty(value="价格",index=8,converter = AdditionalConfigConverter.class)
@ColumnWidth(15)
private AdditionalConfig additionalConfig;
public AdditionalConfig getAdditionalConfig() {
return additionalConfig;
}
// 注意set,要这么写,才可以将转换之后的数据进行替换
public void setAdditionalConfig(AdditionalConfig additionalConfig) {
this.additionalConfig=additionalConfig;
}
自定义类型:
public class AdditionalConfig {
private double price;
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
}
转换器:
package cn.testin.util;
import cn.testin.api.cfg.bean.AdditionalConfig;
import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.CellData;
import com.alibaba.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.property.ExcelContentProperty;
public class AdditionalConfigConverter implements Converter<AdditionalConfig> {
//在java中数据类型
@Override
public Class supportJavaTypeKey() {
return AdditionalConfig.class;
}
// 在excel中的数据类型
@Override
public CellDataTypeEnum supportExcelTypeKey() {
return CellDataTypeEnum.STRING;
}
// 将excel的数据类型转为java数据类型
@Override
public AdditionalConfig convertToJavaData(CellData cellData, ExcelContentProperty excelContentProperty, GlobalConfiguration globalConfiguration) throws Exception {
AdditionalConfig additionalConfig =new AdditionalConfig();
CellDataTypeEnum type = cellData.getType();
String cellMsg = "";
// 转换格式,因为不确定excel中用户设置的单元格类型
if (type.equals(CellDataTypeEnum.NUMBER)) {
cellMsg = cellData.getNumberValue().toString();
} else if (type.equals(CellDataTypeEnum.STRING)) {
cellMsg = cellData.getStringValue();
} else if (type.equals(CellDataTypeEnum.BOOLEAN)) {
cellMsg = cellData.getBooleanValue().toString();
}
additionalConfig.setPrice(Double.parseDouble(cellMsg));
return additionalConfig;
}
// 将java的数据类型转为excel数据类型
@Override
public CellData<AdditionalConfig> convertToExcelData(AdditionalConfig additionalConfig, ExcelContentProperty excelContentProperty, GlobalConfiguration globalConfiguration) throws Exception {
return new CellData(String.valueOf(additionalConfig.getPrice()));
}
}
新增:
在实体变量上添加@Excel
注解,默认为导出导入,也可以单独设置仅导入Type.IMPORT
@Excel(name = "用户序号")
private Long id;
@Excel(name = "部门编号", type = Type.IMPORT)
private Long deptId;
@Excel(name = "用户名称")
private String userName;
/** 导出部门多个对象 */
@Excels({
@Excel(name = "部门名称", targetAttr = "deptName", type = Type.EXPORT),
@Excel(name = "部门负责人", targetAttr = "leader", type = Type.EXPORT)
})
private SysDept dept;
/** 导出部门单个对象 */
@Excel(name = "部门名称", targetAttr = "deptName", type = Type.EXPORT)
private SysDept dept;
自定义数据处理器
有时候我们希望数据展现为一个特殊的格式,或者需要对数据进行其它处理。Excel
注解提供了自定义数据处理器以满足各种业务场景。而实现一个数据处理器也是非常简单的。如下:
1、在实体类用Excel
注解handler
属性指定自定义的数据处理器
public class User extends BaseEntity
{
@Excel(name = "用户名称", handler = MyDataHandler.class, args = { "aaa", "bbb" })
private String userName;
}
2、编写数据处理器MyDataHandler
继承ExcelHandlerAdapter
,返回值为处理后的值。
public class MyDataHandler implements ExcelHandlerAdapter
{
@Override
public Object format(Object value, String[] args)
{
// value 为单元格数据值
// args 为excel注解args参数组
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");
}
util.exportExcel(response, list, "用户数据");
}
导出对象的子列表
有时候对象里面还包含集合列表,例如用户管理包含多个角色需要导出,那么我们可以进行如下处理。
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;
public String getUserId()
{
return userId;
}
public void setUserId(String userId)
{
this.userId = userId;
}
public String getUserName()
{
return userName;
}
public void setUserName(String userName)
{
this.userName = userName;
}
public String getEmail()
{
return email;
}
public void setEmail(String email)
{
this.email = email;
}
public List<SysRole> getRoles()
{
return roles;
}
public void setRoles(List<SysRole> roles)
{
this.roles = 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 String getRoleId()
{
return roleId;
}
public void setRoleId(String roleId)
{
this.roleId = roleId;
}
public String getRoleName()
{
return roleName;
}
public void setRoleName(String roleName)
{
this.roleName = roleName;
}
public String getRoleKey()
{
return roleKey;
}
public void setRoleKey(String roleKey)
{
this.roleKey = 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("[email protected]");
user1.setRoles(roles1);
userList.add(user1);
SysUser user2 = new SysUser();
List<SysRole> roles2 = new ArrayList<SysRole>();
SysRole role21 = new SysRole();
role21.setRoleId("4");
role21.setRoleName("研发角色");
role21.setRoleKey("yanfa_key");
SysRole role22 = new SysRole();
role22.setRoleId("5");
role22.setRoleName("销售角色");
role22.setRoleKey("xiaoshou_key");
roles2.add(role21);
roles2.add(role22);
user2.setUserId("2");
user2.setUserName("ry");
user2.setEmail("[email protected]");
user2.setRoles(roles2);
userList.add(user2);
SysUser user3 = new SysUser();
List<SysRole> roles3 = new ArrayList<SysRole>();
SysRole role31 = new SysRole();
role31.setRoleId("4");
role31.setRoleName("张三角色");
role31.setRoleKey("zs_key");
SysRole role32 = new SysRole();
role32.setRoleId("5");
role32.setRoleName("李四角色");
role32.setRoleKey("ls_key");
roles3.add(role31);
roles3.add(role32);
user3.setUserId("3");
user3.setUserName("test");
user3.setEmail("[email protected]");
user3.setRoles(roles3);
userList.add(user3);
ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class);
AjaxResult ajax = util.exportExcel(userList, "用户数据", "用户数据");
System.out.println(ajax.toString());
}
}
导出文件结果