使用完全脱离excel的导出中的方法导出excel,使用了一段时间后,发现问题不少,尤其是数据量特别大的时候,例如上万的数据,经常需要好几分钟。于是自己就开始进行优化。
经过观察代码,发现能优化的地方。1使用反射的地方 2类型判断的地方3是设置单元的值
1使用反射的地方
PropertyInfo pinfo = typeof(TModel).GetProperty(column.Key);
我想到了如果我把这些信息提前准备好,是不是就可以避免每一次循环都反射呢?
解决方法如下:使用字典提前把反射的信息保存下来,避免每一次循环都反射
Dictionary<string, PropertyInfo> FieldNamesPropertyInfoDic = new Dictionary<string, PropertyInfo>(); if (list.Count > 0) { foreach (KeyValuePair<string, string> column in FieldNames) { string key = column.Key; PropertyInfo pinfo = typeof(Titem).GetProperty(key); if (pinfo != null) { if (!FieldNamesPropertyInfoDic.ContainsKey(key)) { FieldNamesPropertyInfoDic.Add(key, pinfo); } } else { throw new Exception("未找到关联的属性" + column.Key + ""); } } } else { return sheet; }
PropertyInfo pinfo = FieldNamesPropertyInfoDic[column.Key];/
把最常用的类型放在最前边,使用return直接返回
public static void SetCellValue(Type modePropertyType, ICell newCell,string drValue) { if (string.IsNullOrEmpty(drValue)) { return; } if (modePropertyType == typeof(string)) { newCell.SetCellValue(drValue); return; } else if (modePropertyType == typeof(DateTime)) { newCell.SetCellValue(Convert.ToDateTime(drValue)); return; } else if (modePropertyType == typeof(DateTime?)) { newCell.SetCellValue(Convert.ToDateTime(drValue)); return; } else if (modePropertyType == typeof(float?)) { newCell.SetCellValue(Convert.ToSingle(drValue)); return; } else if (modePropertyType == typeof(decimal?)) { newCell.SetCellValue(Convert.ToDouble(drValue)); return; } else if (modePropertyType == typeof(double?)) { newCell.SetCellValue(Convert.ToDouble(drValue)); return; } else if (modePropertyType == typeof(int?)) { newCell.SetCellValue(Convert.ToInt32(drValue)); return; } else if (modePropertyType == typeof(int)) { newCell.SetCellValue(Convert.ToInt32(drValue)); return; } else if (modePropertyType == typeof(float)) { newCell.SetCellValue(Convert.ToSingle(drValue)); return; } else if (modePropertyType == typeof(double)) { newCell.SetCellValue(Convert.ToDouble(drValue)); return; } else if (modePropertyType == typeof(decimal)) { newCell.SetCellValue(Convert.ToDouble(drValue)); return; } else if (modePropertyType == typeof(sbyte)) { newCell.SetCellValue(Convert.ToSByte(drValue)); return; } else if (modePropertyType == typeof(sbyte?)) { newCell.SetCellValue(Convert.ToSByte(drValue)); return; } else if (modePropertyType == typeof(byte)) { newCell.SetCellValue(Convert.ToByte(drValue)); return; } else if (modePropertyType == typeof(byte?)) { newCell.SetCellValue(Convert.ToByte(drValue)); return; } else if (modePropertyType == typeof(short)) { newCell.SetCellValue(Convert.ToInt16(drValue)); return; } else if (modePropertyType == typeof(short?)) { newCell.SetCellValue(Convert.ToInt16(drValue)); return; } else if (modePropertyType == typeof(ushort)) { newCell.SetCellValue(Convert.ToUInt16(drValue)); return; } else if (modePropertyType == typeof(ushort?)) { newCell.SetCellValue(Convert.ToUInt16(drValue)); return; } else if (modePropertyType == typeof(uint)) { newCell.SetCellValue(Convert.ToUInt32(drValue)); return; } else if (modePropertyType == typeof(uint?)) { newCell.SetCellValue(Convert.ToUInt32(drValue)); return; } else if (modePropertyType == typeof(long)) { newCell.SetCellValue(Convert.ToInt64(drValue)); return; } else if (modePropertyType == typeof(long?)) { newCell.SetCellValue(Convert.ToInt64(drValue)); return; } else if (modePropertyType == typeof(ulong)) { newCell.SetCellValue(Convert.ToUInt64(drValue)); return; } else if (modePropertyType == typeof(ulong?)) { newCell.SetCellValue(Convert.ToUInt64(drValue)); return; } else if (modePropertyType == typeof(bool)) { newCell.SetCellValue(Convert.ToBoolean(drValue)); return; } else if (modePropertyType == typeof(bool?)) { newCell.SetCellValue(Convert.ToBoolean(drValue)); return; } else if (modePropertyType == typeof(char)) { newCell.SetCellValue(Convert.ToChar(drValue)); return; } else if (modePropertyType == typeof(char?)) { newCell.SetCellValue(Convert.ToChar(drValue)); return; } else { newCell.SetCellValue(drValue); } }
这样修改以后,性能确实有改善,能提高百分之二十左右吧。改善不明显,想想是不是反射影响的。于是自己不使用反射,直接使用datatable,发现没有大的改善。于是自己再加日志,判断到底满载什么地方。竟然发现慢的地方不在自己的考虑范围内。
for (int i = 0; i < FieldNames.Count; i++) { sheet.AutoSizeColumn(i, true); }