在我的前一篇博客中<<itoo项目实战之减少IO读写的导入思路>>,我介绍了如何完成减少IO读写的Excel导入,在这里我就把具体的代码实现分享给大家:
我就按照这张图的顺序给大家分享.
检查Excel 数据是否重复的代码:
<span style="font-family:Times New Roman;font-size:18px;">// 2.从指定列中寻找重复行
for (int i = 1; i < realRows - 1; i++) {
int nullCols = 0;
// 利用set元素的不重复特征来判断是否有重复行
Set<Integer> sameSet = new HashSet<Integer>();
for (int j = 0; j < uniqueFields.length; j++) {
String currentContent = uniqueCells[j][i].getContents();
Cell sameCell = sheet.findCell(currentContent,
uniqueCells[j][i].getColumn(),
uniqueCells[j][i].getRow() + 1,
uniqueCells[j][i].getColumn(),
uniqueCells[j][realRows - 1].getRow(), true);
if (sameCell != null) {
nullCols++;
sameSet.add(sameCell.getRow());
}
}
if (nullCols == uniqueFields.length && sameSet.size() == 1) {
throw new ExcelException("Excel中有重复行,请检查");
}
}
}</span>
检查Excel数据是否在database中是否已存在:
<span style="font-family:Times New Roman;font-size:18px;">for (int i = 1; i < realRows; i++) {
// 新建要转换的对象
T entity = entityClass.newInstance();
// 根据业务主键查询对象
LinkedHashMap<Object, Object> uniqueMap = new LinkedHashMap<Object, Object>();
String enValue = "";
for (int m = 0; m < uniqueFields.length; m++) {
// 获取英文字段名
String enName = combineMap.get(uniqueFields[m]);
// 获取英文字段值
// 1.获取列号
int col = colMap.get(uniqueFields[m]);
// 2.获取内容
enValue = sheet.getCell(col, i).getContents().toString()
.trim();
Field field = null;
Field[] fields = entityClass.getDeclaredFields(); //获取子类中所有的属性
if (Arrays.asList(fields).contains(enName)) { //判断传进来的属性是否属于该自诶
field = entityClass.getDeclaredField(enName); // 通过反射,获取类的属性
}
else{
Class<T> firstClass = entityClass;
firstClass = (Class<T>) firstClass.getSuperclass();
field = firstClass.getDeclaredField(enName);
}
field.setAccessible(true);
//先通过反射把list对象中的值取出来,然后在进行比较,判断数据库中是否已经存在
for (int j = 0; j < queryAllList.size(); j++) {
Object fieldValue = field.get(queryAllList.get(j));
// 如果对象已存在,在添加到错误列表,并continue
if (fieldValue.equals(enValue) && fieldValue !=null ) {
// 将该行添加到错误列表
errorMap.put(i, "对象已存在");
continue;
}
}
}
</span>
处理含有主外键关系的数据:
<span style="font-family:Times New Roman;font-size:18px;">// 用来标记是否有为空的引用对象
boolean isReferNull = false;
// 如果有引用字段,则给引用字段赋值
if (referFieldMap != null && referFieldMap.size() != 0) {
// 给对象的引用字段赋值
for (Entry<LinkedHashMap<String, Class<?>>, LinkedHashMap<String, String>> entry : referFieldMap
.entrySet()) {
LinkedHashMap<String, Class<?>> keyMap = entry.getKey(); // 获取实体中外键名
LinkedHashMap<String, String> valueMap = entry // 外键所对应的类
.getValue();
// 获取引用字段名和类型
String referField = "";
Class<?> type = null; // 定义外键多对一个的类
for (Entry<String, Class<?>> keyEntry : keyMap
.entrySet()) {
referField = keyEntry.getKey(); // 需要导入的对象的外键属性
type = keyEntry.getValue(); // 外键所对应的类
}
String enField = ""; // excel中有外键关系的字段
String cnField = ""; // excel中类名所对应的数据库字段名
String content = "";
for (Entry<String, String> valueEntry : valueMap
.entrySet()) {
enField = valueEntry.getValue();
// excel中有外键关系的字段
cnField = valueEntry.getKey();
int col = colMap.get(cnField);
content = sheet.getCell(col, i).getContents()
.toString().trim(); // 获取外键所对应的单元格内容
}
boolean isObjectBe = false; // 判断业务主键代表的引用对象 是否存在
// list变成map start
Object fieldIdValue = "";
Object fieldNameValue = "";
// 把list中的值放到map中
Field fieldId = null;
Field fieldName = null;
try {
fieldName = type.getDeclaredField(enField); // 通过反射,获取类的属性Name
} catch (NoSuchFieldException e1) {
e1.printStackTrace();
} catch (SecurityException e1) {
e1.printStackTrace();
}// 属性Name
fieldName.setAccessible(true); // 设置可以访问私有属性
for (; type != Object.class; type = type
.getSuperclass()) {
try {
fieldId = type.getDeclaredField("id"); // 通过反射,获取类的属性id
} catch (Exception e) {
}
}
fieldId.setAccessible(true);
String linkKey = "";
for (Entry<String, List> listEntity : listFileMap
.entrySet()) {
linkKey = listEntity.getKey();
List listvalue = listEntity.getValue();
if (linkKey != "" && linkKey.equals(referField)) { // 判断当前所循环的外键属性与map中的key值是否一致
Map<Object, Object> fileMap = new HashMap<Object, Object>(); // 放属性值
for (int k = 0; k < listvalue.size(); k++) {
try {
fieldIdValue = fieldId.get(listvalue
.get(k)); // 获取Id的值
fieldNameValue = fieldName
.get(listvalue.get(k)); // 获取name值
} catch (IllegalArgumentException
| IllegalAccessException e) {
e.printStackTrace();
}
fileMap.put(fieldIdValue, fieldNameValue);
if (fieldNameValue != null
& fieldNameValue.toString().equals(
content)) { // 判断该单元格中内容在list中是否存在
// 赋值给entity对象
setFieldValueByName(referField,
listvalue.get(k), entity);
isObjectBe = true;
}
}
}
}
// 如果引用对象不为空,则给对象赋值
if (isObjectBe == false) {
isReferNull = true;
errorMap.put(i, "业务主键代表的引用对象不存在");
break;
}
}
}</span>
以行为单位把数据保存到list中:
<span style="font-family:Times New Roman;font-size:18px;"> /**
* @MethodName : setFieldValueByName
* @Description : 根据字段名给对象的字段赋值
* @param fieldName
* 字段名
* @param fieldValue
* 字段值
* @param o
* 对象
*/
private void setFieldValueByName(String fieldName, Object fieldValue,
Object o) throws Exception {
Field field = getFieldByName(fieldName, o.getClass());
if (field != null) {
field.setAccessible(true);
// 获取字段类型
Class<?> fieldType = field.getType();
// 根据字段类型给字段赋值
if (String.class == fieldType) {
field.set(o, String.valueOf(fieldValue));
} else if ((Integer.TYPE == fieldType)
|| (Integer.class == fieldType)) {
field.set(o, Integer.parseInt(fieldValue.toString()));
} else if ((Long.TYPE == fieldType) || (Long.class == fieldType)) {
field.set(o, Long.valueOf(fieldValue.toString()));
} else if ((Float.TYPE == fieldType) || (Float.class == fieldType)) {
field.set(o, Float.valueOf(fieldValue.toString()));
} else if ((Short.TYPE == fieldType) || (Short.class == fieldType)) {
field.set(o, Short.valueOf(fieldValue.toString()));
} else if ((Double.TYPE == fieldType)
|| (Double.class == fieldType)) {
field.set(o, Double.valueOf(fieldValue.toString()));
} else if (Character.TYPE == fieldType) {
if ((fieldValue != null)
&& (fieldValue.toString().length() > 0)) {
field.set(o,
Character.valueOf(fieldValue.toString().charAt(0)));
}
} else if (Date.class == fieldType) {
field.set(o, new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
.parse(fieldValue.toString()));
} else {
field.set(o, fieldValue);
}
} else {
throw new ExcelException(o.getClass().getSimpleName() + "类不存在字段名 "
+ fieldName);
}
}
</span>
代码同时也反映着一个人的思考方式,你想读懂别人的代码,你需要做的是如何让别人先读懂自己代码.最近学会了一个读别人代码的好办法,和大家分享一下,在看别人的代码的时候,先别一头扎进去,然后自己就在里面出不来了.先从宏观上给代码画一张图,然后按照这张图去代码,代码整块整块的读,细节需要的话在研究,这样你就会觉得读别人的代码也是一件轻松的事情.
以上的代码只是部分代码,完整代码可以到这里下载: