【问题标题】:C# Excel import data from CSV into ExcelC# Excel 将数据从 CSV 导入 Excel
【发布时间】:2010-12-07 22:09:25
【问题描述】:

如何使用 C# 从 CSV 文件导入 Excel 中的数据?实际上,我想要实现的与我们在 Excel 中所做的类似,您转到 Data 选项卡,然后选择 From Text 选项,然后使用 Text到列 选项并选择 CSV,它会发挥神奇的作用,以及所有这些东西。我想自动化它。

如果您能指引我正确的方向,我将不胜感激。

编辑:我想我解释得不好。我想做的是像

Excel.Application excelApp;
Excel.Workbook excelWorkbook;

// open excel
excelApp = new Excel.Application();

// something like
excelWorkbook.ImportFromTextFile(); // is what I need

我想将该数据导入 Excel,而不是我自己的应用程序。据我所知,我认为我不必自己解析 CSV,然后将它们插入 Excel。 Excel 为我们做到了这一点。我只需要知道如何自动化这个过程。

【问题讨论】:

  • 所以你只想在excel中打开一个csv文件?或者您想将 csv 文件数据导入您的应用程序?还是?
  • 我只想在 Excel 中打开它:) 并在 Excel 中应用“文本到列”选项

标签: c# excel csv import vsto


【解决方案1】:

你可以看看TakeIo.Spreadsheet .NET library。它接受来自 Excel 97-2003、Excel 2007 和更新版本以及 CSV 格式(分号或逗号分隔符)的文件。

例子:

var inputFile = new FileInfo("Book1.csv"); // could be .xls or .xlsx too
var sheet = Spreadsheet.Read(inputFile);

foreach (var row in sheet)
{
    foreach (var cell in row)
    {
        // do something
    }
}

您可以使用Normalize() 函数从导入的数据中删除开头和结尾的空行,以及开头和结尾的列:

sheet.Normalize();

有时您会发现导入的数据在数据之间包含空行,因此您可以针对这种情况使用另一个助手:

sheet.RemoveEmptyRows();

还有一个 Serialize() 函数也可以将任何输入转换为 CSV:

var outfile = new StreamWriter("AllData.csv");
sheet.Serialize(outfile);

如果您想在 CSV 文件中使用逗号而不是默认的分号分隔符,请执行以下操作:

sheet.Serialize(outfile, ',');

是的,还有一个ToString() 函数...

这个包也可以在 NuGet 上找到,看看TakeIo.Spreadsheet

