2016-02-03 47 views
1

我正在写一个应用程序,它将数据从csv整理到txt。从csv到txt的数据排序

我已经witten,但我不能得到所需的输出。

有人可以请帮忙,我不明白我错了。

我最初认为它的File.WriteAllLines是问题,但即使在写入控制台时,我也会得到相同的结果。

我的文件看起来像这样

乔治娜,辛克莱,408999703657,查询,第一国民银行,弗威斯,275.00,12/01/2012 扎卡里,白石,409122372301,查询,ABSA,艾琳, 70.25,12/01/2012 Toby,Henderson,401255489873,支票,第一国家银行,Edenvale,181.03,12/13/2012 Katherine,Cooke,409155874935,节省,ABSA,Southdowns,975.89,01/01/2013 Bradley,James,409254998,节省,ABSA,Melville,207.74,12/09/2012 Sophie,Lane,409771987,节省,ABSA,Roodepoort,207.74,12/31/2012

我的输出应该是这样的

First National B0020000045603 
GSinclair  408999703657 CH Fourways 002750001122012 
THenderson  401255489873 CH Edenvale 001810313122012 
ABSA   0040000146162 
ZWhitehead  409122372301 CH Irene  000702501122012 
KCooke   409155874935 SAVSouthdowns009758901012013 
BJames    409254998 SAVMelville 002077409122012 
SLane    409771987 SAVRoodepoort002077431122012 

我目前拥有的代码只返回头和2线,如下所示。

ABSA     0040000146162 
KCooke 409155874935 SAVSouthdowns 009758901012013 

请协助。

我的代码如下

string text = @"C:\\Test\\output.txt"; 
    var inputEntries = File.ReadLines(@"C:\\Test\\debitorders.csv").Select(line => 
    { 
     var values = line.Split(','); 
     return new 
     { 
      accountholder = values[0].Trim().Substring(0, 1) + values[1].Trim(), 
      accountnumber = long.Parse(values[2].Trim()), 
      accounttype = values[3].Trim(), 
      bankname = values[4].Trim(), 
      branch = values[5].Trim(), 
      amount = 100 * double.Parse(values[6].Trim()), 
      date = DateTime.Parse(values[7].Trim()) 
     }; 
    }); 
    var banks = inputEntries 
          .OrderBy(e => e.bankname) 
          .GroupBy(e => e.bankname, e => e); 

    foreach (var bank in banks) 
    { 


     var AccountName = bank.Key; 
     if (AccountName.Length >= 20) 
     { 
      AccountName = AccountName.Substring(0, 16); 
     } 
     else 
     { 
      AccountName += new string(' ', 20 - AccountName.Length); 
     } 
     var NumberOfAccounts = bank.Count(); 
     var TotalAmount = bank.Select(acc => acc.amount).Sum(); 
     var Header = AccountName + "\t" + NumberOfAccounts.ToString("000") + TotalAmount.ToString("0000000000"); 


     var sortedAccounts = bank 
           .OrderBy(acc => acc.accountholder) 
           .OrderByDescending(acc => acc.amount); 


     foreach (var account in sortedAccounts) 
     { 
      var outputLine = 
      account.accountholder + "\t" + 
      account.accountnumber + "\t" + 

      //get first 2 characters 
      account.accounttype.Substring(0, 3).ToUpper() + account.branch + "\t" + "00" + 
      account.amount + 
      account.date.ToString("ddMMyyyy"); 

      for (int i = 0; i < 15; i++) 
      { 
       File.WriteAllText(text, Header + Environment.NewLine + outputLine); 

       Console.WriteLine(Header + outputLine); 
       Console.ReadLine(); 

      } 

     } 
    } 
+0

你在控制台上写了什么错误? –

+0

@ M.Schena我刚刚编辑了我的问题,我的意思是我只得到两行代码,而不是所有行的输出 –

+0

您的代码给我的合成代码 –

回答

0

一个更好的和更清洁的解决方案将是利用List<string>向其中添加文本。在代码的末尾,只需将列表转换为数组并将所有行写入文件。

List<string> outputLine = new List<string>(); //note this addition to the code 

foreach (var bank in banks) 
{ 

    //do header formatting stuff here 
    var Header = somecode 

    outputLine.Add(Header); //Add Header to outputLine 

    var sortedAccounts = bank.OrderBy(acc => acc.accountholder) 
          .OrderByDescending(acc => acc.amount); 

    foreach (var account in sortedAccounts) 
    { 
     var tempStringBuilder = 
     account.accountholder + "\t" + 
     account.accountnumber + "\t" + 
     //get first 2 characters 
     account.accounttype.Substring(0, 3).ToUpper() + account.branch + "\t" + "00" + 
     account.amount + 
     account.date.ToString("ddMMyyyy"); 

     outputLine.Add(tempStringBuilder); //Add tempStringBuilder to outputLine 
    } 
} 
File.WriteAllLines("destination path", outputLine.ToArray()); //Write everything to your output file in one go 

