当行数超过3000时,C#Excel互操作占用的进程太长
当行数超过3000行时,C#Excel互操作的处理时间太长,当我将Excel分解为1500行并处理Excel时,其处理时间不超过2分钟 注意:我想知道为什么两个1500行的excel处理速度更快,而一个3000行以上的excel处理时间太长 有时会引发以下异常当行数超过3000时,C#Excel互操作占用的进程太长,c#,excel,C#,Excel,当行数超过3000行时,C#Excel互操作的处理时间太长,当我将Excel分解为1500行并处理Excel时,其处理时间不超过2分钟 注意:我想知道为什么两个1500行的excel处理速度更快,而一个3000行以上的excel处理时间太长 有时会引发以下异常 Return argument has an invalid type. at System.Runtime.Remoting.Proxies.RealProxy.ValidateReturnArg(Object arg, Type
Return argument has an invalid type.
at System.Runtime.Remoting.Proxies.RealProxy.ValidateReturnArg(Object arg, Type paramType)
at System.Runtime.Remoting.Proxies.RealProxy.PropagateOutParameters(IMessage msg, Object[] outArgs, Object returnValue)
at System.RuntimeType.ForwardCallToInvokeMember(String memberName, BindingFlags flags, Object target, Int32[] aWrapperTypes, MessageData& msgData)
at Microsoft.Office.Interop.Excel.Range.get_Columns()
at PayableManagementHandler.Common.Utilities.ReadFileDetails(Request requestObj)
方法调用性能问题
public static DataTable ReadFileDetails(Request requestObj)
{
DataTable fileDetailsTable = null;
try
{
Excel.Application xlApp;
Excel.Workbook xlWorkBook;
Excel.Worksheet xlWorkSheet;
Excel.Range range;
DataRow row = null;
xlApp = new Microsoft.Office.Interop.Excel.Application();
xlWorkBook = xlApp.Workbooks.Open(requestObj.FileName, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing);
xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);
range = xlWorkSheet.UsedRange;
if ((null != range) && (null != range.Cells) &&
(requestObj.Source != PayableHndlrResource.STR_SOURCE ? range.Columns.Count.ToString() == PayableHndlrResource.ColumnsCount :
(requestObj.FileName.Contains(ConfigurationManager.AppSettings["FileName"]) || requestObj.FileName.Contains(ConfigurationManager.AppSettings["FileName"]) ? range.Columns.Count.ToString() == PayableHndlrResource.ColumnsCount : range.Columns.Count.ToString() == PayableHndlrResource.ColumnsCount)))
{
fileDetailsTable = new DataTable("ExcelData");
for (int rowCount = 1; rowCount <= range.Rows.Count; rowCount++)
{
if (range.Cells[rowCount, 1].Value2 != null)
{
if (rowCount > 1)
row = fileDetailsTable.Rows.Add();
for (int col = 1; col <= range.Columns.Count; col++)
{
if (rowCount == 1)
{
fileDetailsTable.Columns.Add((string)(range.Cells[rowCount, col] as Excel.Range).Value2).ToString().Trim();
}
else
{
if (requestObj.Source == PayableHndlrResource.STR_SOURCE)
{
row[col - 1] = ((range.Cells[rowCount, col] as Excel.Range).Value);
}
else
{
string data = Convert.ToString((range.Cells[rowCount, col] as Excel.Range).Value);
if (data != null)
{
switch (fileDetailsTable.Columns[col - 1].Caption.ToString().ToUpper())
{
case "SECONDARY ID":
row[col - 1] = data.Trim().ToString().Truncate(15);
break;
case "ACCOUNT NAME":
row[col - 1] = data.Trim().ToString().Truncate(255);
break;
case "BUSINESS UNIT1":
row[col - 1] = data.Trim().ToString().Truncate(100);
break;
case "BUSINESS UNIT2":
row[col - 1] = data.Trim().ToString().Truncate(100);
break;
case "DESCRIPTION":
row[col - 1] = data.Trim().ToString().Truncate(100);
break;
case "VENDOR":
row[col - 1] = data.Trim().ToString().Truncate(51);
break;
case "CITY":
row[col - 1] = data.Trim().ToString().Truncate(35);
break;
default:
row[col - 1] = data.Trim().ToString();
break;
}
}
else
{
if (fileDetailsTable.Columns[col - 1].Caption.ToString().ToUpper() == "REPORT TOTAL"
|| fileDetailsTable.Columns[col - 1].Caption.ToString().ToUpper() == "TRANSACTION AMOUNT"
|| fileDetailsTable.Columns[col - 1].Caption.ToString().ToUpper() == "ACCOUNT NO"
)
{
row[col - 1] = 0;
}
else if (fileDetailsTable.Columns[col - 1].Caption.ToString().ToUpper() == "TOTAL"
|| fileDetailsTable.Columns[col - 1].Caption.ToString().ToUpper() == " AMOUNT")
{
row[col - 1] = DateTime.MinValue;
}
else
{
row[col - 1] = string.Empty;
}
}
}
}
}
}
}
xlWorkBook.Close(true, requestObj.FileName, Type.Missing);
xlApp.Quit();
ReleaseObject(xlWorkSheet);
ReleaseObject(xlWorkBook);
ReleaseObject(xlApp);
if (requestObj.Source == PayableHndlrResource.STR_SOURCE)
{
SetDefaultValueForCTSI(fileDetailsTable,requestObj.CompanyId);
}
}
}
catch (Exception)
{
throw;
}
return fileDetailsTable;
}
公共静态数据表ReadFileDetails(请求对象)
{
DataTableFileDetailStable=null;
尝试
{
Excel.applicationxlapp;
Excel.工作簿;
Excel工作表;
范围;
DataRow行=null;
xlApp=新的Microsoft.Office.Interop.Excel.Application();
xlWorkBook=xlApp.Workbooks.Open(requestObj.FileName,Type.Missing,Type.Missing,Type.Missing,Type.Missing,
类型。缺失,类型。缺失,类型。缺失,类型。缺失,类型。缺失,
类型。缺失,类型。缺失,类型。缺失,类型。缺失,类型。缺失,
类型。缺失,类型。缺失);
xlWorkSheet=(Excel.Worksheet)xlWorkBook.Worksheets.get_项(1);
range=xlWorkSheet.UsedRange;
if((null!=范围)&&(null!=范围.单元格)&&
(requestObj.Source!=PayableHndlrResource.STR_Source?range.Columns.Count.ToString()==PayableHndlrResource.columnsunt:
(requestObj.FileName.Contains(ConfigurationManager.AppSettings[“FileName”])| | requestObj.FileName.Contains(ConfigurationManager.AppSettings[“FileName”])?range.Columns.Count.ToString()==PayableHndlResource.ColumnsCount:range.Columns.Count.ToString()==PayableHndlResource.ColumnsCount)))
{
fileDetailsTable=新数据表(“ExcelData”);
对于(int rowCount=1;rowCount 1)
row=fileDetailsTable.Rows.Add();
对于(int col=1;col您的代码显然正在崩溃,您不知道发生在何处或原因。我过去做过的一些事情是在try/catch外部的顶部创建一个变量。运行该过程,然后在异常中放置一个断点以查看问题所在。我打赌这可能是某个数据类型异常。您希望阻塞一种类型的对象和您获得的值不是该类型,因此阻塞。虽然这是一个存根,但它可能有助于您缩小失败的范围。它失败的另一个原因可能是第一个1500ish记录都正常,然后您有一些奇怪的数据,这就是导致失败的原因
这是你发布的内容的精简版本
public static DataTable ReadFileDetails(Request requestObj)
{
DataTable fileDetailsTable = null;
var failStep = 1;
try
{
Excel.Application xlApp;
Excel.Workbook xlWorkBook;
Excel.Worksheet xlWorkSheet;
Excel.Range range;
DataRow row = null;
xlApp = new Microsoft.Office.Interop.Excel.Application();
xlWorkBook = xlApp.Workbooks.Open(requestObj.FileName, Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing, Type.Missing, Type.Missing,
Type.Missing, Type.Missing);
xlWorkSheet = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);
range = xlWorkSheet.UsedRange;
if ((null != range) && (null != range.Cells) &&
(requestObj.Source != PayableHndlrResource.STR_SOURCE ? range.Columns.Count.ToString() == PayableHndlrResource.ColumnsCount :
(requestObj.FileName.Contains(ConfigurationManager.AppSettings["FileName"]) || requestObj.FileName.Contains(ConfigurationManager.AppSettings["FileName"]) ? range.Columns.Count.ToString() == PayableHndlrResource.ColumnsCount : range.Columns.Count.ToString() == PayableHndlrResource.ColumnsCount)))
{
fileDetailsTable = new DataTable("ExcelData");
for (int rowCount = 1; rowCount <= range.Rows.Count; rowCount++)
{
failStep = 1;
if (range.Cells[rowCount, 1].Value2 != null)
{
if (rowCount > 1)
row = fileDetailsTable.Rows.Add();
for (int col = 1; col <= range.Columns.Count; col++)
{
if (rowCount == 1)
{
failStep = 2;
fileDetailsTable.Columns.Add((string)(range.Cells[rowCount, col] as Excel.Range).Value2).ToString().Trim();
}
else
{
// checking before he IF to make sure
// no problem of the source type...
failStep = 3;
if (requestObj.Source == PayableHndlrResource.STR_SOURCE)
{
failStep = 4;
row[col - 1] = ((range.Cells[rowCount, col] as Excel.Range).Value);
}
else
{
failStep = 5;
string data = Convert.ToString((range.Cells[rowCount, col] as Excel.Range).Value);
etc... with rest of code
}
}
failStep = 99;
xlWorkBook.Close(true, requestObj.FileName, Type.Missing);
xlApp.Quit();
ReleaseObject(xlWorkSheet);
ReleaseObject(xlWorkBook);
ReleaseObject(xlApp);
if (requestObj.Source == PayableHndlrResource.STR_SOURCE)
{
SetDefaultValueForCTSI(fileDetailsTable,requestObj.CompanyId);
}
}
}
catch (Exception e)
{
// at this point, you can look at the explicit exception
// and also look at the "failStep" variable to see where
// it failed. Then put a break point at that location
// to add additional logging information.
throw;
}
return fileDetailsTable;
}
公共静态数据表ReadFileDetails(请求对象)
{
DataTableFileDetailStable=null;
var-failStep=1;
尝试
{
Excel.applicationxlapp;
Excel.工作簿;
Excel工作表;
范围;
DataRow行=null;
xlApp=新的Microsoft.Office.Interop.Excel.Application();
xlWorkBook=xlApp.Workbooks.Open(requestObj.FileName,Type.Missing,Type.Missing,Type.Missing,Type.Missing,
类型。缺失,类型。缺失,类型。缺失,类型。缺失,类型。缺失,
类型。缺失,类型。缺失,类型。缺失,类型。缺失,类型。缺失,
类型。缺失,类型。缺失);
xlWorkSheet=(Excel.Worksheet)xlWorkBook.Worksheets.get_项(1);
range=xlWorkSheet.UsedRange;
if((null!=范围)&&(null!=范围.单元格)&&
(requestObj.Source!=PayableHndlrResource.STR_Source?range.Columns.Count.ToString()==PayableHndlrResource.columnsunt:
(requestObj.FileName.Contains(ConfigurationManager.AppSettings[“FileName”])| | requestObj.FileName.Contains(ConfigurationManager.AppSettings[“FileName”])?range.Columns.Count.ToString()==PayableHndlResource.ColumnsCount:range.Columns.Count.ToString()==PayableHndlResource.ColumnsCount)))
{
fileDetailsTable=新数据表(“ExcelData”);
对于(int rowCount=1;rowCount 1)
row=fileDetailsTable.Rows.Add();
对于(int col=1;col如果perf是紧密循环中的一个主要问题,我最喜欢的是用VBA编写它并从C调用宏#您是否期望我们阅读这堵代码墙并解决问题?您需要学习一步一步地调试,习惯于遵循代码并理解它的功能。我调试过,但自己无法理解只需要一些建议来找出我真正缺少的@CamiloTerevintocould是内存吗?VSTO本质上是一个带有非托管代码的库,使用COM。在访问完元素后,必须释放COM引用。否则,内存将无法正确释放。还请注意,COM调用没有那么快。如果您愿意的话要处理多行,最好的解决方案是将整个范围复制到一个C#数组中,在C#中处理数组,然后写回数组。这将大大加快速度。