C#/ASP.NET Oledb - MS Excel считал “Неустановленную ошибку”

Один из вариантов будет:

struct widget_t {
    char const *name;
    uint8_t numberOfNicknames;
    char const * const *nicknames;
};

static char const *mower_nicknames[] = { "Choppie", "Bob" };
widget_t SomeWidget = { "Lawn Mower", 2, mower_nicknames };

static char const *bus_nicknames[] = { "Wheels", "Go", "Round" };
widget_t OtherWidget = { "Bus", 3, bus_nicknames };

// no setup function needed
5
задан 17 March 2009 в 04:57
поделиться

5 ответов

SpreadsheetGear для.NET дает Вам API для работы с xls и xlsx рабочими книгами от.NET. Легче использовать и быстрее, чем OleDB, или модель COM-объекта Excel (продолжайте читать для некоторого доказательства этого).

Отказ от ответственности: Я владею SpreadsheetGear LLC

Ниже код, чтобы создать 50 000 строк рабочей книгой на 10 столбцов с SpreadsheetGear, сохранить его на диск и затем суммировать использование чисел OleDb и SpreadsheetGear. SpreadsheetGear читает 500K ячейки за 0,31 секунды по сравнению с 0,63 секундами с OleDB - чуть более чем вдвое более быстрый. SpreadsheetGear на самом деле создает и читает рабочую книгу за меньшее время, чем он берет для чтения рабочей книги с OleDB.

Код ниже. Вы видите живые образцы или пробуете его за себя с бесплатной демонстрационной версией.

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 would 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;
        }
    }
}
1
ответ дан 13 December 2019 в 19:37
поделиться

Я использовал SpreadSheetGear.NET некоторое время, главным образом для создания файлов Excel, и это работает хорошо.

http://www.spreadsheetgear.com/products/spreadsheetgear.net.aspx

Это обеспечивает двоичный файл Excel, читающий/пишущий в собственной.NET, решая все предыдущие проблемы, я встретился с попыткой использовать OLE и СТРУЮ, чтобы считать и создать файлы Excel.

Базовая версия раньше стала бесплатная привилегией для регистрации Экспресса Visual C++ 2005. Это было необъявленным, таким образом, это может или не может все еще существовать с выпуском 2008 года.

2
ответ дан 13 December 2019 в 19:37
поделиться

Удостоверьтесь, что Вы закрываете свои соединения.

Например, при разрабатывании приложений Доступа MS (Струя) эта ошибка происходит, если слишком много соединений оставляют открытыми. Это хорошо работает (существует Ваш иногда), некоторое время, пока это не достигает макс. открытых соединений.

3
ответ дан 13 December 2019 в 19:37
поделиться

Я подозреваю, что ошибка - что-то, чтобы сделать с почтенным Струйным механизмом OLEDB. Это является довольно скрипучим - прекрасный для большинства настольных вещей, но не большого использования для обмена данными предприятия.

Если можно обновить до недавнего C# 3/.Net 3.5, можно использовать System.IO.Packaging библиотека для открытия Office 2 007 файлов (.xlsx или .xlsm файлы).

Эти файлы являются на самом деле zip - переименовывают их к .zip, и можно просто просмотреть XML-файлы внутри.

Форматы XML-файлов довольно ужасны (например, комментарии ячейки являются VML, тьфу!), но читаемый.

Кроме того, заставьте своих пользователей сохранять таблицы Excel как CSVs. Я избежал бы текстового поставщика БД драйвера Microsoft, хотя - это - мусор и не может обработать unicode. CSVs легко считать так или иначе.

2
ответ дан 13 December 2019 в 19:37
поделиться

У меня была такая же проблема, и кажется, что она исправляется закрытием соединения с файлом (xls или csv) на каждой итерации цикла. Я предполагаю, что вы также просматриваете список файлов и .Open () новое соединение с каждым файлом. Если вы .Close () соединение в конце цикла, проблема, кажется, исчезнет.

1
ответ дан 13 December 2019 в 19:37
поделиться
Другие вопросы по тегам:

Похожие вопросы: