Для начала у вас вполне может быть уже установлен драйвер, но только для 32-битных программ, а ваша программа работает под 64-битной (или наоборот, но это реже).
Вы можете указать определенную среду в файле .csproj
. Чтобы принудительно установить 32-битную версию, используйте:
<PropertyGroup>
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
и принудительно 64-битный:
<PropertyGroup>
<PlatformTarget>x64</PlatformTarget>
</PropertyGroup>
Если драйвер был установлен в другой среде, ваш код должен успешно подключиться.
NB. Вы можете перечислить доступных поставщиков для текущей среды, используя следующий код:
using System.Data;
using System.Data.OleDb;
using System.Linq;
using static System.Console;
var oleEnum = new OleDbEnumerator();
var data =
oleEnum.GetElements()
.Rows
.Cast<DataRow>()
.Select(row => (
name: row["SOURCES_NAME"] as string,
descr: row["SOURCES_DESCRIPTION"] as string
))
.OrderBy(descr => descr);
foreach (var (name, descr) in data) {
WriteLine($"{name,-30}{descr}");
}
Что делать, если у вас нет поставщика Microsoft.ACE.OLEDB.12.0
ни в одной из сред? Если вы можете преобразовать файл .xlsx
в файл .xls
, вы можете использовать файл Microsoft Jet 4.0 OLE DB Provider
, который был установлен во всех версиях Windows, начиная с Windows 2000 (доступен только для 32-разрядной версии).
Установите PlatformTarget
на x86
(32-бит), как указано выше. Затем отредактируйте строку подключения, чтобы использовать более старый провайдер:
using System.Data.OleDb;
var fileName = @"C:\ExcelFile.xls";
// note the changes to Provider and the first value in Extended Properties
var connectionString =
"Provider=Microsoft.Jet.OLEDB.4.0;" +
$"Data Source={fileName};" +
"Extended Properties=\"Excel 8.0;HDR=NO;TypeGuessRows=0;ImportMixedTypes=Text\"";
using var conn = new OleDbConnection(connectionString);
conn.Open();
Когда у вас есть открытое OleDbConnection, вы можете читать и записывать данные, используя стандартные идиомы команд ADO .NET для взаимодействия с источником данных:
using System.Data;
using System.Data.OleDb;
var ds = new DataSet();
using (var conn = new OleDbConnection(connectionString)) {
conn.Open();
// assuming the first worksheet is called Sheet1
using (var cmd = conn.CreateCommand()) {
cmd.CommandText = "UPDATE [Sheet1$] SET Field1 = \"AB\" WHERE Field2 = 2";
cmd.ExecuteNonQuery();
}
using (var cmd1 = conn.CreateCommand()) {
cmd1.CommandText = "SELECT * FROM [Sheet1$]";
var adapter = new OleDbDataAdapter(cmd);
adapter.Fill(ds);
}
};
Примечание. Я обнаружил, что для обновления данных мне нужно удалить значение IMEX=1
из строки подключения согласно этому ответу. суб>
Если вы должны использовать файл .xlsx
и вам нужно только прочитать данные из файла Excel, вы можете использовать ExcelDataReader Пакет NuGet в вашем проекте.
Затем вы можете написать код, подобный следующему:
using System.IO;
using ExcelDataReader;
// The following line is required on .NET Core / .NET 5+
// see https://github.com/ExcelDataReader/ExcelDataReader#important-note-on-net-core
System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);
DataSet ds = null;
using (var stream = File.Open(@"C:\ExcelFile.xlsx", FileMode.Open, FileAccess.Read)) {
using var reader = ExcelReaderFactory.CreateReader(stream);
ds = reader.AsDataSet();
}
Другой альтернативой, которую вы можете рассмотреть, является использование Office Open XML. SDK, поддерживающий как чтение, так и запись. Я думаю, это является хорошей отправной точкой — он показывает, как читать из данной ячейки, и как записывать информацию обратно в ячейку.
person
Zev Spitz
schedule
03.03.2021
.xlsx
-- какие файлы куда помещаются; какой файл содержит данные, которые вы ищете; и какая структура XML используется для определения данных. В общем, это почти так же сложно и хрупко, как реверс-инжиниринг провайдера. // Поддерживаете ли вы свою версию Windows в актуальном состоянии? Вы используете последнюю версию браузера? Вы должны посмотреть на эту инсталляцию в том же свете. - person Zev Spitz   schedule 04.03.2021