简体   繁体   English

C# Excel 行数超过 3000 时 Interop 占用的进程太长

[英]C# Excel Interop taking too long process when the row count is more than 3000

C# Excel Interop taking too long process when the row count is more than 3000, when i break the excel down by 1500 rows and process the excel its not taking more than 2 mins. C# Excel Interop taking too long process when the row count is more than 3000, when i break the excel down by 1500 rows and process the excel its not taking more than 2 mins.

Note: I am wondering why excel of two 1500 rows is processed quicker but one excel with more than 3000 rows is taking too long?注意:我想知道为什么两个 1500 行的 excel 处理得更快,但一个超过 3000 行的 excel 处理时间太长?

sometimes this below exception is thrown有时会抛出以下异常

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) 

Method calling performance issue.方法调用性能问题。

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;
}

Your code is obviously crashing and you have no idea where or why.您的代码显然崩溃了,您不知道在哪里或为什么。 On some things I have done in the past is to create a variable at the top outside of the try/catch.我过去做过的一些事情是在 try/catch 之外的顶部创建一个变量。 Run the process, and then put a breakpoint in the exception to see what was the problem.运行该进程,然后在异常中放置一个断点以查看问题所在。 I am betting it is probably some data type exception.我打赌这可能是一些数据类型异常。 You are expecting one type of object and the value you are getting is not that type and thus choking.您期待一种类型的 object 并且您获得的值不是那种类型,因此令人窒息。 Although this is a stub, it may help you in narrowing down where it is failing.虽然这是一个存根,但它可以帮助您缩小失败的范围。 The other reason it may be failing is the first 1500ish records are all ok, then you have some strange data down after that, and THAT is causing the failure.它可能失败的另一个原因是前 1500 条记录都正常,然后你有一些奇怪的数据,这就是导致失败的原因。

This is stripped-down version of what you had posted这是您发布的内容的精简版

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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM