Как прочитать файл excel в c#, не пропуская ни одного столбца?
Я уже довольно давно использую OleDb-соединение для чтения файлов excel, но столкнулся с проблемой. У меня есть кто-то, кто пытается загрузить электронную таблицу Excel без ничего в первом столбце, и когда я пытаюсь прочитать файл, он не распознает этот столбец.
В настоящее время я использую следующую строку подключения OleDb:
Поставщик=Microsoft.Реактивный самолет.Oledb для.4.0;
Источник данных=c: test.xls;
Расширенные Свойства= " Excel 8.0; IMEX=1; "
Таким образом, если в файле excel есть 13 столбцов, OleDbDataReader, который я получаю обратно, имеет только 12 столбцов/полей.
Любое понимание будет оценено.
6 ответов:
SpreadsheetGear for .NET предоставляет API для работы с XLS и xlsx книгами из .NET. он проще в использовании и быстрее, чем OleDB или объектная модель Excel COM. Вы можете посмотреть живые образцы или попробовать их самостоятельно с помощью бесплатной пробной версии .
Отказ от ответственности: я владею SpreadsheetGear LLC
Правка:
Скупердяй прокомментировал: " быстрее, чем OleDb? Лучше подкрепите это утверждение ".
Это разумная просьба. Я вижу претензии все те время, которое я знаю как факт, является ложным, поэтому я не могу обвинять кого-либо в скептицизме. Ниже приведен код для создания книги размером 50 000 строк на 10 столбцов с помощью SpreadsheetGear, сохранения ее на диск, а затем суммирования чисел с помощью OleDb и SpreadsheetGear. SpreadsheetGear считывает 500k ячеек за 0,31 секунды по сравнению с 0,63 секунды с OleDB-чуть более чем в два раза быстрее. SpreadsheetGear фактически создает и читает книгу за меньшее время, чем требуется для чтения книги с помощью Oledb для.Код приведен ниже. Вы можете попробовать это самостоятельно с помощью бесплатной пробной версии SpreadsheetGear.
using System; using System.Data; using System.Data.OleDb; using SpreadsheetGear; using SpreadsheetGear.Advanced.Cells; using System.Diagnostics; namespace SpreadsheetGearAndOleDBBenchmark { class Program { static void Main(string[] args) { // Warm up (get the code JITed). BM(10, 10); // Do it for real. BM(50000, 10); } static void BM(int rows, int cols) { // Compare the performance of OleDB to SpreadsheetGear for reading // workbooks. We sum numbers just to have something to do. // // Run on Windows Vista 32 bit, Visual Studio 2008, Release Build, // Run Without Debugger: // Create time: 0.25 seconds // OleDb Time: 0.63 seconds // SpreadsheetGear Time: 0.31 seconds // // SpreadsheetGear is more than twice as fast at reading. Furthermore, // SpreadsheetGear can create the file and read it faster than OleDB // can just read it. string filename = @"C:\tmp\SpreadsheetGearOleDbBenchmark.xls"; Console.WriteLine("\nCreating {0} rows x {1} columns", rows, cols); Stopwatch timer = Stopwatch.StartNew(); double createSum = CreateWorkbook(filename, rows, cols); double createTime = timer.Elapsed.TotalSeconds; Console.WriteLine("Create sum of {0} took {1} seconds.", createSum, createTime); timer = Stopwatch.StartNew(); double oleDbSum = ReadWithOleDB(filename); double oleDbTime = timer.Elapsed.TotalSeconds; Console.WriteLine("OleDb sum of {0} took {1} seconds.", oleDbSum, oleDbTime); timer = Stopwatch.StartNew(); double spreadsheetGearSum = ReadWithSpreadsheetGear(filename); double spreadsheetGearTime = timer.Elapsed.TotalSeconds; Console.WriteLine("SpreadsheetGear sum of {0} took {1} seconds.", spreadsheetGearSum, spreadsheetGearTime); } static double CreateWorkbook(string filename, int rows, int cols) { IWorkbook workbook = Factory.GetWorkbook(); IWorksheet worksheet = workbook.Worksheets[0]; IValues values = (IValues)worksheet; double sum = 0.0; Random rand = new Random(); // Put labels in the first row. foreach (IRange cell in worksheet.Cells[0, 0, 0, cols - 1]) cell.Value = "Cell-" + cell.Address; // Using IRange and foreach be less code, // but we'll do it the fast way. for (int row = 1; row <= rows; row++) { for (int col = 0; col < cols; col++) { double number = rand.NextDouble(); sum += number; values.SetNumber(row, col, number); } } workbook.SaveAs(filename, FileFormat.Excel8); return sum; } static double ReadWithSpreadsheetGear(string filename) { IWorkbook workbook = Factory.GetWorkbook(filename); IWorksheet worksheet = workbook.Worksheets[0]; IValues values = (IValues)worksheet; IRange usedRahge = worksheet.UsedRange; int rowCount = usedRahge.RowCount; int colCount = usedRahge.ColumnCount; double sum = 0.0; // We could use foreach (IRange cell in usedRange) for cleaner // code, but this is faster. for (int row = 1; row <= rowCount; row++) { for (int col = 0; col < colCount; col++) { IValue value = values[row, col]; if (value != null && value.Type == SpreadsheetGear.Advanced.Cells.ValueType.Number) sum += value.Number; } } return sum; } static double ReadWithOleDB(string filename) { String connectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=" + filename + ";" + "Extended Properties=Excel 8.0;"; OleDbConnection connection = new OleDbConnection(connectionString); connection.Open(); OleDbCommand selectCommand =new OleDbCommand("SELECT * FROM [Sheet1$]", connection); OleDbDataAdapter dataAdapter = new OleDbDataAdapter(); dataAdapter.SelectCommand = selectCommand; DataSet dataSet = new DataSet(); dataAdapter.Fill(dataSet); connection.Close(); double sum = 0.0; // We'll make some assumptions for brevity of the code. DataTable dataTable = dataSet.Tables[0]; int cols = dataTable.Columns.Count; foreach (DataRow row in dataTable.Rows) { for (int i = 0; i < cols; i++) { object val = row[i]; if (val is double) sum += (double)val; } } return sum; } } }
Мы всегда используем Excel Interop для открытия электронной таблицы и непосредственного анализа (например, аналогично сканированию ячеек в VBA), или мы создаем заблокированные шаблоны, которые принудительно заполняют определенные столбцы, прежде чем пользователь сможет сохранить данные.
Вы, вероятно, можете посмотреть на ExcelMapper. Это инструмент для чтения файлов excel как строго типизированных объектов. Он скрывает все детали чтения excel из вашего кода. Он будет заботиться, если в excel отсутствует столбец или отсутствуют данные из столбца. Вы читаете данные, которые вас интересуют. Вы можете получить код / исполняемый файл для ExcelMapper из http://code.google.com/p/excelmapper/.
Если требуется, чтобы формат листа excel содержал заголовки столбцов, то у вас всегда будет 13 столбцов. Вам просто нужно будет пропустить строку заголовка при обработке.
Это также исправит ситуации, когда пользователь помещает столбцы в порядке, которого вы не ожидаете. (обнаружение индексов столбцов в строке заголовка и чтение соответствующим образом)
Я вижу, что другие рекомендуют взаимодействие с Excel, но, черт возьми, это медленный вариант по сравнению с OleDb-способом. Плюс это требует установки Excel или OWC на сервере (лицензирование).
Можно попробовать использовать Excel и COM. Таким образом, вы будете получать информацию прямо из пасти лошади, так сказать.
От д. Ананда на форумах MSDN:
Создайте в проекте ссылку на библиотеку объектов Excel. Библиотека объектов excel может быть добавлена на вкладке COM диалогового окна добавление ссылки.
Вот некоторые сведения об объектной модели Excel в C# http://msdn.microsoft.com/en-us/library/aa168292 (офис.11).aspx
Я рекомендую вам попробовать Visual Studio Tools for Office и Excel Interop! Его использование очень легко.
Comments