概念

转换器

将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());
    }
}

导出文件结果 ruoyi-sub-execl