如何使用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为我们做了。我只需要知道如何自动化该过程。
答案 0 :(得分:8)
我认为你过度复杂化了。如果是CSV文件,Excel会自动将数据按逗号分隔符拆分为列。因此,您需要做的就是确保您的扩展名为CSV。
我只是尝试在Excel中快速打开文件,它工作正常。因此,您真正需要的是使用带有CSV扩展名的文件调用Workbook.Open()。
答案 1 :(得分:8)
您可以打开Excel,开始录制宏,执行您想要的操作,然后查看宏录制的内容。这应该告诉你使用什么对象以及如何使用它们。
答案 2 :(得分:4)
我相信有两个部分,一个是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引用,此时我想要使用的文件,这就是我传递的内容。可以在谷歌上搜索所有参数的用途,但基本上使用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 factory = DbProviderFactories.GetFactory(“System.Data.OleDb”);
using (DbConnection connection = factory.CreateConnection())
{
connection.ConnectionString = connectString;
using (DbCommand command = connection.CreateCommand())
{
connection.Open();
接下来我们需要DB插入的实际逻辑。因此,基本上将查询抛出到循环或任何逻辑中,并逐行插入数据。
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表的所有我的forumals将正常运行,因为值是正确的类型。如果您的目标与我的相似,并且使用已经指向此数据的模板(仅从第10行而不是第2行开始),这可能对您有用。
因此,excel中的raw_aaa选项卡可能如下所示: correid 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列将被检测为一个数字,并且插入的任何数据都将被正确处理。
Antoher注意到这让人讨厌,Jet Driver只有32位,所以在我的情况下我有一个明确的64位程序,我无法直接执行它。所以我有一个讨厌的黑客写入文件,然后启动一个程序,将文件中的数据插入我的Excel模板。
总而言之,我认为解决方案非常糟糕,但到目前为止还没有找到更好的方法来做到这一点。祝你好运!
答案 3 :(得分:3)
您可以查看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。
答案 4 :(得分:1)
答案 5 :(得分:-1)
好吧,从CSV导入应该不是什么大问题。我认为最基本的方法是使用字符串操作来完成它。您可以使用简单的Split()命令构建一个非常精细的解析器,并将数据包装到数组中。