我测试了它,它在我身边工作。我希望这对你有帮助。


替代Excel的解决方案:

Microsoft Excel中有一个称为Pivot Tables真正强大的工具,这是非常适合您的需求。如果你不熟悉它,请阅读一些关于它的教程。起初,这是一个让您的工作流程使用它的过程,但是一旦掌握了它,它就非常简单。您只需拖放想要分组的字段即可。

您可能还想考虑使用Data Connections链接到您的原始数据,根据您的数据集,这也很简单。

+0

甜美,像魅力一样工作,LINQ不是我最强的技巧。需要更频繁地看看它 –

+0

我很高兴能帮上忙。在写入文件之前将数据写入数组或列表也会增加性能方面的好处,因为您不需要访问该文件来编写每个循环。 –

0

我想我找到了解决办法:

File.AppendAllText(text, Header + Environment.NewLine + outputLine + Environment.NewLine); 

使用File.AppendAllText代替File.WriteAllText。使用WriteAllText,您总是删除旧内容。 但是,在开始编写文件之前,请考虑清除文件(File.WriteAllText(text, "");),否则您将在上次运行时也包含旧数据。

尝试使用String.Format("{0,-10}", name)这意味着名称的长度填充了长度为10的空格。减号表示左对齐,正值表示右对齐。

我你的代码更新为:

string text = @"D:\C#\output.txt"; 
File.WriteAllText(text, ""); 
var inputEntries = File.ReadLines(@"D:\c#\debitorders.csv").Select(line => 
{ 
    var values = line.Split(','); 
    return new 
    { 
     accountholder = values[0].Trim().Substring(0, 1) + values[1].Trim(), 
     accountnumber = long.Parse(values[2].Trim()), 
     accounttype = values[3].Trim(), 
     bankname = values[4].Trim(), 
     branch = values[5].Trim(), 
     amount = 100 * double.Parse(values[6].Trim()), 
     date = DateTime.ParseExact(values[7].Trim(), "MM/dd/yyyy", CultureInfo.InvariantCulture) 
    }; 
}); 
var banks = inputEntries.OrderBy(e => e.bankname) 
         .GroupBy(e => e.bankname, e => e); 

foreach (var bank in banks) 
{ 
    var AccountName = bank.Key; 
    var NumberOfAccounts = bank.Count(); 
    var TotalAmount = bank.Select(acc => acc.amount).Sum(); 
    var Header = String.Format("{0,-20} {1,-10} {2}", AccountName, NumberOfAccounts.ToString("000"), TotalAmount.ToString("0000000000")); 

    var sortedAccounts = bank.OrderBy(acc => acc.accountholder) 
          .OrderByDescending(acc => acc.amount); 

    File.AppendAllText(text, Header + Environment.NewLine); 
    Console.WriteLine(Header); 
    foreach (var account in sortedAccounts) 
    { 
     var outputLine = String.Format("{0,-11} {1,15} {2,-3} {3,-10} {4,7} {5,-10}", 
      account.accountholder, 
      account.accountnumber, 
      account.accounttype.Substring(0, 3).ToUpper(), 
      account.branch, 
      account.amount, 
      account.date.ToString("ddMMyyyy") 
     ); 

     //get first 2 characters 
     //account.accounttype.Substring(0, 3).ToUpper() + account.branch + "\t" + "00" + 
     // what are the "00" for? didn't include them you may this do by yourself 
     File.AppendAllText(text, outputLine + Environment.NewLine); 

     Console.WriteLine(outputLine); 
    } 
    File.AppendAllText(text, Environment.NewLine); 
    Console.WriteLine(); 
} 

输出是:

ABSA     004  0000146162 
KCooke   409155874935 SAV Southdowns 97589 01012013 
BJames   409254998 SAV Melville  20774 09122012 
SLane    409771987 SAV Roodepoort 20774 31122012 
ZWhitehead  409122372301 CHE Irene   7025 01122012 

First National Bank 002  0000045603 
GSinclair  408999703657 CHE Fourways  27500 01122012 
THenderson  401255489873 CHE Edenvale  18103 13122012 
+0

看起来像它的写一些记录到控制台,但我仍然只得到2行作为输出到文本文件 –

+0

我已经更新它 –

+0

甜,现在它的写作线,但格式是完全错误的。只有前两行是正确的,而其他所有内容都是重复的 –