使用C#将CSV数据导入Excel

9
如何使用C#从CSV文件导入Excel中的数据?实际上,我想要实现的与我们在Excel中所做的类似,您进入“数据”选项卡,然后选择“从文本”选项,然后使用“文本到列”选项并选择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会替我们完成这个过程。我只需要知道如何自动化这个过程。


1
所以你只是想在Excel中打开一个CSV文件吗?还是你想将CSV文件数据导入到你的应用程序中?或者? - Svish
我只想在Excel中打开它 :) 并在Excel中应用“文本到列”选项 - akif
6个回答

8

我认为你把事情复杂化了。如果是CSV文件,Excel会自动根据逗号分隔符将数据拆分成列。因此,您只需要确保文件扩展名为CSV。

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


是的,没错 - 但是区域设置有微妙的差别。例如,英语(英国或美国)更喜欢使用逗号作为分隔符(列表分隔符),并使用小数点表示数字,而德语(德国)设置则使用分号作为分隔符和逗号表示小数。因此,如果Excel无法理解分隔符,则会将所有内容加载到A列中。指定分隔符的唯一方法是通过Windows,或者如果您打开一个空工作簿并选择数据->从文本/ CSV。这并不总是通过文件扩展名分配正确地工作。 - Matt

7

您可以打开Excel,开始录制宏,执行您想要的操作,然后查看宏记录的内容。这样可以告诉您要使用哪些对象以及如何使用它们。


那么你真正想做的是显示配置CSV导入对话框吗? - Ian
这也对我很有帮助。谢谢! - jrsconfitto

4
我认为有两个部分,一个是csv的拆分操作,其他回答者已经提到了,我认为这不是必要的,但我会包含在内。另一个更重要的部分是写入Excel文件,我已经成功实现了,但只适用于特定情况,并且很难完成。
CSV非常简单,如果需要可以使用string.split按逗号分隔符进行分割。然而,这种方法存在严重缺陷,尽管我承认我自己也使用过,主要是因为我也控制着源数据,并且知道不会出现引号或转义字符。我包含了一篇关于正确解析csv的文章链接,但我从未测试过源代码或完全审查过代码本身。我已经成功地使用了同一作者的其他代码。http://www.boyet.com/articles/csvparser.html 第二部分要复杂得多,对我来说非常困难。我采用的方法是使用Jet驱动程序将Excel文件视为数据库,然后运行SQL查询。有一些限制可能导致这不适用于您的目标。我想使用预建的Excel文件模板来显示数据和一些预设的函数和图形。为了实现这一点,我有几个报告数据选项卡,以及一个原始数据选项卡。我的程序写入原始数据选项卡,而所有其他选项卡的计算都指向此表中的单元格。在代码之后,我会解释一些这种行为的原因:
首先,是导入(不一定需要所有导入,这是从一个更大的类文件中提取的,我没有正确注释哪个是哪个):
using System.IO;
using System.Diagnostics;
using System.Data.Common;
using System.Globalization;

接下来,我们需要定义连接字符串。在这一点上,我的类已经有了一个FileInfo引用,指向我想要使用的文件,所以我会传递这个引用。可以在Google上搜索所有参数的含义,但基本上使用Jet Driver(应该在任何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);

现在让我们打开与数据库的连接,并准备好在数据库上运行命令:
DbProviderFactory factory = 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选项卡可能如下所示: correlationid 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
请注意,第一行是我在SQL查询中引用的列名。我认为您可以不需要这个,但这将需要更多的研究。通过已经在Excel文件中拥有这些数据,somenum列将被检测为数字,并且插入的任何数据都将被正确处理。
另一个需要注意的地方是Jet驱动程序仅支持32位,因此在我的情况下,由于我有一个显式的64位程序,我无法直接执行此操作。所以我使用了一个恶心的hack,写入一个文件,然后启动一个程序,将文件中的数据插入到我的Excel模板中。
总的来说,我认为这个解决方案相当糟糕,但不幸的是到目前为止还没有找到更好的方法来解决这个问题。祝你好运!

3
你可以看一下TakeIo.Spreadsheet .NET库。它支持来自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



-1

嗯,从CSV导入不应该是什么大问题。我认为最基本的方法是使用字符串操作来完成。您可以使用简单的Split()命令构建一个相当好的解析器,并将内容存储在数组中。


1
相当不错,但非常脆弱。 - Vinko Vrsalovic
2
请记住,使用此方法时,逗号可能需要转义。您也必须考虑到这一点。 - RichardOD
在自制CSV解析器的兔子洞里。你如何处理无效的CSV文件等等。 - Lance Fisher

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接