将数据从csv排序到txt

时间:2016-02-03 07:15:50

标签: c# csv text-files console-application

我正在编写一个应用程序,它将数据从csv分类到txt。

我已经见过但我无法获得所需的输出。

有人可以帮忙吗,我不知道我出错了。

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

我的文件看起来像这样

  

Georgina,Sinclair,408999703657,check,First National Bank,Fourways,275.00,12 / 01/2012   扎卡里,白石,409122372301,查询,ABSA,艾琳,70.25,12 / 01/2012   Toby,Henderson,401255489873,check,First National Bank,Edenvale,181.03,12 / 13/2012   兆,库克,409155874935,储蓄,ABSA,Southdowns,975.89,01 / 01/2013   布拉德利,詹姆斯,409254998,储蓄,ABSA,梅尔维尔,207.74,12 / 09/2012   柔弄,409771987,储蓄,ABSA,鲁德普特,207.74,12 /二千〇一十二分之三十一

我的输出应该是这样的

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();

            }

        }
    }

2 个答案:

答案 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

答案 1 :(得分: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链接到您的原始数据,考虑到您拥有的数据集,这也非常简单。