导入CSV文件时处理列顺序的更改

时间:2010-03-16 16:05:59

标签: c# excel .net-3.5

我有一个CSV文件。第一行将始终包含列标题。根据各种因素,列的顺序可能会发生变化,在极少数情况下,某些列可能不存在。这些变化超出了我的控制范围。

到目前为止,我的想法是如何解决这个问题。我将读取文件的第一行并使用这些值生成源文件中包含的列列表。目标文件将使用与源相同的列名称。这应该像在源和目标中搜索相同的名称一样简单,然后只映射列索引值,对吗?

您对此有何建议?

3 个答案:

答案 0 :(得分:0)

我曾经通过构建一个Hash Map来实现这一点,该Hash Map包含我希望存在于实际存在的列标题的索引(或实际列名)中的列的名称。我这样做的方法是首先使用我期望的所有列名称构建地图作为键,并将某些值(如-1)作为值。然后我得到了列标题数组。通过嵌套循环遍历地图中所有键的循环和文件中存在的所有标题,我在修剪掉空格后进行了不区分大小写的比较,如果有匹配,我将列的索引作为值在地图中的那个键。然后在构建目标文件时,我所要做的就是遍历CSV中每一行的地图中的键,并从地图中指定的索引中获取数据,并根据数据执行任何操作,忽略列,如果地图中的值为-1。我用Java做过这个,但我想它在C#中差不多完全相同。

答案 1 :(得分:0)

简单,将CSV文件加载到内存中,更改列顺序,保存文件。 Copied from c# documentation,LINQ非常简单。

// Create the IEnumerable data source  
string[] lines = System.IO.File.ReadAllLines(@"../../../spreadsheet1.csv");  

// Create the query. Put field 2 first, then  
// reverse and combine fields 0 and 1 from the old field  
IEnumerable<string> query =  
    from line in lines  
    let x = line.Split(',')  
    orderby x[2]  
    select x[2] + ", " + (x[1] + " " + x[0]);  

// Execute the query and write out the new file. Note that WriteAllLines  
// takes a string[], so ToArray is called on the query.  
System.IO.File.WriteAllLines(@"../../../spreadsheet2.csv", query.ToArray());  
Console.WriteLine("Spreadsheet2.csv written to disk. Press any key to exit");  
Console.ReadKey();  

答案 2 :(得分:-1)

如果我要这样做,我会使用SQL和DAO。有两个技巧。第一个是建立与Excel工作表的连接,就像它是一个数据库表(你需要DAO 3.6对象库作为VBA中的参考),

Dim dbtmp As dao.Database
Dim qd As dao.QueryDef

Set dbtmp = OpenDatabase(mPath & "\" & mName, False, True, "Excel 8.0;")
Set qd = dbtmp.CreateQueryDef("", " THE QUERY ")
qd.Execute

,第二个是建立与CSV文件的连接作为数据源。其格式如下:

mQuery = "SELECT * FROM [Text;HDR=NO;CharacterSet=437;DATABASE="
mQuery = mQuery & mpath
mQuery = mQuery & "]."
mQuery = mQuery & mfile
mQuery = mQuery & ";"

您必须使用代码构建SQL,您需要在源文件中建立字段,并且您正在构建INSERT INTO查询。并且最简单的方法是使用名称创建对源数据的选择查询,然后在插入查询中使用它

这样做的好处是SQL将处理源数据中缺少的字段,并且对于列出现的顺序不会很繁琐。您可以通过将csv作为文本文件打开来获取标题