Эффективный метод для перечисления ячеек в книге Excel с использованием C # - PullRequest
2 голосов
/ 04 ноября 2008

Каков наиболее эффективный способ перечисления каждой ячейки на каждом листе рабочей книги?

Представленный ниже метод вполне оправдан для рабочей книги с ~ 130 000 ячеек. На моей машине потребовалось ~ 26 секунд, чтобы открыть файл и ~ 5 секунд, чтобы перечислить ячейки. Однако я не эксперт по Excel и хотел проверить этот фрагмент кода с широким сообществом.

DateTime timer = DateTime.Now;
Microsoft.Office.Interop.Excel.Application excelApplication = new Microsoft.Office.Interop.Excel.Application();
try
{
    exampleFile = new FileInfo(Path.Combine(System.Environment.CurrentDirectory, "Large.xlsx"));
    excelApplication.Workbooks.Open(exampleFile.FullName, false, false, missing, missing, missing, true, missing, missing, true, missing, missing, missing, missing, missing);
    Console.WriteLine(string.Format("Took {0} seconds to open file", (DateTime.Now - timer).Seconds.ToString()));

    timer = DateTime.Now;
    foreach(Workbook workbook in excelApplication.Workbooks)
    {
            foreach(Worksheet sheet in workbook.Sheets)
            {
            int i = 0, iRowMax, iColMax;
            string data = String.Empty;

            Object[,] rangeData = (System.Object[,]) sheet.UsedRange.Cells.get_Value(missing);

            if (rangeData != null)
            {
                iRowMax = rangeData.GetUpperBound(0);                       
                iColMax = rangeData.GetUpperBound(1);                                                       

                for (int iRow = 1; iRow < iRowMax; iRow++)
                {
                        for(int iCol = 1; iCol < iColMax; iCol++)
                    {
                        data = rangeData[iRow, iCol] != null ? rangeData[iRow, iCol].ToString() : string.Empty;
                        if (i % 100 == 0)
                        {
                            Console.WriteLine(String.Format("Processed {0} cells.", i));
                        }

                        i++;
                    }                                                                                                   
                }   
            }
        }

        workbook.Close(false, missing, missing);
    }

    Console.WriteLine(string.Format("Took {0} seconds to parse file", (DateTime.Now - timer).Seconds.ToString()));              
    }
    finally
    {
        excelApplication.Workbooks.Close();             
        excelApplication.Quit();                  
    }                   

Редактировать

Стоит отметить, что я хочу использовать PIA и взаимодействие для доступа к свойствам книг Excel, которые не предоставляются API, работающими непосредственно с файлом Excel.

Ответы [ 3 ]

2 голосов
/ 04 ноября 2008

Существует открытая реализация для чтения и записи Excel, которая называется Koogra . Это позволяет вам читать в файле Excel и изменять его, используя чистый управляемый код. Это, вероятно, будет намного быстрее, чем код, который вы используете сейчас.

2 голосов
/ 04 ноября 2008

Excel PIA Interop работает очень медленно, когда вы делаете что-то по клеткам.

Вы должны выбрать диапазон, который хотите извлечь, как вы сделали со свойством Worksheet.UsedRange, а затем прочитать значение всего диапазона за один шаг, вызвав get_Value() (или просто просто прочитав Value или Value2 свойство, я не могу вспомнить, какое) на нем.

Это даст object[,], то есть двумерный массив, который можно легко перечислить и быстро прочитать.

РЕДАКТИРОВАТЬ : Я только что прочитал ваш реальный код и понял, что он действительно делает то, что я предложил. Позор мне, что я не прочитал вопрос правильно, прежде чем ответить. В этом случае вы не можете сделать это намного быстрее. Excel PIA Interop работает медленно. Если вам нужно более быстрое решение, вам придется либо перенести jExcelApi с Java на C # (это не очень сложно), либо использовать какой-либо коммерческий компонент. Я предлагаю избегать интерфейса OLEDB любой ценой, чтобы сохранить ваше здоровье.

Несвязанный, но полезный совет: вы должны использовать ?? оператор. Это действительно удобно. Вместо

data = rangeData[iRow, iCol] != null ? rangeData[iRow, iCol].ToString() : string.Empty;

Вы могли бы просто написать

data = Convert.ToString(rangeData[iRow, iCol]) ?? string.Empty;

В этом случае даже String.Empty не требуется, поскольку Convert.ToString (object) в любом случае null преобразует в пустую строку.

1 голос
/ 04 ноября 2008

Я думаю, это самый эффективный способ, как это сделать с PIA. Может быть, будет немного быстрее, если использовать "foreach" вместо "for", но это не изменится.

Если ваша главная цель - эффективность, вы должны работать с файлами Excel напрямую - без приложения Excel.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...