|
|
@ -8,6 +8,7 @@ import com.wb.excel.api.exception.*;
|
|
|
|
import com.wb.excel.api.exception.Error;
|
|
|
|
import com.wb.excel.api.exception.Error;
|
|
|
|
import com.wb.excel.api.util.*;
|
|
|
|
import com.wb.excel.api.util.*;
|
|
|
|
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
|
|
|
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
|
|
|
|
|
|
|
import org.apache.poi.ss.usermodel.Cell;
|
|
|
|
import org.apache.poi.ss.usermodel.Row;
|
|
|
|
import org.apache.poi.ss.usermodel.Row;
|
|
|
|
import org.apache.poi.ss.usermodel.Sheet;
|
|
|
|
import org.apache.poi.ss.usermodel.Sheet;
|
|
|
|
import org.apache.poi.ss.usermodel.Workbook;
|
|
|
|
import org.apache.poi.ss.usermodel.Workbook;
|
|
|
@ -121,7 +122,8 @@ public class WSheet<T> implements Serializable, Cloneable {
|
|
|
|
* @param clazz 模板类
|
|
|
|
* @param clazz 模板类
|
|
|
|
* @return 包含@Name标记的字段Set
|
|
|
|
* @return 包含@Name标记的字段Set
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
private WColumn[] initColumns(Class<?> clazz) {
|
|
|
|
private List<WColumn> initColumns(Class<?> clazz) {
|
|
|
|
|
|
|
|
List<WColumn> result = new ArrayList();
|
|
|
|
//获取工作簿名称,没有则以类名为默认工作簿名称
|
|
|
|
//获取工作簿名称,没有则以类名为默认工作簿名称
|
|
|
|
SheetName sheetName = clazz.getAnnotation(SheetName.class);
|
|
|
|
SheetName sheetName = clazz.getAnnotation(SheetName.class);
|
|
|
|
if (sheetName != null) {
|
|
|
|
if (sheetName != null) {
|
|
|
@ -166,8 +168,9 @@ public class WSheet<T> implements Serializable, Cloneable {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
this.addColumn(WColumn);
|
|
|
|
this.addColumn(WColumn);
|
|
|
|
|
|
|
|
result.add(WColumn);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return this.WColumns;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@ -186,11 +189,11 @@ public class WSheet<T> implements Serializable, Cloneable {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (list.size() > 0) {
|
|
|
|
if (list.size() > 0) {
|
|
|
|
T tClass = list.get(0);
|
|
|
|
T tClass = list.get(0);
|
|
|
|
WColumn[] WColumns = initColumns(tClass.getClass());
|
|
|
|
List<WColumn> wColumns = initColumns(tClass.getClass());
|
|
|
|
|
|
|
|
|
|
|
|
for (T t : list) {
|
|
|
|
for (T t : list) {
|
|
|
|
WRow row = new WRow();
|
|
|
|
WRow row = new WRow();
|
|
|
|
for (WColumn WColumn : WColumns) {
|
|
|
|
for (WColumn WColumn : wColumns) {
|
|
|
|
if (WColumn == null) {
|
|
|
|
if (WColumn == null) {
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -330,33 +333,41 @@ public class WSheet<T> implements Serializable, Cloneable {
|
|
|
|
if (!flag) {
|
|
|
|
if (!flag) {
|
|
|
|
throw new TemplateNotMatchException("不支持的文件类型");
|
|
|
|
throw new TemplateNotMatchException("不支持的文件类型");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//第一张Sheet表
|
|
|
|
Sheet sheet = workbook.getSheetAt(0); //处理第一张Sheet表
|
|
|
|
Sheet sheet = workbook.getSheetAt(0);
|
|
|
|
String tableName = sheet.getSheetName(); //DataTable的名字
|
|
|
|
//获取Sheet名称
|
|
|
|
|
|
|
|
SheetName sheetName = clazz.getAnnotation(SheetName.class);
|
|
|
|
/* 获取指定类所有带有Name注解的属性集合 */
|
|
|
|
if (sheetName != null) {//如果模板存在注解则使用注解名称
|
|
|
|
ColumnName classColumnName = clazz.getAnnotation(ColumnName.class); //该类所声明的名字
|
|
|
|
this.setName(sheetName.value());
|
|
|
|
ParentFirst parentFirstAnnotation = clazz.getAnnotation(ParentFirst.class);
|
|
|
|
} else {//将类名设为表名,如果类名不存在,将Excel表名设为表名
|
|
|
|
boolean parentFirst = parentFirstAnnotation != null && parentFirstAnnotation.value();
|
|
|
|
this.setName(sheet.getSheetName());
|
|
|
|
if (classColumnName != null) {
|
|
|
|
|
|
|
|
tableName = classColumnName.value();
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
this.setName(tableName); //将类名设为表名,如果类名不存在,将Excel表名设为表名
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//Field[] fields = clazz.getDeclaredFields(); //该类所声明的全部属性
|
|
|
|
//读取表头
|
|
|
|
Field[] fields = ClassUtil.getFields(clazz, parentFirst); //该类所声明的全部属性
|
|
|
|
Row headRow = sheet.getRow(0);
|
|
|
|
Set<Field> set = new HashSet<>(); //用于保存所有带有Name注解的属性
|
|
|
|
//获取Excel列的总数
|
|
|
|
for (Field field : fields) {
|
|
|
|
int columnSum = headRow.getPhysicalNumberOfCells();
|
|
|
|
if (field.isAnnotationPresent(ColumnName.class)) {
|
|
|
|
//匹配列的数量。用于判断Excel是否包含所有必须列。
|
|
|
|
set.add(field);
|
|
|
|
int columnMatchNumber = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//检查列数量
|
|
|
|
|
|
|
|
List<WColumn> list = initColumns(clazz);
|
|
|
|
|
|
|
|
if (list.size() != columnSum) {
|
|
|
|
|
|
|
|
throw new TemplateNotMatchException("与模板列数量不同。");
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
for (int i = 0; i < list.size(); i++) {
|
|
|
|
|
|
|
|
WColumn wColumn = list.get(i);
|
|
|
|
|
|
|
|
Cell cell = headRow.getCell(i);
|
|
|
|
|
|
|
|
String headValue = ExcelUtil.getValue(cell);
|
|
|
|
|
|
|
|
headValue = headValue.replace("*", "");
|
|
|
|
|
|
|
|
headValue = headValue.replace(" ", "");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!wColumn.getName().equals(headValue)) {
|
|
|
|
|
|
|
|
throw new TemplateNotMatchException("第" + (i + 1) + "项,不匹配的列名," + wColumn.getName() + "和" + headValue);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* 读取表头 */
|
|
|
|
|
|
|
|
Row headRow = sheet.getRow(0);
|
|
|
|
|
|
|
|
int columnSum = headRow.getPhysicalNumberOfCells(); //获取Excel列的总数
|
|
|
|
|
|
|
|
int columnMatchNumber = 0; //匹配列的数量。用于判断Excel是否包含所有必须列。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* 为Excel表中的每一列分配空间 */
|
|
|
|
/* 为Excel表中的每一列分配空间 */
|
|
|
|
List<Set<String>> sets = new ArrayList<>();
|
|
|
|
List<Set<String>> sets = new ArrayList<>();
|
|
|
|
ColumnType[] columnTypes = new ColumnType[columnSum];
|
|
|
|
ColumnType[] columnTypes = new ColumnType[columnSum];
|
|
|
@ -370,78 +381,18 @@ public class WSheet<T> implements Serializable, Cloneable {
|
|
|
|
ColumnDescription[] columnDescriptions = new ColumnDescription[columnSum];
|
|
|
|
ColumnDescription[] columnDescriptions = new ColumnDescription[columnSum];
|
|
|
|
IsDuplicated[] isDuplicateds = new IsDuplicated[columnSum];
|
|
|
|
IsDuplicated[] isDuplicateds = new IsDuplicated[columnSum];
|
|
|
|
|
|
|
|
|
|
|
|
boolean[] matchFlag = new boolean[set.size()]; //保存字段是否出现在Excel文件中。
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* 查找匹配列的数量 */
|
|
|
|
|
|
|
|
for (int i = 0; i < columnSum; i++) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sets.add(new HashSet<String>());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
org.apache.poi.ss.usermodel.Cell cell = headRow.getCell(i);
|
|
|
|
|
|
|
|
String headValue = ExcelUtil.getValue(cell); //获取列名
|
|
|
|
|
|
|
|
headValue = headValue.replace("*", "");
|
|
|
|
|
|
|
|
headValue = headValue.replace(" ", "");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int tempFieldIndex = 0; //字段的编号,临时变量
|
|
|
|
|
|
|
|
for (Field field : set) {
|
|
|
|
|
|
|
|
ColumnName fieldColumnName = field.getAnnotation(ColumnName.class);
|
|
|
|
|
|
|
|
if (headValue.equals(fieldColumnName.value())) { //如果Excel列名与Class属性名相一致
|
|
|
|
|
|
|
|
columnMatchNumber++; //标记该列的存在
|
|
|
|
|
|
|
|
columnTypes[i] = field.getAnnotation(ColumnType.class);
|
|
|
|
|
|
|
|
enums[i] = field.getAnnotation(Enum.class);
|
|
|
|
|
|
|
|
splits[i] = field.getAnnotation(Split.class);
|
|
|
|
|
|
|
|
lengths[i] = field.getAnnotation(Length.class);
|
|
|
|
|
|
|
|
notNulls[i] = field.getAnnotation(NotNull.class);
|
|
|
|
|
|
|
|
substrings[i] = field.getAnnotation(Substring.class);
|
|
|
|
|
|
|
|
decimalMins[i] = field.getAnnotation(DecimalMin.class);
|
|
|
|
|
|
|
|
decimalMaxs[i] = field.getAnnotation(DecimalMax.class);
|
|
|
|
|
|
|
|
columnDescriptions[i] = field.getAnnotation(ColumnDescription.class);
|
|
|
|
|
|
|
|
isDuplicateds[i] = field.getAnnotation(IsDuplicated.class);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
matchFlag[tempFieldIndex] = true;
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
tempFieldIndex++;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
WColumn WColumn = new WColumn();
|
|
|
|
|
|
|
|
WColumn.setName(ExcelUtil.getValue(cell));
|
|
|
|
|
|
|
|
if (columnDescriptions[i] != null) {
|
|
|
|
|
|
|
|
WColumn.setDescription(columnDescriptions[i].value());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (columnTypes[i] != null) {
|
|
|
|
|
|
|
|
WColumn.setDataType(columnTypes[i].value());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (notNulls[i] != null) {
|
|
|
|
|
|
|
|
WColumn.setRequired(true);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
this.addColumn(WColumn);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* 如果文件不匹配 */
|
|
|
|
|
|
|
|
if (columnMatchNumber != set.size()) {
|
|
|
|
|
|
|
|
StringBuilder templateExcept = new StringBuilder();
|
|
|
|
|
|
|
|
int tempIndex = 0;
|
|
|
|
|
|
|
|
for (Field field : set) {
|
|
|
|
|
|
|
|
if (matchFlag[tempIndex++]) {
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
templateExcept.append(field.getAnnotation(ColumnName.class).value()).append("栏;");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
throw new TemplateNotMatchException("不匹配的Excel文件,没有:" + templateExcept.toString());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int maxRowNumber = sheet.getLastRowNum(); //Excel文件的总行数
|
|
|
|
int maxRowNumber = sheet.getLastRowNum(); //Excel文件的总行数
|
|
|
|
/* 逐行读取导入文件的数据 */
|
|
|
|
/* 逐行读取导入文件的数据 */
|
|
|
|
for (int i = 0; i < maxRowNumber; i++) {
|
|
|
|
for (int i = 0; i < maxRowNumber; i++) {
|
|
|
|
Row inputRow = sheet.getRow(i + 1); //Excel中的一行数据,第0行为表头,所以要加1
|
|
|
|
Row inputRow = sheet.getRow(i + 1); //Excel中的一行数据,第0行为表头,所以要加1
|
|
|
|
WRow row = new WRow(); //DataTable中的一行
|
|
|
|
WRow row = new WRow(); //DataTable中的一行
|
|
|
|
this.addRow(row);
|
|
|
|
this.addRow(row);
|
|
|
|
|
|
|
|
|
|
|
|
if (null != inputRow) {
|
|
|
|
if (null != inputRow) {
|
|
|
|
for (int j = 0; j < columnSum; j++) { //逐格扫描
|
|
|
|
for (int j = 0; j < columnSum; j++) { //逐格扫描
|
|
|
|
|
|
|
|
|
|
|
|
/* 取得当前格子的值 */
|
|
|
|
/* 取得当前格子的值 */
|
|
|
|
org.apache.poi.ss.usermodel.Cell excelCell = inputRow.getCell(j);
|
|
|
|
Cell excelCell = inputRow.getCell(j);
|
|
|
|
WCell WCell = new WCell();
|
|
|
|
WCell WCell = new WCell();
|
|
|
|
this.setCell(i, WColumns[j].getName(), WCell);
|
|
|
|
this.setCell(i, WColumns[j].getName(), WCell);
|
|
|
|
|
|
|
|
|
|
|
@ -869,7 +820,7 @@ public class WSheet<T> implements Serializable, Cloneable {
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
method.invoke(object, EnumUtil.valueOf(e.target(), sValue));
|
|
|
|
method.invoke(object, EnumUtil.valueOf(e.target(), sValue));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if (field.getType() == Date.class || field.getType() == java.sql.Date.class) {
|
|
|
|
} else if (field.getType() == Date.class) {
|
|
|
|
Date date = TransferUtil.transferDate(value);
|
|
|
|
Date date = TransferUtil.transferDate(value);
|
|
|
|
method.invoke(object, date);
|
|
|
|
method.invoke(object, date);
|
|
|
|
} else if (field.getType() == Double.class || field.getType() == double.class
|
|
|
|
} else if (field.getType() == Double.class || field.getType() == double.class
|
|
|
@ -905,8 +856,7 @@ public class WSheet<T> implements Serializable, Cloneable {
|
|
|
|
* @return T型列表
|
|
|
|
* @return T型列表
|
|
|
|
* @see WColumn 列名称
|
|
|
|
* @see WColumn 列名称
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public List<T> transferList(Class<T> clazz)
|
|
|
|
public List<T> transferList(Class<T> clazz) throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
|
|
|
|
throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
|
|
|
|
|
|
|
|
List<T> list = new ArrayList<>();
|
|
|
|
List<T> list = new ArrayList<>();
|
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < this.getRowIndex(); i++) {
|
|
|
|
for (int i = 0; i < this.getRowIndex(); i++) {
|
|
|
|