Excel «Внешняя таблица не в ожидаемом формате.»


162

Я пытаюсь прочитать файл Excel (xlsx), используя код, показанный ниже. Я получаю «Внешняя таблица не в ожидаемом формате». ошибка, если у меня нет файла уже открыт в Excel. Другими словами, мне нужно сначала открыть файл в Excel, прежде чем я смогу прочитать его из моей программы на C #. Файл xlsx находится в общем доступе в нашей сети. Как я могу прочитать файл, не открывая его сначала? Спасибо

string sql = "SELECT * FROM [Sheet1$]";
string excelConnection = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + pathname + ";Extended Properties=\"Excel 8.0;HDR=YES;IMEX=1;\"";

using (OleDbDataAdapter adaptor = new OleDbDataAdapter(sql, excelConnection)) {
    DataSet ds = new DataSet();
    adaptor.Fill(ds);
}

Я получил это на листе Excel, пытаясь открыть его, я использовал текущий ACE и предложенные расширенные свойства. Когда я вручную открывал файл, в верхней части окна было это приглашение включить редактирование, мне нужно было разобраться, как автоматически перевернуть этот бит, но если вы получаете это, вам, возможно, просто нужно открыть файл, а затем включить редактирование , Я могу посмотреть, смогу ли я открыть файл только для чтения, я увидел кое-что очень об этом в этой теме.
Джефф Паттон

Ответы:


246

«Внешняя таблица не в ожидаемом формате.» обычно возникает при попытке использовать файл Excel 2007 со строкой подключения, которая использует: Microsoft.Jet.OLEDB.4.0 и Extended Properties = Excel 8.0

Использование следующей строки подключения, кажется, решает большинство проблем.

public static string path = @"C:\src\RedirectApplication\RedirectApplication\301s.xlsx";
public static string connStr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + path + ";Extended Properties=Excel 12.0;";

10
По иронии судьбы я получил эту ошибку из чужого приложения (Scribe), но объяснение все же решило проблему для меня: «Сохранить как» в Excel 97-2003, и ошибка исправлена.
Джефф Дэвис

4
Расширение .xlsx или .xls?
FAtBalloon

3
вам, возможно, придется сначала установить это: microsoft.com/en-us/download/confirmation.aspx?id=23734
rovsen

11
это может быть невероятно, но я просто изменяю имя листа на строчные и использую sheet1 $
Смит

3
Я использую LinqToExcel, и чтобы LinqToExcel использовал эту строку запроса, мне нужно переименовать файл в xlsx. Эта электронная таблица действительно является таблицей Excel 97, но поставщик odbc, похоже, не заботится об этом. Как только я обманом заставлю LinqToExcel использовать правильную строку запроса, поставщик, по-видимому, определяет, как читать файл независимо от его расширения. Удобная лазейка в моем случае.
Тим Кокер

26

Спасибо за этот код :) Я действительно ценю это. Работает для меня.

public static string connStr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + path + ";Extended Properties=Excel 12.0;";

Так что, если у вас есть diff версия файла Excel, получите имя файла, если его расширение - .xlsx , используйте это:

Private Const connstring As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + path + ";Extended Properties=Excel 12.0;";

и если это .xls , используйте:

Private Const connstring As String = "Provider=Microsoft.Jet.OLEDB.4.0;" & "Data Source=" + path + ";Extended Properties=""Excel 8.0;HDR=YES;"""

5
К вашему сведению: это вызовет исключение OleDbException, если вы попытаетесь открыть .xlsфайл на ПК, на котором не установлен Jet OleDb.
jp2code

@ Трекс, ты уверен, что твоя последняя строка кода верна? Можете ли вы еще раз проверить это в каком-нибудь редакторе?
Йоги

15

(У меня слишком низкая репутация, чтобы комментировать, но это комментарий к записи JoshCaba, использующей движок Ace вместо Jet для Excel 2007)

Если на вашем компьютере Ace не установлен / не зарегистрирован, вы можете получить его по адресу: https://www.microsoft.com/en-US/download/details.aspx?id=13255.

Это относится и к Excel 2010.


У меня установлен движок ACE, но мне нужно знать, какую ссылку II нужно включить в мой проект, чтобы мой установщик включил ее. Не на всех машинах, на которых установлено мое приложение, обязательно будет установлен MS Office.
jp2code

