之前写过一篇导出Excel文件的通用类的文章,当时只实现了导出数据到Excel的功能,这次在上次的基础上,增加从Excel读取数据到List的功能,依旧使用POI读取Excel文件。
1.在pom.xml中添加POI相关依赖
<dependency>
<groupId>org.apache.poigroupId>
<artifactId>poiartifactId>
<version>5.2.2version>
dependency>
<dependency>
<groupId>org.apache.poigroupId>
<artifactId>poi-ooxmlartifactId>
<version>5.2.2version>
dependency>
2.Excel字段注解类
package com.example.study.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface ExcelField {
/**
* 排序,该字段值越小,排序越前
*/
int ordinal() default 0;
/**
* 列宽,取值范围0-255,默认16,当列宽<0或>255时,使用默认列宽
*/
int columnWidth() default 16;
/**
* 字段名
*/
String columnName();
/**
* 时间类型的格式化,目前支持Date, LocalDate, LocalTime, LocalDateTime四种时间类型
*/
String format() default "yyyy-MM-dd HH:mm:ss";
}
3.Excel导入&导出工具类
package com.example.study.util;
import com.example.study.annotation.ExcelField;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.SimpleDateFormat;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAccessor;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
/**
* 导出Excel
*/
@Slf4j
public class ExcelUtil {
/**
* 读取excel文件内容到List中
*
* @param clazz 数据实体类的class
* @param excel excel文件
* @param 数据实体类
* @return 包含指定工作表内容的数据的list
*/
public static <T> List<T> read(Class<? extends T> clazz, String excel) {
return read(clazz, excel, null, 0);
}
/**
* 读取excel文件内容到List中
*
* @param clazz 数据实体类的class
* @param excel excel文件
* @param 数据实体类
* @return 包含指定工作表内容的数据的list
*/
public static <T> List<T> read(Class<? extends T> clazz, File excel) {
return read(clazz, excel, null, 0);
}
/**
* 读取excel文件内容到List中
*
* @param clazz 数据实体类的class
* @param inputStream excel文件
* @param 数据实体类
* @return 包含指定工作表内容的数据的list
*/
public static <T> List<T> read(Class<? extends T> clazz, InputStream inputStream) {
return read(clazz, inputStream, null, 0);
}
/**
* 读取excel文件内容到List中
*
* @param clazz 数据实体类的class
* @param excel excel文件
* @param sheetName 工作表名(默认取第一个工作表)
* @param 数据实体类
* @return 包含指定工作表内容的数据的list
*/
public static <T> List<T> read(Class<? extends T> clazz, String excel, String sheetName, Integer titleRowIndex) {
Assert.hasText(excel, "excel文件不能为空");
return read(clazz, new File(excel), sheetName, titleRowIndex);
}
/**
* 读取excel文件内容到List中
*
* @param clazz 数据实体类的class
* @param excel excel文件
* @param sheetName 工作表名(默认取第一个工作表)
* @param 数据实体类
* @return 包含指定工作表内容的数据的list
*/
public static <T> List<T> read(Class<? extends T> clazz, File excel, String sheetName, Integer titleRowIndex) {
Assert.notNull(excel, "excel文件不能为空");
try {
InputStream inputStream = new FileInputStream(excel);
return read(clazz, inputStream, sheetName, titleRowIndex);
} catch (FileNotFoundException exception) {
log.error("excel file not exists");
throw new IllegalArgumentException("excel文件不存在");
}
}
/**
* 读取excel文件内容到List中
*
* @param clazz 数据实体类的class
* @param inputStream excel文件
* @param sheetName 工作表名(默认取第1个工作表)
* @param titleRowIndex 标题所在行索引(起始地址为0,默认取第1行)
* @param 数据实体类
* @return 包含指定工作表内容的数据的list
*/
public static <T> List<T> read(Class<? extends T> clazz, InputStream inputStream, String sheetName, Integer titleRowIndex) {
Assert.notNull(clazz, "实体类不能为空");
Assert.notNull(inputStream, "excel文件不能为空");
if (titleRowIndex == null || titleRowIndex < 0) {
titleRowIndex = 0;
}
try (XSSFWorkbook workbook = new XSSFWorkbook(inputStream)) {
XSSFSheet sheet;
if (StringUtils.hasText(sheetName)) {
sheet = workbook.getSheet(sheetName);
} else {
sheet = workbook.getSheetAt(0);
}
Assert.notNull(sheet, "指定或默认的sheet不存在");
Map<Integer, Field> columnIndexFieldMap = readTitle(clazz, sheet, titleRowIndex);
Assert.notEmpty(columnIndexFieldMap, "在excel中未找到有效数据");
return readData(clazz, sheet, titleRowIndex, columnIndexFieldMap);
} catch (IOException | InstantiationException | IllegalAccessException exception) {
log.error("throw Exception when read excel:{}", exception.getMessage());
throw new IllegalArgumentException(exception.getMessage());
}
}
/**
* 读取excel数据
*
* @param clazz 数据实体类的class
* @param sheet 工作表对象
* @param titleRowIndex 标题所在行索引
* @param columnIndexFieldMap 列索引与数据实体类字段Field的映射map
* @param 数据实体类
* @return excel数据
* @throws IllegalAccessException 没有设置属性的权限
* @throws InstantiationException 实例化对象失败
*/
private static <T> List<T> readData(Class<? extends T> clazz, XSSFSheet sheet, Integer titleRowIndex, Map<Integer, Field> columnIndexFieldMap) throws IllegalAccessException, InstantiationException {
List<T> list = new ArrayList<>();
for (int rowIndex = titleRowIndex + 1; rowIndex <= sheet.getLastRowNum(); rowIndex++) {
XSSFRow row = sheet.getRow(rowIndex);
T data = clazz.newInstance();
for (Map.Entry<Integer, Field> entry : columnIndexFieldMap.entrySet()) {
Integer colIndex = entry.getKey();
Field field = entry.getValue();
Object value = getCell(row, colIndex, field.getType());
field.setAccessible(true);
field.set(data, value);
}
list.add(data);
}
return list;
}
/**
* 读取excel标题,获取列索引与数据实体类字段Field的映射map
*
* @param clazz 数据实体类的class
* @param sheet 工作表对象
* @param titleRowIndex 标题所在行索引
* @return 列索引与数据实体类字段Field的映射map
*/
private static Map<Integer, Field> readTitle(Class<?> clazz, XSSFSheet sheet, Integer titleRowIndex) {
List<FieldProperties> properties = getFieldProperties(clazz);
Map<String, Field> columnNameFieldMap = new HashMap<>();
for (FieldProperties property : properties) {
String columnName = property.getExcelField().columnName();
columnNameFieldMap.put(columnName, property.getField());
}
Map<Integer, Field> columnIndexFieldMap = new HashMap<>();
XSSFRow row = sheet.getRow(titleRowIndex);
Assert.notNull(row, "指定或默认的标题行不存在");
for (int columnIndex = 0; columnIndex < row.getLastCellNum(); columnIndex++) {
String titleName = getCell(row, columnIndex, String.class);
Field field = columnNameFieldMap.get(titleName);
if (field != null) {
columnIndexFieldMap.put(columnIndex, field);
}
}
return columnIndexFieldMap;
}
/**
* 获取单元格内容,单元格内容转为对应字段的类型
*
* @param row 行
* @param colIndex 列索引
* @param clazz 对应字段类型的class
* @param 对应字段类型
* @return 已转为对应字段类型的单元格内容
*/
private static <T> T getCell(XSSFRow row, int colIndex, Class<? extends T> clazz) {
XSSFCell cell = row.getCell(colIndex);
if (cell == null) {
cell = row.createCell(colIndex);
}
String name = clazz.getName();
Object cellValue;
switch (name) {
case "byte":
case "java.lang.Byte":
cellValue = (byte) cell.getNumericCellValue();
break;
case "short":
case "java.lang.Short":
cellValue = (short) cell.getNumericCellValue();
break;
case "int":
case "java.lang.Integer":
cellValue = (int) cell.getNumericCellValue();
break;
case "long":
case "java.lang.Long":
cellValue = (long) cell.getNumericCellValue();
break;
case "float":
case "java.lang.Float":
cellValue = (float) cell.getNumericCellValue();
break;
case "double":
case "java.lang.Double":
cellValue = cell.getNumericCellValue();
break;
case "char":
case "java.lang.Character":
cellValue = (char) cell.getNumericCellValue();
break;
case "boolean":
case "java.lang.Boolean":
cellValue = cell.getBooleanCellValue();
break;
case "java.util.Date":
cellValue = cell.getDateCellValue();
break;
case "java.time.LocalDate":
cellValue = cell.getLocalDateTimeCellValue() == null ? null : cell.getLocalDateTimeCellValue().toLocalDate();
break;
case "java.time.LocalTime":
cellValue = cell.getLocalDateTimeCellValue() == null ? null : cell.getLocalDateTimeCellValue().toLocalTime();
break;
case "java.time.LocalDateTime":
cellValue = cell.getLocalDateTimeCellValue();
break;
case "java.lang.String":
cellValue = cell.toString().trim();
break;
case "java.math.BigInteger":
String strValue = cell.toString().trim();
int dotIndex = strValue.indexOf('.');
if (dotIndex >= 0) {
strValue = strValue.substring(0, dotIndex);
}
cellValue = StringUtils.hasText(strValue) ? new BigInteger(strValue) : null;
break;
case "java.math.BigDecimal":
cellValue = StringUtils.hasText(cell.toString().trim()) ? new BigDecimal(cell.toString().trim()) : null;
break;
default:
cellValue = cell.toString().trim();
}
return (T) cellValue;
}
/**
* 导出excel文件
*
* @param collection 数据集合
* @param 数据实体类
* @return workbook对象
*/
public static <T> XSSFWorkbook write(Collection<T> collection) {
return write(collection, null, null);
}
/**
* 导出excel文件
*
* @param collection 数据集合
* @param clazz 数据实体类的class
* @param 数据实体类
* @return workbook对象
*/
public static <T> XSSFWorkbook write(Collection<T> collection, Class<?> clazz) {
return write(collection, clazz, null);
}
/**
* 导出excel文件
*
* @param collection 数据集合
* @param sheetName 工作表表名
* @param 数据实体类
* @return workbook对象
*/
public static <T> XSSFWorkbook write(Collection<T> collection, String sheetName) {
return write(collection, null, sheetName);
}
/**
* 导出excel文件
*
* @param collection 数据集合
* @param clazz 数据实体类的class
* @param sheetName 工作表表名
* @param 数据实体类
* @return workbook对象
*/
public static <T> XSSFWorkbook write(Collection<T> collection, Class<?> clazz, String sheetName) {
XSSFWorkbook workbook = new XSSFWorkbook();
XSSFSheet sheet = workbook.createSheet(StringUtils.hasText(sheetName) ? sheetName : "Sheet0");
XSSFCellStyle titleStyle = createCellStyle(workbook);
List<FieldProperties> properties = null;
if (clazz != null) {
properties = getFieldProperties(clazz);
writeTitle(sheet, properties, titleStyle);
}
if (collection == null || collection.isEmpty()) {
return workbook;
}
if (properties == null) {
Optional<T> any = collection.stream().filter(o -> o != null).findAny();
if (!any.isPresent()) {
return workbook;
}
properties = getFieldProperties(any.get().getClass());
writeTitle(sheet, properties, titleStyle);
}
try {
writeData(sheet, properties, collection);
} catch (IllegalAccessException exception) {
log.error("throw IllegalAccessException when writeData:{}", exception.getMessage());
}
return workbook;
}
/**
* 返回表头的单元格格式
*
* @param workbook workbook对象
* @return 绿色背景的单元格格式
*/
private static XSSFCellStyle createCellStyle(XSSFWorkbook workbook) {
XSSFCellStyle titleStyle = workbook.createCellStyle();
titleStyle.setFillForegroundColor(IndexedColors.GREEN.getIndex());
titleStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
return titleStyle;
}
/**
* 写入数据
*
* @param sheet 工作表
* @param properties 表头
* @param collection 数据
* @param 数据实体类
* @throws IllegalAccessException 访问数据字段值时无访问权限
*/
private static <T> void writeData(XSSFSheet sheet, List<FieldProperties> properties, Collection<T> collection) throws IllegalAccessException {
int rowIndex = 1;
XSSFRow row;
for (T element : collection) {
if (element == null) {
continue;
}
row = sheet.createRow(rowIndex++);
for (int index = 0; index < properties.size(); index++) {
FieldProperties property = properties.get(index);
Object value = property.getField().get(element);
if (value == null) {
continue;
}
String type = property.getField().getType().getSimpleName();
switch (type) {
case "Date":
SimpleDateFormat format = new SimpleDateFormat(property.getExcelField().format());
row.createCell(index).setCellValue(format.format(value));
break;
case "LocalDate":
case "LocalTime":
case "LocalDateTime":
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(property.getExcelField().format());
row.createCell(index).setCellValue(formatter.format((TemporalAccessor) value));
break;
default:
row.createCell(index).setCellValue(value.toString());
}
}
}
}
/**
* 写入表头
*
* @param sheet 工作表
* @param properties 表头
* @param titleStyle 表头格式
*/
private static void writeTitle(XSSFSheet sheet, List<FieldProperties> properties, XSSFCellStyle titleStyle) {
XSSFRow row = sheet.createRow(0);
for (int index = 0; index < properties.size(); index++) {
ExcelField excelField = properties.get(index).getExcelField();
String columnName = excelField.columnName();
XSSFCell cell = row.createCell(index);
cell.setCellValue(columnName);
cell.setCellStyle(titleStyle);
// 设置列宽
int columnWidth = excelField.columnWidth();
columnWidth = columnWidth < 0 || columnWidth > 255 ? 16 : columnWidth;
sheet.setColumnWidth(index, columnWidth * 256);
}
}
/**
* 获取表头字段
*
* @param clazz 数据实体类的class
* @return 排好序的表头字段
*/
private static List<FieldProperties> getFieldProperties(Class<?> clazz) {
Field[] declaredFields = clazz.getDeclaredFields();
List<FieldProperties> properties = new ArrayList<>();
for (Field declaredField : declaredFields) {
ExcelField excelField = declaredField.getAnnotation(ExcelField.class);
if (excelField == null) {
continue;
}
declaredField.setAccessible(true);
FieldProperties property = FieldProperties.builder().excelField(excelField).field(declaredField).build();
properties.add(property);
}
properties.sort((o1, o2) -> o1.getExcelField().ordinal() - o2.getExcelField().ordinal());
return properties;
}
@Getter
@Setter
@Builder
private static class FieldProperties {
private ExcelField excelField;
private Field field;
}
}
实体类:
package com.example.study.entity;
import com.example.study.annotation.ExcelField;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
import lombok.Getter;
import lombok.Setter;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.Date;
@Getter
@Setter
public class StudentEntity {
@ExcelField(columnName = "Bolid")
private Boolean bBolid;
@ExcelField(columnName = "bolid")
private boolean bolid;
@ExcelField(columnName = "Bid")
private Byte bBid;
@ExcelField(columnName = "bid")
private byte bid;
@ExcelField(columnName = "Sid")
private Short bSid;
@ExcelField(columnName = "sid")
private short sid;
@ExcelField(columnName = "Iid")
private Integer bIid;
@ExcelField(columnName = "iid")
private int iid;
@ExcelField(columnName = "Lid")
private Long bLid;
@ExcelField(columnName = "lid")
private long lid;
@ExcelField(columnName = "Fid")
private Float bFid;
@ExcelField(columnName = "fid")
private float fid;
@ExcelField(columnName = "Did")
private Double bDid;
@ExcelField(columnName = "did")
private double did;
@ExcelField(columnName = "Cid")
private Character bCid;
@ExcelField(columnName = "cid")
private char cid;
@ExcelField(columnName = "Bigid")
private BigInteger Bigid;
@ExcelField(columnName = "Decid")
private BigDecimal Decid;
@ExcelField(columnName = "id")
private Integer id;
@ExcelField(columnName = "生日")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date birthday;
@ExcelField(columnName = "LD生日")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
@JsonSerialize(using = LocalDateSerializer.class)
@JsonDeserialize(using = LocalDateDeserializer.class)
private LocalDate LdBirthday;
@ExcelField(columnName = "LT生日")
@JsonFormat(pattern = "HH:mm:ss", timezone = "GMT+8")
@JsonSerialize(using = LocalTimeSerializer.class)
@JsonDeserialize(using = LocalTimeDeserializer.class)
private LocalTime LtBirthday;
@ExcelField(columnName = "LDT生日")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@JsonSerialize(using = LocalDateTimeSerializer.class)
@JsonDeserialize(using = LocalDateTimeDeserializer.class)
private LocalDateTime LdtBirthday;
@ExcelField(columnName = "名字")
private String name;
@ExcelField(columnName = "性别")
private String sex;
}
测试代码:
package com.example.study.test;
import com.example.study.entity.StudentEntity;
import com.example.study.util.ExcelUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.File;
import java.io.FileInputStream;
import java.util.List;
public class ExcelUtilTest {
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
List<StudentEntity> read = ExcelUtil.read(StudentEntity.class, "F:\\tmp\\students.xlsx");
System.out.println(mapper.writeValueAsString(read));
read = ExcelUtil.read(StudentEntity.class, new File("F:\\tmp\\students.xlsx"));
System.out.println(mapper.writeValueAsString(read));
read = ExcelUtil.read(StudentEntity.class, new FileInputStream("F:\\tmp\\students.xlsx"));
System.out.println(mapper.writeValueAsString(read));
read = ExcelUtil.read(StudentEntity.class, "F:\\tmp\\students.xlsx", "sheet2", 1);
System.out.println(mapper.writeValueAsString(read));
read = ExcelUtil.read(StudentEntity.class, new File("F:\\tmp\\students.xlsx"), "sheet2", 1);
System.out.println(mapper.writeValueAsString(read));
read = ExcelUtil.read(StudentEntity.class, new FileInputStream("F:\\tmp\\students.xlsx"), "sheet2", 1);
System.out.println(mapper.writeValueAsString(read));
}
}
excel表内容如下:
sheet1(第一个工作表,左边和上边都没有空行,可使用默认参数):
名字 | id | 生日 | 性别 | Bolid | bolid | Bid | bid | Sid | sid | Iid | iid | Lid | lid | Fid | fid | Did | did | Cid | cid | Bigid | Decid | LD生日 | LT生日 | LDT生日 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
张三 | 1 | 1995/1/1 | 男 | TRUE | FALSE | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 65 | 97 | 1 | 1 | 1995/1/1 | 1995/1/1 | 1995/1/1 | |
李四 | 2 | 1995/1/2 | 男 | FALSE | TRUE | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 66 | 98 | 2 | 2 | 1995/1/2 | 1995/1/2 | 1995/1/2 | |
王冰冰 | 3 | 1995/1/3 | 女 | TRUE | FALSE | 3 | 3 | 3 | 3 | 3 | 3 | 3 | 3 | 3 | 3 | 3 | 67 | 99 | 3 | 3 | 1995/1/3 | 1995/1/3 | 1995/1/3 |
sheet2(第二个工作表,左边有四列空单元格,上边有一行空行,必须手动指定参数):
名字 | id | 生日 | 性别 | ||||
张三 | 1 | 1995/1/1 | 男 | ||||
李四 | 2 | 1995/1/2 | 男 | ||||
王冰冰 | 3 | 1995/1/3 | 女 |
执行结果如下:
19:46:44.624 [main] DEBUG org.apache.poi.openxml4j.opc.PackageRelationshipCollection - Parsing relationship: /xl/_rels/workbook.xml.rels
19:46:44.624 [main] DEBUG org.apache.poi.openxml4j.opc.PackageRelationshipCollection - Parsing relationship: /_rels/.rels
[{"bolid":false,"bid":1,"sid":0,"iid":1,"lid":1,"fid":1.0,"did":1.0,"cid":"a","id":1,"birthday":"1995-01-01 00:00:00","LdBirthday":"1995-01-01","LtBirthday":"00:00:00","LdtBirthday":"1995-01-01 00:00:00","name":"张三","sex":"男","biid":1,"bfid":1.0,"bdid":1.0,"bbolid":true,"bcid":"A","blid":1,"decid":1.0,"bigid":1,"bbid":1,"ltBirthday":{"hour":0,"minute":0,"second":0,"nano":0},"ldtBirthday":{"month":"JANUARY","year":1995,"dayOfMonth":1,"hour":0,"minute":0,"monthValue":1,"nano":0,"second":0,"dayOfWeek":"SUNDAY","dayOfYear":1,"chronology":{"id":"ISO","calendarType":"iso8601"}},"ldBirthday":{"year":1995,"month":"JANUARY","dayOfMonth":1,"monthValue":1,"era":"CE","dayOfWeek":"SUNDAY","dayOfYear":1,"leapYear":false,"chronology":{"id":"ISO","calendarType":"iso8601"}},"bsid":1},{"bolid":true,"bid":2,"sid":0,"iid":2,"lid":2,"fid":2.0,"did":2.0,"cid":"b","id":2,"birthday":"1995-01-02 00:00:00","LdBirthday":"1995-01-02","LtBirthday":"00:00:00","LdtBirthday":"1995-01-02 00:00:00","name":"李四","sex":"男","biid":2,"bfid":2.0,"bdid":2.0,"bbolid":false,"bcid":"B","blid":2,"decid":2.0,"bigid":2,"bbid":2,"ltBirthday":{"hour":0,"minute":0,"second":0,"nano":0},"ldtBirthday":{"month":"JANUARY","year":1995,"dayOfMonth":2,"hour":0,"minute":0,"monthValue":1,"nano":0,"second":0,"dayOfWeek":"MONDAY","dayOfYear":2,"chronology":{"id":"ISO","calendarType":"iso8601"}},"ldBirthday":{"year":1995,"month":"JANUARY","dayOfMonth":2,"monthValue":1,"era":"CE","dayOfWeek":"MONDAY","dayOfYear":2,"leapYear":false,"chronology":{"id":"ISO","calendarType":"iso8601"}},"bsid":2},{"bolid":false,"bid":3,"sid":0,"iid":3,"lid":3,"fid":3.0,"did":3.0,"cid":"c","id":3,"birthday":"1995-01-03 00:00:00","LdBirthday":"1995-01-03","LtBirthday":"00:00:00","LdtBirthday":"1995-01-03 00:00:00","name":"王冰冰","sex":"女","biid":3,"bfid":3.0,"bdid":3.0,"bbolid":true,"bcid":"C","blid":3,"decid":3.0,"bigid":3,"bbid":3,"ltBirthday":{"hour":0,"minute":0,"second":0,"nano":0},"ldtBirthday":{"month":"JANUARY","year":1995,"dayOfMonth":3,"hour":0,"minute":0,"monthValue":1,"nano":0,"second":0,"dayOfWeek":"TUESDAY","dayOfYear":3,"chronology":{"id":"ISO","calendarType":"iso8601"}},"ldBirthday":{"year":1995,"month":"JANUARY","dayOfMonth":3,"monthValue":1,"era":"CE","dayOfWeek":"TUESDAY","dayOfYear":3,"leapYear":false,"chronology":{"id":"ISO","calendarType":"iso8601"}},"bsid":3}]
19:46:45.686 [main] DEBUG org.apache.poi.openxml4j.opc.PackageRelationshipCollection - Parsing relationship: /xl/_rels/workbook.xml.rels
19:46:45.686 [main] DEBUG org.apache.poi.openxml4j.opc.PackageRelationshipCollection - Parsing relationship: /_rels/.rels
[{"bolid":false,"bid":1,"sid":0,"iid":1,"lid":1,"fid":1.0,"did":1.0,"cid":"a","id":1,"birthday":"1995-01-01 00:00:00","LdBirthday":"1995-01-01","LtBirthday":"00:00:00","LdtBirthday":"1995-01-01 00:00:00","name":"张三","sex":"男","biid":1,"bfid":1.0,"bdid":1.0,"bbolid":true,"bcid":"A","blid":1,"decid":1.0,"bigid":1,"bbid":1,"ltBirthday":{"hour":0,"minute":0,"second":0,"nano":0},"ldtBirthday":{"month":"JANUARY","year":1995,"dayOfMonth":1,"hour":0,"minute":0,"monthValue":1,"nano":0,"second":0,"dayOfWeek":"SUNDAY","dayOfYear":1,"chronology":{"id":"ISO","calendarType":"iso8601"}},"ldBirthday":{"year":1995,"month":"JANUARY","dayOfMonth":1,"monthValue":1,"era":"CE","dayOfWeek":"SUNDAY","dayOfYear":1,"leapYear":false,"chronology":{"id":"ISO","calendarType":"iso8601"}},"bsid":1},{"bolid":true,"bid":2,"sid":0,"iid":2,"lid":2,"fid":2.0,"did":2.0,"cid":"b","id":2,"birthday":"1995-01-02 00:00:00","LdBirthday":"1995-01-02","LtBirthday":"00:00:00","LdtBirthday":"1995-01-02 00:00:00","name":"李四","sex":"男","biid":2,"bfid":2.0,"bdid":2.0,"bbolid":false,"bcid":"B","blid":2,"decid":2.0,"bigid":2,"bbid":2,"ltBirthday":{"hour":0,"minute":0,"second":0,"nano":0},"ldtBirthday":{"month":"JANUARY","year":1995,"dayOfMonth":2,"hour":0,"minute":0,"monthValue":1,"nano":0,"second":0,"dayOfWeek":"MONDAY","dayOfYear":2,"chronology":{"id":"ISO","calendarType":"iso8601"}},"ldBirthday":{"year":1995,"month":"JANUARY","dayOfMonth":2,"monthValue":1,"era":"CE","dayOfWeek":"MONDAY","dayOfYear":2,"leapYear":false,"chronology":{"id":"ISO","calendarType":"iso8601"}},"bsid":2},{"bolid":false,"bid":3,"sid":0,"iid":3,"lid":3,"fid":3.0,"did":3.0,"cid":"c","id":3,"birthday":"1995-01-03 00:00:00","LdBirthday":"1995-01-03","LtBirthday":"00:00:00","LdtBirthday":"1995-01-03 00:00:00","name":"王冰冰","sex":"女","biid":3,"bfid":3.0,"bdid":3.0,"bbolid":true,"bcid":"C","blid":3,"decid":3.0,"bigid":3,"bbid":3,"ltBirthday":{"hour":0,"minute":0,"second":0,"nano":0},"ldtBirthday":{"month":"JANUARY","year":1995,"dayOfMonth":3,"hour":0,"minute":0,"monthValue":1,"nano":0,"second":0,"dayOfWeek":"TUESDAY","dayOfYear":3,"chronology":{"id":"ISO","calendarType":"iso8601"}},"ldBirthday":{"year":1995,"month":"JANUARY","dayOfMonth":3,"monthValue":1,"era":"CE","dayOfWeek":"TUESDAY","dayOfYear":3,"leapYear":false,"chronology":{"id":"ISO","calendarType":"iso8601"}},"bsid":3}]
19:46:45.765 [main] DEBUG org.apache.poi.openxml4j.opc.PackageRelationshipCollection - Parsing relationship: /xl/_rels/workbook.xml.rels
19:46:45.765 [main] DEBUG org.apache.poi.openxml4j.opc.PackageRelationshipCollection - Parsing relationship: /_rels/.rels
[{"bolid":false,"bid":1,"sid":0,"iid":1,"lid":1,"fid":1.0,"did":1.0,"cid":"a","id":1,"birthday":"1995-01-01 00:00:00","LdBirthday":"1995-01-01","LtBirthday":"00:00:00","LdtBirthday":"1995-01-01 00:00:00","name":"张三","sex":"男","biid":1,"bfid":1.0,"bdid":1.0,"bbolid":true,"bcid":"A","blid":1,"decid":1.0,"bigid":1,"bbid":1,"ltBirthday":{"hour":0,"minute":0,"second":0,"nano":0},"ldtBirthday":{"month":"JANUARY","year":1995,"dayOfMonth":1,"hour":0,"minute":0,"monthValue":1,"nano":0,"second":0,"dayOfWeek":"SUNDAY","dayOfYear":1,"chronology":{"id":"ISO","calendarType":"iso8601"}},"ldBirthday":{"year":1995,"month":"JANUARY","dayOfMonth":1,"monthValue":1,"era":"CE","dayOfWeek":"SUNDAY","dayOfYear":1,"leapYear":false,"chronology":{"id":"ISO","calendarType":"iso8601"}},"bsid":1},{"bolid":true,"bid":2,"sid":0,"iid":2,"lid":2,"fid":2.0,"did":2.0,"cid":"b","id":2,"birthday":"1995-01-02 00:00:00","LdBirthday":"1995-01-02","LtBirthday":"00:00:00","LdtBirthday":"1995-01-02 00:00:00","name":"李四","sex":"男","biid":2,"bfid":2.0,"bdid":2.0,"bbolid":false,"bcid":"B","blid":2,"decid":2.0,"bigid":2,"bbid":2,"ltBirthday":{"hour":0,"minute":0,"second":0,"nano":0},"ldtBirthday":{"month":"JANUARY","year":1995,"dayOfMonth":2,"hour":0,"minute":0,"monthValue":1,"nano":0,"second":0,"dayOfWeek":"MONDAY","dayOfYear":2,"chronology":{"id":"ISO","calendarType":"iso8601"}},"ldBirthday":{"year":1995,"month":"JANUARY","dayOfMonth":2,"monthValue":1,"era":"CE","dayOfWeek":"MONDAY","dayOfYear":2,"leapYear":false,"chronology":{"id":"ISO","calendarType":"iso8601"}},"bsid":2},{"bolid":false,"bid":3,"sid":0,"iid":3,"lid":3,"fid":3.0,"did":3.0,"cid":"c","id":3,"birthday":"1995-01-03 00:00:00","LdBirthday":"1995-01-03","LtBirthday":"00:00:00","LdtBirthday":"1995-01-03 00:00:00","name":"王冰冰","sex":"女","biid":3,"bfid":3.0,"bdid":3.0,"bbolid":true,"bcid":"C","blid":3,"decid":3.0,"bigid":3,"bbid":3,"ltBirthday":{"hour":0,"minute":0,"second":0,"nano":0},"ldtBirthday":{"month":"JANUARY","year":1995,"dayOfMonth":3,"hour":0,"minute":0,"monthValue":1,"nano":0,"second":0,"dayOfWeek":"TUESDAY","dayOfYear":3,"chronology":{"id":"ISO","calendarType":"iso8601"}},"ldBirthday":{"year":1995,"month":"JANUARY","dayOfMonth":3,"monthValue":1,"era":"CE","dayOfWeek":"TUESDAY","dayOfYear":3,"leapYear":false,"chronology":{"id":"ISO","calendarType":"iso8601"}},"bsid":3}]
19:46:45.858 [main] DEBUG org.apache.poi.openxml4j.opc.PackageRelationshipCollection - Parsing relationship: /xl/_rels/workbook.xml.rels
19:46:45.905 [main] DEBUG org.apache.poi.openxml4j.opc.PackageRelationshipCollection - Parsing relationship: /_rels/.rels
[{"bolid":false,"bid":0,"sid":0,"iid":0,"lid":0,"fid":0.0,"did":0.0,"cid":"\u0000","id":1,"birthday":"1995-01-01 00:00:00","LdBirthday":null,"LtBirthday":null,"LdtBirthday":null,"name":"张三","sex":"男","biid":null,"bfid":null,"bdid":null,"bbolid":null,"bcid":null,"blid":null,"decid":null,"bigid":null,"bbid":null,"ltBirthday":null,"ldtBirthday":null,"ldBirthday":null,"bsid":null},{"bolid":false,"bid":0,"sid":0,"iid":0,"lid":0,"fid":0.0,"did":0.0,"cid":"\u0000","id":2,"birthday":"1995-01-02 00:00:00","LdBirthday":null,"LtBirthday":null,"LdtBirthday":null,"name":"李四","sex":"男","biid":null,"bfid":null,"bdid":null,"bbolid":null,"bcid":null,"blid":null,"decid":null,"bigid":null,"bbid":null,"ltBirthday":null,"ldtBirthday":null,"ldBirthday":null,"bsid":null},{"bolid":false,"bid":0,"sid":0,"iid":0,"lid":0,"fid":0.0,"did":0.0,"cid":"\u0000","id":3,"birthday":"1995-01-03 00:00:00","LdBirthday":null,"LtBirthday":null,"LdtBirthday":null,"name":"王冰冰","sex":"女","biid":null,"bfid":null,"bdid":null,"bbolid":null,"bcid":null,"blid":null,"decid":null,"bigid":null,"bbid":null,"ltBirthday":null,"ldtBirthday":null,"ldBirthday":null,"bsid":null}]
19:46:45.983 [main] DEBUG org.apache.poi.openxml4j.opc.PackageRelationshipCollection - Parsing relationship: /xl/_rels/workbook.xml.rels
19:46:45.983 [main] DEBUG org.apache.poi.openxml4j.opc.PackageRelationshipCollection - Parsing relationship: /_rels/.rels
[{"bolid":false,"bid":0,"sid":0,"iid":0,"lid":0,"fid":0.0,"did":0.0,"cid":"\u0000","id":1,"birthday":"1995-01-01 00:00:00","LdBirthday":null,"LtBirthday":null,"LdtBirthday":null,"name":"张三","sex":"男","biid":null,"bfid":null,"bdid":null,"bbolid":null,"bcid":null,"blid":null,"decid":null,"bigid":null,"bbid":null,"ltBirthday":null,"ldtBirthday":null,"ldBirthday":null,"bsid":null},{"bolid":false,"bid":0,"sid":0,"iid":0,"lid":0,"fid":0.0,"did":0.0,"cid":"\u0000","id":2,"birthday":"1995-01-02 00:00:00","LdBirthday":null,"LtBirthday":null,"LdtBirthday":null,"name":"李四","sex":"男","biid":null,"bfid":null,"bdid":null,"bbolid":null,"bcid":null,"blid":null,"decid":null,"bigid":null,"bbid":null,"ltBirthday":null,"ldtBirthday":null,"ldBirthday":null,"bsid":null},{"bolid":false,"bid":0,"sid":0,"iid":0,"lid":0,"fid":0.0,"did":0.0,"cid":"\u0000","id":3,"birthday":"1995-01-03 00:00:00","LdBirthday":null,"LtBirthday":null,"LdtBirthday":null,"name":"王冰冰","sex":"女","biid":null,"bfid":null,"bdid":null,"bbolid":null,"bcid":null,"blid":null,"decid":null,"bigid":null,"bbid":null,"ltBirthday":null,"ldtBirthday":null,"ldBirthday":null,"bsid":null}]
19:46:46.030 [main] DEBUG org.apache.poi.openxml4j.opc.PackageRelationshipCollection - Parsing relationship: /xl/_rels/workbook.xml.rels
19:46:46.030 [main] DEBUG org.apache.poi.openxml4j.opc.PackageRelationshipCollection - Parsing relationship: /_rels/.rels
[{"bolid":false,"bid":0,"sid":0,"iid":0,"lid":0,"fid":0.0,"did":0.0,"cid":"\u0000","id":1,"birthday":"1995-01-01 00:00:00","LdBirthday":null,"LtBirthday":null,"LdtBirthday":null,"name":"张三","sex":"男","biid":null,"bfid":null,"bdid":null,"bbolid":null,"bcid":null,"blid":null,"decid":null,"bigid":null,"bbid":null,"ltBirthday":null,"ldtBirthday":null,"ldBirthday":null,"bsid":null},{"bolid":false,"bid":0,"sid":0,"iid":0,"lid":0,"fid":0.0,"did":0.0,"cid":"\u0000","id":2,"birthday":"1995-01-02 00:00:00","LdBirthday":null,"LtBirthday":null,"LdtBirthday":null,"name":"李四","sex":"男","biid":null,"bfid":null,"bdid":null,"bbolid":null,"bcid":null,"blid":null,"decid":null,"bigid":null,"bbid":null,"ltBirthday":null,"ldtBirthday":null,"ldBirthday":null,"bsid":null},{"bolid":false,"bid":0,"sid":0,"iid":0,"lid":0,"fid":0.0,"did":0.0,"cid":"\u0000","id":3,"birthday":"1995-01-03 00:00:00","LdBirthday":null,"LtBirthday":null,"LdtBirthday":null,"name":"王冰冰","sex":"女","biid":null,"bfid":null,"bdid":null,"bbolid":null,"bcid":null,"blid":null,"decid":null,"bigid":null,"bbid":null,"ltBirthday":null,"ldtBirthday":null,"ldBirthday":null,"bsid":null}]