2010-06-02 4 views
2

Читаю файл Excel с использованием OLEDB в Csharp я показал образец данных Excel, что яЧтение Excel с помощью OLEDB читает строки как DBNull

F1 F2 F3 F4 
India 23 44 4 
China 4  8  Month 6 
USA 45 Neg 4 

Когда я прочитал эти данные и проверить в моей DataTable я получаю Null значения для «Месяц 6» и «Негативный» , где я могу правильно получить столбец F1 ... моя строка подключения показана так, как показано

Поставщик = Microsoft.ACE.OLEDB.12.0; Источник данных = [XLSource ]; Расширенные свойства = Excel 12.0;

OleDbDataReader dr; 
OleDbConnection conExcel = new OleDbConnection(); 
conExcel.ConnectionString = ConnectionString 
conExcel.Open(); 
OleDbCommand cmdExcel = new OleDbCommand(); 
cmdExcel.Connection = conExcel; 
cmdExcel.CommandText = "SELECT * FROM Sheet1$"; 
dr = cmdExcel.ExecuteReader(); 
DataTable dtExcel = new DataTable(); 
dtExcel.Load(dr); 
+1

Можете ли вы показать код, как вы его читаете в своем DataTable? – chiccodoro

+1

недостаточно информации для ответа –

ответ

4

Попробуйте использовать параметр IMEX = 1 в строке подключения (для получения дополнительной информации о Google).

Я думаю, что происходит то, что Excel выводит тип данных каждого столбца из первых нескольких строк. Когда он затем встречает значение, которое не соответствует типу данных inferred, он рассматривает его как null.

+0

, но для регистрации некоторой библиотеки DLL в системе, когда я ее использую, отображается «Не удалось найти устанавливаемый ISAM». – Sathish

+1

Возможно, синтаксис вашей строки подключения неверен. Googling для «Excel Oledb не смог найти устанавливаемый ISAM», будет включать некоторую помощь, включая следующий поток: http://www.devnewsgroups.net/adonet/t16014-could-not-find-installable-isam.aspx – Joe

+0

Расширенные свойства должен быть помещен в кавычки Extended Properties = "" Excel 8.0; HDR = NO "" " – rsapru

2

У меня была эта проблема, но вместо установки IMEX = 1. Я установил параметр реестра TypeGuessRows в 0, а не по умолчанию 8, я прочитал, что IMEX будет где-то нужен, но, похоже, он может изменить это изменение реестра в любом случае.
Однако я использую поставщик Jet, а не Ace, чтобы иметь значение.

Для меня я нашел установку на: Hkey_Local_Machine/Software/Microsoft/Jet/4.0/Engines/Excel/TypeGuessRows

+0

, когда я меняю это значение на ноль, слишком долго читать лист :( – Sathish

+0

Ну, насколько мне известно, действительный значения равны 0-16, где значение 0 означает чтение всех строк (до 65000 или что-то, что я думаю, так что это плохо для больших листов), чтобы определить тип данных, в то время как другие значения означают чтение многих строк, поэтому, я полагаю, вы могли бы попробовать с 16 и посмотреть, поможет ли это. –

0

Я отвечал на подобный вопрос here. Здесь я скопировал и вставил один и тот же ответ для вашего удобства:

У меня была эта же проблема, но мне удалось обойти ее, не прибегая к интерфейсу Excel COM или стороннему программному обеспечению. Это связано с небольшими затратами на обработку, но, похоже, работает для меня.

  1. Первое чтение в данных, чтобы получить имена столбцов
  2. Затем создайте новый набор данных с каждой из этих колонн, установка каждого из них Datatypes в строку.
  3. Прочтите данные снова в этот новый набор данных . Voila - научная нотация теперь ушла, и все считывается как строка.

Вот несколько примеров, иллюстрирующих это, и в качестве дополнительного бонуса это даже StyleCopped!

public void ImportSpreadsheet(string path) 
{ 
    string extendedProperties = "Excel 12.0;HDR=YES;IMEX=1"; 
    string connectionString = string.Format(
     CultureInfo.CurrentCulture, 
     "Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=\"{1}\"", 
     path, 
     extendedProperties); 

    using (OleDbConnection connection = new OleDbConnection(connectionString)) 
    { 
     using (OleDbCommand command = connection.CreateCommand()) 
     { 
      command.CommandText = "SELECT * FROM [Worksheet1$]"; 
      connection.Open(); 

      using (OleDbDataAdapter adapter = new OleDbDataAdapter(command)) 
      using (DataSet columnDataSet = new DataSet()) 
      using (DataSet dataSet = new DataSet()) 
      { 
       columnDataSet.Locale = CultureInfo.CurrentCulture; 
       adapter.Fill(columnDataSet); 

       if (columnDataSet.Tables.Count == 1) 
       { 
        var worksheet = columnDataSet.Tables[0]; 

        // Now that we have a valid worksheet read in, with column names, we can create a 
        // new DataSet with a table that has preset columns that are all of type string. 
        // This fixes a problem where the OLEDB provider is trying to guess the data types 
        // of the cells and strange data appears, such as scientific notation on some cells. 
        dataSet.Tables.Add("WorksheetData"); 
        DataTable tempTable = dataSet.Tables[0]; 

        foreach (DataColumn column in worksheet.Columns) 
        { 
         tempTable.Columns.Add(column.ColumnName, typeof(string)); 
        } 

        adapter.Fill(dataSet, "WorksheetData"); 

        if (dataSet.Tables.Count == 1) 
        { 
         worksheet = dataSet.Tables[0]; 

         foreach (var row in worksheet.Rows) 
         { 
          // TODO: Consume some data. 
         } 
        } 
       } 
      } 
     } 
    } 
} 
0

Я ответил another question очень понравился этот.

Короче говоря, параметры, которые контролируют поведение водителя ACE расположены в реестре по адресу:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\14.0\Access Connectivity Engine\Engines\Excel 

Набор ImportMixedTypes к Text и установите TypeGuessRows в 0 (или какой-то достаточно большое количество как 1000), и вы должны получите поведение, которое вы ожидаете.

Смежные вопросы