1
Ссылка теперь дает сообщение об ошибке - We're sorry, this download is no longer available.
RBT

9

Просто добавьте мой случай. Мой файл xls был создан функцией экспорта данных с веб-сайта, расширение файла - xls, его обычно можно открыть в MS Excel 2003. Но и Microsoft.Jet.OLEDB.4.0, и Microsoft.ACE.OLEDB.12.0 получили " Внешняя таблица не в ожидаемом формате "исключение.

Наконец, проблема заключается в том, что, как говорится в исключении, «это не в ожидаемом формате». Хотя это расширение имя xls, но когда я открываю его с помощью текстового редактора, это на самом деле правильно сформированный HTML-файл, все данные находятся в <table>, каждый <tr> является строкой, а каждый <td> является клетка. Тогда я думаю, что могу разобрать его в формате HTML.


Это был и мой случай, однако мой файл на самом деле был XML. Тем не менее, было бы неплохо узнать, как импортировать его с помощью OBDC, но я не думаю, что он поддерживается.
Дэвид Роджерс

@DavidRogers, я когда-либо видел что-то вроде XML ODBC Driver, но никогда не использовал, вы посмотрите на cdata.com/drivers/xml/odbc .
Джозеф Дин

То же самое и здесь, я думаю, что магия началась с открытия файла с помощью блокнота, на самом деле я голосую за ваш ответ, потому что я не прокручивал вниз, чтобы увидеть ваше сообщение до сих пор (и теперь я уже открыл файл / проанализировал его с пакетом Html Agility ...) но ваш ответ заслуживает того, чтобы быть на вершине, по чистой логике: ОТКРЫТЬ ФАЙЛ ПЕРВЫЙ! и посмотрите, есть ли внутри какой-нибудь стиль файла Excel-ish!
Габриэль G

Если это HTML-файл, просто примените расширенные свойства следующим образом:Extended Properties=""HTML Import;HDR=No;IMEX=1
Nepaluz

4

У меня такая же проблема. который решен с помощью этих шагов:

1.) Нажмите Файл

2.) Выберите «Сохранить как»

3.) Нажмите на выпадающее меню (Сохранить как тип)

введите описание изображения здесь

4.) Выберите книгу Excel 97-2003

введите описание изображения здесь

5.) Нажмите на кнопку Сохранить

введите описание изображения здесь


1
Бу! Возвращение к устаревшему формату файла даже не должно рассматриваться. На момент этого ответа формат 97-2003 был 16 лет и 12 лет устарели. Я мог бы понять несколько лет, но более десяти лет не должны предлагать профессиональному разработчику, что формат файла должен быть старше.
Лемарти

3

У меня была та же самая проблема (Используя ACE.OLEDB), и что решило это для меня, была эта ссылка:

http://support.microsoft.com/kb/2459087

Суть в том, что установка нескольких версий Office и различных офисных SDK, сборок и т. Д. Привела к ссылке ACEOleDB.dll в реестре, указывающей на папку OFFICE12 вместо OFFICE14 в

C: \ Program Files \ Common Files \ Microsoft Shared \ OFFICE14 \ ACEOLEDB.DLL

По ссылке:

Кроме того, вы можете изменить раздел реестра, изменив путь к DLL, чтобы он соответствовал вашей версии Access.

Access 2007 должен использовать OFFICE12, Access 2010 - OFFICE14 и Access 2013 - OFFICE15

(ОС: 64-битная Офис: 64-битная) или (ОС: 32-битная Офис: 32-битная)

Ключ: HKCR \ CLSID {3BE786A0-0366-4F5C-9434-25CF162E475E} \ InprocServer32 \

Имя значения: (по умолчанию)

Данные значения: C: \ Program Files \ Common Files \ Microsoft Shared \ OFFICE14 \ ACEOLEDB.DLL

(ОС: 64-битная Офис: 32-битная)

Ключ: HKCR \ Wow6432Node \ CLSID {3BE786A0-0366-4F5C-9434-25CF162E475E} \ InprocServer32 \

Имя значения: (по умолчанию)

Данные значения: C: \ Program Files (x86) \ Общие файлы \ Microsoft Shared \ OFFICE14 \ ACEOLEDB.DLL


