Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
353 views
in Technique[技术] by (71.8m points)

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.

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 ?

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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. 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. 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.

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...