【讨论】:

    【解决方案2】:
    【解决方案3】:

    您可以打开 Excel,开始录制宏,做您想做的事,然后查看宏录制的内容。这应该会告诉您要使用哪些对象以及如何使用它们。

    【讨论】:

    • 那么您真正想做的是显示配置 CSV 导入的对话框?
    • 这对我也有很大帮助。谢谢!
    【解决方案4】:

    我认为你把事情复杂化了。如果数据是 CSV 文件,Excel 会自动通过逗号分隔符将数据拆分为列。因此,您需要做的就是确保您的扩展程序是 CSV。

    我刚刚尝试在 Excel 中快速打开一个文件,它工作正常。因此,您真正需要的只是使用带有 CSV 扩展名的文件调用 Workbook.Open()。

    【讨论】:

    • 是的,确实如此 - 但区域设置存在细微差别。例如,英语(英国或美国)更喜欢逗号作为分隔符(列表分隔符)并使用小数点作为数字,而德语(德国)设置使用分号作为分隔符,逗号作为小数。因此,如果 Excel 不理解分隔符,它会将所有内容加载到 A 列中。指定分隔符的唯一方法是通过 Windows,或者打开一个空工作簿并选择数据 -> 从文本/CSV。这并不总是通过文件扩展名分配以正确的方式工作。
    【解决方案5】:

    我相信有两个部分,一个是另一个响应者已经接受的 csv 的拆分操作,我认为这不是必需的,但无论如何我都会包括在内。最重要的是写入 excel 文件,我能够开始工作,但在特定情况下,完成起来很痛苦。

    CSV 非常简单,您可以根据需要在逗号分隔符上执行 string.split。但是,这种方法非常糟糕,尽管我承认我自己也使用过,主要是因为我也可以控制源数据,并且知道不会出现引号或转义字符。我已经包含了一篇关于正确 csv 解析的文章的链接,但是,我自己从未测试过源代码或完全审核过代码。我成功地使用了同一作者的其他代码。 http://www.boyet.com/articles/csvparser.html

    第二部分要复杂得多,对我来说是一个巨大的痛苦。我采用的方法是使用 jet 驱动程序将 excel 文件视为数据库,然后对其运行 SQL 查询。有一些限制,这可能会导致这不符合您的目标。我一直在寻找使用预建的 excel 文件模板来基本上显示数据和一些预设函数和图表。为此,我有几个报告数据选项卡,一个是 raw_data 选项卡。我的程序写入 raw_data 选项卡,所有其他选项卡计算都指向此表中的单元格。我将在代码之后讨论这种行为的一些原因:

    首先,导入(可能不是全部都需要,这是从一个更大的类文件中提取的,我没有正确评论什么是什么):

    using System.IO;
    using System.Diagnostics;
    using System.Data.Common;
    using System.Globalization;
    

    接下来我们需要定义连接字符串,此时我的类已经有一个指向我要使用的文件的 FileInfo 引用,所以这就是我传递的内容。可以在 google 上搜索所有参数的用途,但基本上使用 Jet 驱动程序(应该在任何 Windows 安装上都可用)打开一个 excel 文件,就像您指的是数据库一样。

    string connectString = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source={filename};Extended Properties=""Excel 8.0;HDR=YES;IMEX=0""";
    connectString = connectString.Replace("{filename}", fi.FullName);
    

    现在让我们打开与 DB 的连接,并准备在 DB 上运行命令:

    DbProviderFactory 工厂 = DbProviderFactories.GetFactory("System.Data.OleDb");

    using (DbConnection connection = factory.CreateConnection())
    {
      connection.ConnectionString = connectString;
      using (DbCommand command = connection.CreateCommand())
      {
        connection.Open();
    

    接下来我们需要数据库插入的实际逻辑。所以基本上将查询放入一个循环或任何你的逻辑,并逐行插入数据。

    string query = "INSERT INTO [raw_aaa$] (correlationid, ipaddr, somenum) VALUES (\"abcdef", \"1.1.1.1", 10)";
    command.CommandText = query;
    command.ExecuteNonQuery();
    

    现在这是真正令人讨厌的部分,excel驱动程序会在插入之前尝试检测你的列类型,所以即使你传递了一个正确的整数值,如果excel认为列类型是文本,它会插入你所有的数字作为文本,很难将其视为数字。因此,excel 必须已经将列类型作为数字。为了做到这一点,对于我的模板文件,我用虚拟数据填充了前 10 行,这样当您在 jet 驱动程序中加载文件时,它可以检测到正确的类型并使用它们。然后我所有指向我的 csv 表的论坛都会正常运行,因为这些值的类型是正确的。如果您的目标与我的相似,并且使用已经指向此数据的模板(从第 10 行而不是第 2 行开始),这可能对您有用。

    因此,我在 excel 中的 raw_aaa 选项卡可能看起来像这样: 相关id ipaddr somenum abcdef 1.1.1.1 5 abcdef 1.1.1.1 5 abcdef 1.1.1.1 5 abcdef 1.1.1.1 5 abcdef 1.1.1.1 5 abcdef 1.1.1.1 5 abcdef 1.1.1.1 5 abcdef 1.1.1.1 5

    注意第 1 行是我在 sql 查询中引用的列名。我认为你可以不用这个,但这需要更多的研究。由于 Excel 文件中已经有这些数据,somenum 列将被检测为数字,并且插入的任何数据都将被正确处理。

    另一个让这很烦人的注意事项是,Jet 驱动程序只有 32 位,所以在我有一个明确的 64 位程序的情况下,我无法直接执行它。所以我有一个讨厌的 hack 写入文件,然后启动一个程序,将文件中的数据插入到我的 excel 模板中。

    总而言之,我认为解决方案非常糟糕,但遗憾的是到目前为止还没有找到更好的方法来解决这个问题。祝你好运!

    【讨论】:

      【解决方案6】:

      嗯,从 CSV 导入应该没什么大不了的。我认为最基本的方法是使用字符串操作来完成。您可以使用简单的 Split() 命令构建一个非常精细的解析器,并在数组中获取内容。

      【讨论】:

      • 相当不错,但非常脆弱。
      • 请记住,这种方法可以转义逗号。您也必须考虑到这一点
      • 然后进入国产 CSV 解析器的兔子洞。如何处理无效的 CSV 文件等
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-12
      • 2012-08-06
      • 2014-08-27
      • 1970-01-01
      相关资源
      最近更新 更多