Read/write Excel 文件没有安装任何东西
Read/write Excel file without installing anything
我有一个 Excel .xlsx
文件。我想从文件中读取数据并将数据写回文件;没有图形、方程式、图像,只有数据。
我尝试使用 System.Data.OleDb
中的类型进行连接:
using System.Data.OleDb;
var fileName = @"C:\ExcelFile.xlsx";
var connectionString =
"Provider=Microsoft.ACE.OLEDB.12.0;" +
$"Data Source={fileName};" +
"Extended Properties=\"Excel 12.0;HDR=NO;TypeGuessRows=0;ImportMixedTypes=Text\"";
using var conn = new OleDbConnection(connectionString);
conn.Open();
但出现以下错误:
The 'Microsoft.ACE.OLEDB.12.0' provider is not registered on the local machine.
我知道我可以安装 Microsoft Access Database Engine 2016 Redistributable,但我想在不安装其他软件的情况下安装。
我该怎么做?
对于初学者,您可能已经安装了驱动程序,但仅适用于 32 位程序,而您的程序 运行 在 64 位下(反之亦然,但这不太常见)。
您可以在 .csproj
文件中强制指定环境。要强制使用 32 位,请使用:
<PropertyGroup>
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
并强制 64 位:
<PropertyGroup>
<PlatformTarget>x64</PlatformTarget>
</PropertyGroup>
如果在其他环境中安装了驱动程序,您的代码应该连接成功。
注意。您可以使用如下代码列出当前环境的可用提供程序:
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 2000 年以来,每个版本的 Windows 中都安装了该文件(仅适用于 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);
}
};
注意。我发现为了更新数据,我需要根据 this answer.
从连接字符串中删除 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, which supports both reading and writing. I think this 是一个很好的起点 -- 它显示了如何从给定的单元格中读取信息,以及如何将信息写回到单元格中。
我有一个 Excel .xlsx
文件。我想从文件中读取数据并将数据写回文件;没有图形、方程式、图像,只有数据。
我尝试使用 System.Data.OleDb
中的类型进行连接:
using System.Data.OleDb;
var fileName = @"C:\ExcelFile.xlsx";
var connectionString =
"Provider=Microsoft.ACE.OLEDB.12.0;" +
$"Data Source={fileName};" +
"Extended Properties=\"Excel 12.0;HDR=NO;TypeGuessRows=0;ImportMixedTypes=Text\"";
using var conn = new OleDbConnection(connectionString);
conn.Open();
但出现以下错误:
The 'Microsoft.ACE.OLEDB.12.0' provider is not registered on the local machine.
我知道我可以安装 Microsoft Access Database Engine 2016 Redistributable,但我想在不安装其他软件的情况下安装。
我该怎么做?
对于初学者,您可能已经安装了驱动程序,但仅适用于 32 位程序,而您的程序 运行 在 64 位下(反之亦然,但这不太常见)。
您可以在 .csproj
文件中强制指定环境。要强制使用 32 位,请使用:
<PropertyGroup>
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
并强制 64 位:
<PropertyGroup>
<PlatformTarget>x64</PlatformTarget>
</PropertyGroup>
如果在其他环境中安装了驱动程序,您的代码应该连接成功。
注意。您可以使用如下代码列出当前环境的可用提供程序:
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 2000 年以来,每个版本的 Windows 中都安装了该文件(仅适用于 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);
}
};
注意。我发现为了更新数据,我需要根据 this answer.
从连接字符串中删除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, which supports both reading and writing. I think this 是一个很好的起点 -- 它显示了如何从给定的单元格中读取信息,以及如何将信息写回到单元格中。