使用完全脱离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];/
2类型判断的地方和设置单元格值得方法修改如下:
把最常用的类型放在最前边,使用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);
}
竟然是这几行,太不起眼了。去掉了后,发现几分钟马上变成了几秒钟。真是太想不到了!!!