Я обнаружил, что проще просто перейти к «Программы и компоненты» и «Восстановить ACE». (Для меня ACE называется Microsoft Access Runtime 2016). Я предполагаю, что у меня был этот вариант проблемы, и что Repair просто сбросил все ключи реестра для меня, и мне не пришлось беспокоиться о regedit ;-).
Бинки,

2

Я также видел эту ошибку при попытке использовать сложные формулы INDIRECT () на импортируемом листе. Я заметил это, потому что это было единственное различие между двумя книгами, в которые импортировалась одна, а другой - нет. Оба были 2007+ .XLSX файлами, и был установлен механизм 12.0.

Я подтвердил, что это проблема:

  • Создание копии файла (проблема все еще существовала, поэтому не было никакой разницы при сохранении)
  • Выбор всех ячеек на листе с помощью косвенных формул
  • Вставка только как значения

и ошибка исчезла.


2

Я получал ошибки при чтении книги XLSX сторонней организацией и Oledb. Похоже, что это скрытый лист, который вызывает ошибку. Раскрытие листа позволило импортировать книгу.


2

Если файл только для чтения, просто удалите его, и он должен снова работать.


1

Наткнулся на ту же проблему и нашел эту ветку. Ни одно из предложенных выше предложений не помогло, за исключением комментария @ Smith к принятому ответу 17 апреля 13 года.

История моей проблемы достаточно близка к @ zhiyazw - в основном я пытаюсь установить экспортированный файл Excel (в моем случае SSRS) в качестве источника данных в пакете dtsx. Все, что я сделал, после некоторого возни, переименовал лист. Это не должно быть в нижнем регистре, как предложил @Smith.

Я предполагаю, что ACE OLEDB ожидает, что файл Excel будет следовать определенной структуре XML, но каким-то образом службы Reporting Services не знают об этом.


Я столкнулся с той же проблемой таблицы не в ожидаемом формате. Я убедился, что в моей книге нет скрытых листов. Фактическое имя рабочего листа в книге написано с большой буквы, но в коде C # для анализа файла я добавил .ToLower () для имени вкладки, и теперь я могу снова проанализировать файл Excel. СПАСИБО!
vvvv4d

1

Этот адрес файла Excel может иметь неправильное расширение. Вы можете изменить расширение с xls на xlsx или наоборот и попробовать еще раз.


0

файл может быть заблокирован другим процессом, вам нужно скопировать его и загрузить, как сказано в этом посте



0

Просто добавляю мое решение этой проблемы. Я загружал файл .xlsx на веб-сервер, затем читал с него и массово вставлял в SQL Server. Получал то же самое сообщение об ошибке, пробовал все предложенные ответы, но ни один не работал. В конце концов я сохранил файл как Excel 97-2003 (.xls), который работал ... единственная проблема, которую я имею сейчас, состоит в том, что исходный файл имел более 110 000 строк


0

Если у вас все еще есть эта проблема, то проверьте свои разрешения, я попробовал многие из этих предложений, и моя конкретная проблема заключалась в том, что файл, который я хотел обработать, находился под контролем исходного кода, а поток не имел разрешений, мне пришлось изменить разрешения для всей папки. и он начал работать (я там обрабатывал много файлов) ... Он также соответствует многим предложениям, таким как изменение имени файла или проверка того, что файл не заблокирован другим процессом.

Я надеюсь, что это поможет вам.


0

У меня была эта проблема, и изменение расширенных свойств на импорт HTML устранило ее в соответствии с этой записью Маркуса Мириса:

strCon = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & importedFilePathAndName _
         & ";Extended Properties=""HTML Import;HDR=No;IMEX=1"";"

0

Вместо OleDb вы можете использовать Excel Interop и открыть лист только для чтения.

https://msdn.microsoft.com/en-us/library/microsoft.office.interop.excel.workbooks.open(v=office.15).aspx


5
Взаимодействие с Excel не является рекомендуемым методом работы с Excel. Это может вызвать много проблем и поэтому не должно быть рекомендовано.
MaxOvrdrv

Хотя это старый пост, я согласен с MaxOvrdrv, однако использование взаимодействия не является хорошей идеей, и его следует избегать, если только по какой-либо причине требуется полная установка Excel на сервере.
Lemiarty

Вы не должны абсолютно этого делать.
17

0

ACE заменил JET

Ace поддерживает все предыдущие версии Office

