csv修改文件

时间:2014-05-15 11:34:22

标签: c# csv

我对我们在公司使用的整合应用程序有点不满。我们从进度数据库创建一个csv文件,这个csv文件有14列,没有标题。

CSV文件包含付款(约173,000行)。除列数(最后一列)

外,其中大多数行都相同

示例:

2014;MONTH;;SC;10110;;;;;;;;EUR;-6500000
2014;01;;SC;10110;;;;;;;;EUR;-1010665
2014;01;;LLC;11110;;;;;;;;EUR;-6567000
2014;01;;SC;10110;;;;;;;;EUR;-1110665
2014;01;;LLC;11110;;;;;;;;EUR;65670.00
2014;01;;SC;10110;;;;;;;;EUR;-11146.65

(约174000行)

正如您所看到的,除了金额列之外,其中一些行是相同的。我需要的是对所有行进行排序,累加金额并保存一个唯一的行而不是1100行具有不同的金额。

我的编码技巧使我无法在一定时间内完成工作,也许你们其中一人可以帮我解决这个问题。

示例代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string input = File.ReadAllText(@"c:\temp\test.txt");
            string inputLine = "";
            StringReader reader = new StringReader(input);
            List<List<string>> data = new List<List<string>>();
            while ((inputLine = reader.ReadLine()) != null)
            {
                if (inputLine.Trim().Length > 0)
                {
                    string[] inputArray = inputLine.Split(new char[] { ';' });
                    data.Add(inputArray.ToList());
                }
            }
            //sort data by every column
            for (int sortCol = data[0].Count() - 1; sortCol >= 0; sortCol--)
            {
                data.OrderBy(x => x[sortCol]); 
            }
            //delete duplicate rows
            for (int rowCount = data.Count - 1; rowCount >= 1; rowCount--)
            {
                Boolean match = true;
                for (int colCount = 0; colCount < data[rowCount].Count - 2; colCount++)
                {
                    if(data[rowCount][colCount] != data[rowCount - 1][colCount])
                    {
                        match = false;
                        break;
                    }
                }
                if (match == true)
                {
                    decimal previousValue = decimal.Parse(data[rowCount - 1][data[rowCount].Count - 1]);
                    decimal currentValue = decimal.Parse(data[rowCount][data[rowCount].Count - 1]);
                    string newStrValue = (previousValue + currentValue).ToString();
                    data[rowCount - 1][data[rowCount].Count - 1] = newStrValue;
                    data.RemoveAt(rowCount);
                }
            }

            string output = string.Join("\r\n",data.AsEnumerable()
                .Select(x => string.Join(";",x.Select(y => y).ToArray())).ToArray());
            File.WriteAllText(@"c:\temp\test1.txt",output);
        }
    }
}

3 个答案:

答案 0 :(得分:2)

逐行读取CSV文件,并构建一个内存中的字典,在其中保存总计(以及您需要的其他信息)。由于大多数行都属于同一个键,因此可能不会导致内存不足问题。然后,根据字典中的信息生成新的CSV。

答案 1 :(得分:0)

在我解释您的问题时,您的问题和您要求的解决方案是如何采取

形式的输入
@"2014;MONTH;;SC;10110;;;;;;;;EUR;-6500000
2014;01;;SC;10110;;;;;;;;EUR;-1010665
2014;01;;LLC;11110;;;;;;;;EUR;-6567000
2014;01;;SC;10110;;;;;;;;EUR;-1110665
2014;01;;LLC;11110;;;;;;;;EUR;65670.00
2014;01;;SC;10110;;;;;;;;EUR;-11146.65"

获取最后一列然后总结一下?如果是这样,实际上很容易做到这样的事情

public static void Main()
    {
        string input = @"2014;MONTH;;SC;10110;;;;;;;;EUR;-6500000
2014;01;;SC;10110;;;;;;;;EUR;-1010665
2014;01;;LLC;11110;;;;;;;;EUR;-6567000
2014;01;;SC;10110;;;;;;;;EUR;-1110665
2014;01;;LLC;11110;;;;;;;;EUR;65670.00
2014;01;;SC;10110;;;;;;;;EUR;-11146.65";

        var rows = input.Split('\n');

        decimal totalValue = 0m;

        foreach(var row in rows)
        {           
            var transaction = row.Substring(row.LastIndexOf(';') +1);

            decimal val = 0m;

            if(decimal.TryParse(transaction, out val))
                totalValue += val;
        }

        Console.WriteLine(totalValue);
    }

