Generate ASP.NET problems encountered by Excel and improvement methods

  • 2020-05-10 18:02:56
  • OfStack

Take a look at the 1 method (with 1 judgment and extension omitted) :
Generate Excel old code
 
/// <summary> 
///  will 1 The group object is exported into EXCEL 
/// </summary> 
/// <typeparam name="T"> The type of the object to be exported </typeparam> 
/// <param name="objList">1 Set of objects </param> 
/// <param name="FileName"> The exported file name </param> 
/// <param name="columnInfo"> The column name information </param> 
public static void ExExcel<T>(List<T> objList, string FileName, Dictionary<string, string> columnInfo) 
{ 

if (columnInfo.Count == 0) { return; } 
if (objList.Count == 0) { return; } 
// generate EXCEL the HTML 
string excelStr = ""; 

Type myType = objList[0].GetType(); 
// Get the property to display based on the reflection from the property name information passed in  
List<PropertyInfo> myPro = new List<PropertyInfo>(); 
foreach (string cName in columnInfo.Keys) 
{ 
PropertyInfo p = myType.GetProperty(cName); 
if (p != null) 
{ 
myPro.Add(p); 
excelStr += columnInfo[cName] + "\t"; 
} 
} 
// If no properties are found available, it ends  
if (myPro.Count == 0) { return; } 
excelStr += "\n"; 

foreach (T obj in objList) 
{ 
foreach (PropertyInfo p in myPro) 
{ 
excelStr += p.GetValue(obj, null) + "\t"; 
} 
excelStr += "\n"; 
} 

// The output EXCEL 
HttpResponse rs = System.Web.HttpContext.Current.Response; 
rs.ContentEncoding = System.Text.Encoding.GetEncoding("GB2312"); 
rs.AppendHeader("Content-Disposition", "attachment;filename=" + FileName); 
rs.ContentType = "application/ms-excel"; 
rs.Write(excelStr); 
rs.End(); 
} 

By this point I think some friends can see the problem.

This method will not cause problems when the amount of data generated by Excel is small, but it will cause problems when the amount of data is large. Since a variable of type string is defined in the method, overlay the contents that need to be filled into Excel. Using the += operation for data of type string is equivalent to concatenating strings using the string.Concat method. A new string is generated each time a += operation is performed. One block of memory is bound to be allocated, and more than one such operation will exhaust the memory and produce an OutOfMemoryException.

After knowing the problem, it is easy to improve, that is, to use StringBuilder overlay to fill the content of Excel. The improved code is as follows:
The improved code for Excel is generated
 
/// <summary> 
///  will 1 The group object is exported into EXCEL 
/// </summary> 
/// <typeparam name="T"> The type of the object to be exported </typeparam> 
/// <param name="objList">1 Set of objects </param> 
/// <param name="FileName"> The exported file name </param> 
/// <param name="columnInfo"> The column name information </param> 
public static void ExExcel<T>(List<T> objList, string FileName, Dictionary<string, string> columnInfo) 
{ 

if (columnInfo.Count == 0) { return; } 
if (objList.Count == 0) { return; } 
// generate EXCEL the HTML 
StringBuilder excelStr = new StringBuilder(objList.Count * columnInfo.Count); 

Type myType = objList[0].GetType(); 
// Get the property to display based on the reflection from the property name information passed in  
List<PropertyInfo> myPro = new List<PropertyInfo>(); 
foreach (string cName in columnInfo.Keys) 
{ 
PropertyInfo p = myType.GetProperty(cName); 
if (p != null) 
{ 
myPro.Add(p); 
excelStr.Append(columnInfo[cName]).Append("\t"); 
} 
} 
// If no properties are found available, it ends  
if (myPro.Count == 0) { return; } 
excelStr.Append("\n"); 

foreach (T obj in objList) 
{ 
foreach (PropertyInfo p in myPro) 
{ 
excelStr.Append(p.GetValue(obj, null)).Append("\t"); 
} 
excelStr.Append("\n"); 
} 

// The output EXCEL 
HttpResponse rs = System.Web.HttpContext.Current.Response; 
rs.ContentEncoding = System.Text.Encoding.GetEncoding("GB2312"); 
rs.AppendHeader("Content-Disposition", "attachment;filename=" + FileName); 
rs.ContentType = "application/ms-excel"; 
rs.Write(excelStr); 
rs.End(); 
} 
} 

StringBuilder excelStr = new StringBuilder(objList.Count * columnInfo.Count); Pre-allocate the start size to make better use of StringBuilder. At this point, the improvement is complete.
Alternatively, if you feel that reflection will affect performance, you can change to an expression tree or use limit.

Related articles: