在管理一个系统时,总会有许多的数据,为了方便浏览查看数据,系统总会提供「导出Excel」的功能;有导出就有导入,在要向数据库中插入大量的数据时,我们向程序提供准备好的 Excel,然后程序读取表格内容,并将数据添加到数据库中。实现这个「导入/导出 Excel」的功能也不复杂,我们使用第三方的类库即可实现。
比如: Apache poi、Java Excel(JXL)和阿里巴巴开源的 Easyexcel 等。
这么多类库该怎么选呢?在这里我给大家推荐阿里巴巴开源的「Easyexcel」。
方法名 | 返回值 | 作用 |
---|---|---|
getContentType() | String | 返回文件的内容类型 |
getlnputStream() | InputStream | 返回InputStream读取文件的内容 |
getName() | String | 返回参数的名称 |
getOriginalFilename() | String | 获取上传文件件的原名 |
getSize() | long | 返回文件大小 以字节为单位 |
isEmpty() | boolean | 判断是否为空,或者上传的文件是否有内容 |
transferTo(File dest) | void | 用来把 MultipartFile 转换换成 File,将数据保存到一个目标文件中 |
getBytes() | byte[] | 将文件内容转化成一个byte[] 返回 |
Excel解析流程图:
EasyExcel读取Excel的解析原理:
在数据模型的字段上加@ExcelIgnore注解排除
@ExcelIgnore
private String password;
@ExcelProperty注解的value属性是一个数组类型, 设置多个head时会自动合并.
@NoArgsConstructor
@AllArgsConstructor
@Data
@Builder
public class ComplexHeadUser {
@ExcelProperty(value = {
"group1", "用户编号"}, index = 0)
private Integer userId;
@ExcelProperty(value = {
"group1", "姓名"}, index = 1)
private String userName;
@ExcelProperty(value = {
"group2", "入职时间"}, index = 2)
private Date hireDate;
// lombok 会生成getter/setter方法
}
对于日期和数字,有时候需要对其展示的样式进行格式化, EasyExcel提供了以下注解
@DateTimeFormat 日期格式化
@NumberFormat 数字格式化(小数或百分数)
@NoArgsConstructor
@AllArgsConstructor
@Data
@Builder
public class User {
@ExcelProperty(value = "用户编号", index = 0)
private Integer userId;
@ExcelProperty(value = "姓名", index = 1)
private String userName;
@ExcelProperty(value = "性别", index = 3)
private String gender;
@ExcelProperty(value = "工资", index = 4)
@NumberFormat(value = "###.#") // 数字格式化,保留1位小数
private Double salary;
@ExcelProperty(value = "入职时间", index = 2)
@DateTimeFormat(value = "yyyy年MM月dd日 HH时mm分ss秒") // 日期格式化
private Date hireDate;
// lombok 会生成getter/setter方法
}
@HeadRowHeight(value = 30) // 头部行高
@ContentRowHeight(value = 25) // 内容行高
@ColumnWidth(value = 20) // 列宽, 可以作用在类或字段上
@NoArgsConstructor
@AllArgsConstructor
@Data
@Builder
@HeadRowHeight(value = 30) // 头部行高
@ContentRowHeight(value = 25) // 内容行高
@ColumnWidth(value = 20) // 列宽
public class WidthAndHeightData {
@ExcelProperty(value = "字符串标题")
private String string;
@ExcelProperty(value = "日期标题")
private Date date;
@ExcelProperty(value = "数字标题")
@ColumnWidth(value = 25)
private Double doubleData;
// lombok 会生成getter/setter方法
}
@NoArgsConstructor
@AllArgsConstructor
@Data
@Builder
@HeadRowHeight(value = 30) // 头部行高
@ContentRowHeight(value = 25) // 内容行高
@ColumnWidth(value = 20) // 列宽
// 头背景设置成红色 IndexedColors.RED.getIndex()
@HeadStyle(fillPatternType = FillPatternType.SOLID_FOREGROUND, fillForegroundColor = 10)
// 头字体设置成20, 字体默认宋体
@HeadFontStyle(fontName = "宋体", fontHeightInPoints = 20)
// 内容的背景设置成绿色 IndexedColors.GREEN.getIndex()
@ContentStyle(fillPatternType = FillPatternType.SOLID_FOREGROUND, fillForegroundColor = 17)
// 内容字体设置成20, 字体默认宋体
@ContentFontStyle(fontName = "宋体", fontHeightInPoints = 20)
public class DemoStyleData {
// 字符串的头背景设置成粉红 IndexedColors.PINK.getIndex()
@HeadStyle(fillPatternType = FillPatternType.SOLID_FOREGROUND, fillForegroundColor = 14)
// 字符串的头字体设置成20
@HeadFontStyle(fontHeightInPoints = 30)
// 字符串的内容背景设置成天蓝 IndexedColors.SKY_BLUE.getIndex()
@ContentStyle(fillPatternType = FillPatternType.SOLID_FOREGROUND, fillForegroundColor = 40)
// 字符串的内容字体设置成20,默认宋体
@ContentFontStyle(fontName = "宋体", fontHeightInPoints = 20)
@ExcelProperty(value = "字符串标题")
private String string;
@ExcelProperty(value = "日期标题")
private Date date;
@ExcelProperty(value = "数字标题")
private Double doubleData;
// lombok 会生成getter/setter方法
}
@NoArgsConstructor
@AllArgsConstructor
@Data
@Builder
@HeadRowHeight(value = 25) // 头部行高
@ContentRowHeight(value = 20) // 内容行高
@ColumnWidth(value = 20) // 列宽
/**
* @OnceAbsoluteMerge 指定从哪一行/列开始,哪一行/列结束,进行单元格合并
* firstRowIndex 起始行索引,从0开始
* lastRowIndex 结束行索引
* firstColumnIndex 起始列索引,从0开始
* lastColumnIndex 结束列索引
*/
// 例如: 第2-3行,2-3列进行合并
@OnceAbsoluteMerge(firstRowIndex = 1, lastRowIndex = 2, firstColumnIndex = 1, lastColumnIndex = 2)
public class DemoMergeData {
// 每隔两行合并一次(竖着合并单元格)
// @ContentLoopMerge(eachRow = 2)
@ExcelProperty(value = "字符串标题")
private String string;
@ExcelProperty(value = "日期标题")
private Date date;
@ExcelProperty(value = "数字标题")
private Double doubleData;
// lombok 会生成getter/setter方法
}
在实际应用场景中, 我们系统db存储的数据可以是枚举, 在界面或导出到Excel文件需要展示为对于的枚举值形式.
比如: 性别, 状态等. EasyExcel提供了转换器接口Converter供我们使用, 我们只需要自定义转换器实现接口, 并将自定义转换器类型传入要转换的属性字段中. 以下面的性别gender字段为例:
@NoArgsConstructor
@AllArgsConstructor
@Data
@Builder
public class UserModel {
@ExcelProperty(value = "用户编号", index = 0)
private Integer userId;
@ExcelProperty(value = "姓名", index = 1)
private String userName;
// 性别添加了转换器, db中存入的是integer类型的枚举 0 , 1 ,2
@ExcelProperty(value = "性别", index = 3, converter = GenderConverter.class)
private Integer gender;
@ExcelProperty(value = "工资", index = 4)
@NumberFormat(value = "###.#")
private Double salary;
@ExcelProperty(value = "入职时间", index = 2)
@DateTimeFormat(value = "yyyy年MM月dd日 HH时mm分ss秒")
private Date hireDate;
// lombok 会生成getter/setter方法
}
/**
* 类描述:性别字段的数据转换器
* @Author wang_qz
* @Date 2021/8/15 19:16
* @Version 1.0
*/
public class GenderConverter implements Converter<Integer> {
private static final String MALE = "男";
private static final String FEMALE = "女";
private static final String NONE = "未知";
// Java数据类型 integer
@Override
public Class supportJavaTypeKey() {
return Integer.class;
}
// Excel文件中单元格的数据类型 string
@Override
public CellDataTypeEnum supportExcelTypeKey() {
return CellDataTypeEnum.STRING;
}
// 读取Excel文件时将string转换为integer
@Override
public Integer convertToJavaData(CellData cellData, ExcelC