但也许我误解了你的要求?

答案 2 :(得分:0)

很抱歉这么晚回答我的帖子,但这是我的最终解决方案

替换所有“字符并将输出写入流编写器。(从25mb到15mb文件。)。将我的CSV文件复制到SQL服务器,以便我可以批量插入。插入后我只是查询表并将结果集读/写到一个新文件。我的新文件只有+/- 700KB!

Filldata()方法在我的应用程序中填充datagridview,因此您可以查看结果而不是在Excel中打开文件。

我是C#的新手,我正在编写一个新的解决方案来直接或在内存中查询csv文件并将其写回新文件。

方法一:

                string line;

                StreamWriter sw = new StreamWriter(insertFile);

                using (StreamReader sr = new StreamReader(sourcePath))
                {
                    while ((line = sr.ReadLine()) != null)
                    {
                        sw.WriteLine(line.Replace("\"", ""));
                    }

                    sr.Close();
                    sw.Close();
                    sr.Dispose();
                    sw.Dispose();

                    File.Copy(insertFile, @"\\SQLSERVER\C$\insert.csv");

                }

方法2:

var destinationFile = @"c:\insert.csv";

                var querieImportCSV = "BULK INSERT dbo.TABLE FROM '" + destinationFile + "' WITH ( FIELDTERMINATOR = ';', ROWTERMINATOR = '\n', FIRSTROW = 1)";
                var truncate = @"TRUNCATE TABLE dbo.TABLE";

              string queryResult =
      @"SELECT [Year]
              ,[Month]
              ,[Week]
              ,[Entity]
              ,[Account]
              ,[C11]
              ,[C12]
              ,[C21]
              ,[C22]
              ,[C3]
              ,[C4]
              ,[CTP]
              ,[VALUTA]
              ,SUM(AMOUNT) as AMOUNT
              ,[CURRENCY_ORIG]
              ,[AMOUNTEXCH]
              ,[AGENTCODE]
            FROM dbo.TABLE
            GROUP BY YEAR, MONTH, WEEK, Entity, Account, C11, C12, C21, C22, C3, C4, CTP, VALUTA, CURRENCY_ORIG, AMOUNTEXCH, AGENTCODE
            ORDER BY Account";

                var conn = new SqlConnection(connectionString);

                conn.Open();
                SqlCommand commandTruncate = new SqlCommand(truncate, conn);
                commandTruncate.ExecuteNonQuery();

                SqlCommand commandInsert = new SqlCommand(querieImportCSV, conn);
                SqlDataReader readerInsert = commandInsert.ExecuteReader();
                readerInsert.Close();

                FillData();

                SqlCommand commandResult = new SqlCommand(queryResult, conn);
                SqlDataReader readerResult = commandResult.ExecuteReader();

                StringBuilder sb = new StringBuilder(); 

                while (readerResult.Read())
                {
                        sb.Append(readerResult["Year"] + ";" + readerResult["Month"] + ";" + readerResult["Week"] + ";" + readerResult["Entity"] + ";" + readerResult["Account"] + ";" +
                        readerResult["C11"] + ";" + readerResult["C12"] + ";" + readerResult["C21"] + ";" + readerResult["C22"] + ";" + readerResult["C3"] + ";" + readerResult["C4"] + ";" +
                        readerResult["CTP"] + ";" + readerResult["Valuta"] + ";" + readerResult["Amount"] + ";" + readerResult["CURRENCY_ORIG"] + ";" + readerResult["AMOUNTEXCH"] + ";" + readerResult["AGENTCODE"]);
                }
                sb.Replace("\"","");

                StreamWriter sw = new StreamWriter(homedrive);
                sw.WriteLine(sb);

                readerResult.Close();
                conn.Close();
                sw.Close();
                sw.Dispose();