Этот кодекс работает хорошо!

        OleDbConnection MyConnection;
        DataSet DtSet;
        OleDbDataAdapter MyCommand;
        
        MyConnection = new System.Data.OleDb.OleDbConnection(@"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=..\\Book.xlsx;Extended Properties=Excel 12.0;");
        MyCommand = new System.Data.OleDb.OleDbDataAdapter("select * from [Sheet1$]", MyConnection);
        DtSet = new System.Data.DataSet();
        
        MyCommand.Fill(DtSet);
        dataGridView1.DataSource = DtSet.Tables[0];
        MyConnection.Close();

1
Это не. Проблема все еще может возникнуть, я еще не выяснил, почему, так как все мои файлы из Excel 2007, а некоторые из них работают, а некоторые нет.
Хенрик

У вас есть источник для этого требования? Я не знаю себя, просто интересно. :-)
midoriha_senpai

0

Это может произойти, если рабочая книга защищена паролем. Есть некоторые обходные пути для удаления этой защиты, но большинство примеров, которые вы найдете в сети, устарели. В любом случае, простое решение состоит в том, чтобы снять защиту рабочей книги вручную, в противном случае используйте что-то вроде OpenXML для программного удаления защиты.


0

Я недавно видел эту ошибку в контексте, который не соответствовал ни одному из ранее перечисленных ответов. Оказалось, конфликт с AutoVer . Обходной путь: временно отключите AutoVer.


0

У меня недавно было это «System.Data.OleDb.OleDbException (0x80004005): внешняя таблица не в ожидаемом формате». ошибка произошла. Я полагался на Microsoft Access 2010 Runtime. До обновления, которое было автоматически установлено на моем сервере 12 декабря 2018 года, мой код C # работал нормально с использованием поставщика Microsoft.ACE.OLEDB.12.0. После установки обновления от 12 декабря 2018 года я начал получать «Внешняя таблица не в ожидаемом формате» в моем файле журнала.

Я отключил Microsoft Access 2010 Runtime и установил Microsoft Access 2013 Runtime, и мой код C # снова начал работать без «System.Data.OleDb.OleDbException (0x80004005): внешняя таблица не в ожидаемом формате». ошибки.

Версия 2013 года, которая исправила эту ошибку для меня https://www.microsoft.com/en-us/download/confirmation.aspx?id=39358

Версия 2010, которая работала для меня до обновления, которое было автоматически установлено на моем сервере 12 декабря. https://www.microsoft.com/en-us/download/confirmation.aspx?id=10910 https://www.microsoft.com/en-us/download/confirmation.aspx?id=10910

Я также имел эту ошибку в прошлом месяце в автоматизированном процессе. Код C # работал нормально, когда я запускал его отладку. Я обнаружил, что учетной записи службы, выполняющей код, также необходимы разрешения для папки C: \ Windows \ Temp.


0

Моя область действия состоит из загрузки шаблона и проверки шаблона, когда он заполнен данными. Итак,

1) Загрузите файл шаблона (.xlsx) со строкой заголовка. файл создается с использованием openxml, и он работает отлично.

2) Загрузить тот же файл без каких-либо изменений из его загруженного состояния. Это приведет к ошибке соединения и не удастся (соединение OLEDB используется для чтения таблицы Excel).

Здесь, если данные заполнены, программа работает как положено.

Любой, кто имеет представление о проблеме, связан с файлом, который мы создаем, в формате xml , если мы откроем его и просто сохраним, преобразуем его в формат Excel, и он работает хорошо.

Любая идея скачать Excel с предпочтительным типом файла?


Вы не должны задавать вопросы в своих ответах, если вам нужны ответы на ваши вопросы, задавайте их отдельно, если это необходимо.
Абхишек

0

Работая с более старым кодом и наткнулся на это же общее исключение. Очень сложно отследить проблему, поэтому я решил добавить сюда, если это поможет кому-то еще.

В моем случае в другом месте проекта был код, который открывал StreamReader для файла Excel до того, как OleDbConnection попытался открыть файл (это было сделано в базовом классе).

Поэтому в основном мне просто нужно было Close()сначала вызвать объект StreamReader, а затем я мог бы успешно открыть соединение OleDb. Это не имело никакого отношения к самому файлу Excel или к строке OleDbConnection (что, естественно, я и просматривал вначале).

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.