无需安装任何东西即可读取/写入 Excel 文件

Posted

技术标签:

【中文标题】无需安装任何东西即可读取/写入 Excel 文件【英文标题】:Read/write Excel file without installing anything 【发布时间】:2021-03-03 13:29:01 【问题描述】:

我有一个 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();

但我收到以下错误:

“Microsoft.ACE.OLEDB.12.0”提供程序未在本地计算机上注册。

我知道我可以安装Microsoft Access Database Engine 2016 Redistributable,但我想在不安装其他软件的情况下执行此操作。

我该怎么做?

【问题讨论】:

这能回答你的问题吗? 'Microsoft.ACE.OLEDB.12.0' provider is not registered on the local machine 不,我不需要任何插件或额外安装的文件,我需要知道如何通过我自己的代码设置连接 您想对整个驱动程序进行逆向工程吗?这是大约 50 MB 的代码......你最接近的方法是检查你是否安装了驱动程序并且你使用了错误的位;或者您可以使用已安装的旧版驱动程序。 不,我当然无法对整个驱动程序进行逆向工程,我认为驱动程序处理的情况或选项太多,我认为只需几行代码就可以建立 ACE 连接 几行代码就可以设置好(example),但是你需要合适的驱动;无需尝试安装缺少的驱动程序,或尝试使用备用驱动程序,您唯一的选择是 1. 对整个驱动程序和 ADODB 系统进行反向工程,或 2. 使用 .NET 文件读取、提取和 XML 解析功能从此文件中提取数据。 【参考方案1】:

对于初学者,您可能已经安装了驱动程序,但仅适用于 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,-30descr");


如果您在任一环境中都没有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,它支持读取和写入。我认为this 是一个很好的起点——它展示了如何从给定的单元格中读取数据,以及如何将信息写回单元格中。

【讨论】:

亲爱的,我将使用我的问题中的代码从 excel 文件中读取数据,但该代码给我错误“microsoft.ace.oledb.12.0 未在本地机器上注册”,我需要知道如何通过编程从我的应用程序中修复此错误消息,而不是手动,而不是通过安装任何插件 @user4773407 我想如果你真的想要,你可以从磁盘读取 Excel 文件,将其作为 ZIP 文件解压缩到磁盘,读取生成的 XML 文件,然后以这种方式提取数据。 (显然您甚至不想使用 OpenXML SDK。)我的意思是,do you want to go 要避免安装任何东西?你想写汇编程序吗? 我正在寻找从 excel 文件中读取数据并再次写入它,读取每张工作表中的工作表名称和列,只是读写,而不是方程式或图表或编辑单元格的表示 @user4773407 而您采用的方法——使用 OLEDB 和 ADO.NET 进行连接就可以做到这一点。但它依赖于能够使用相关的提供程序——Microsoft.ACE.OLEDB.12.0提供程序——这意味着需要安装提供程序,并且在适合您的代码的位数。 我不确定 ( bit-ness ) 是什么意思,那么,有没有其他方法可以在不安装任何额外插件的情况下实现我想要的功能?

以上是关于无需安装任何东西即可读取/写入 Excel 文件的主要内容,如果未能解决你的问题,请参考以下文章

无需 unicode 转义即可读写 Java 属性

从 excel 表中读取并将确切的字符写入 json 文件

无需打开即可拆分 Excel 文件

delphi 如何写入Excel

将具有多个嵌套级别的任何 XML 读取到结构化表中以写入 Excel 的通用方法

java jxl 大量数据写入excel,比如上千万条