读取CSV文件并转换为转置表

时间:2018-07-12 13:29:46

标签: c# .net visual-studio csv

我需要读取CSV文件(以“;”分隔),然后应创建一个包含转置(旋转)表的新文件:

我的输入文件:

enter image description here

enter image description here

  • 该工具应能够从用户接收表的文件名并加载表以转置内容。
  • 该工具应能够将转置表保存到具有输入文件名的新文件中,并以“ transposed”(“ filename_transposed.csv”)扩展。

我的代码

public void ReadCsv()
            {
                // open the file "data.csv" which is a CSV file with headers
                using (CsvReader csv = new CsvReader(
                                       new StreamReader("C:\\Users\\moki\\Downloads\\Input.csv"), true))
                {
                    int fieldCount = csv.FieldCount;

                    string[] headers = csv.GetFieldHeaders();
                    while (csv.ReadNextRecord())
                    {
                        for (int i = 0; i < fieldCount; i++)
                            Console.WriteLine(string.Format("{0}\n{1}",
                                          headers[0], csv[i]) );

                    }
                }
Console.ReadLine();

我的结果

enter image description here

3 个答案:

答案 0 :(得分:2)

由于我们正在提供答案...

title.text_frame.paragraphs[0].font.color.rgb = RGBColor(59,89, 152)

输入数据

const dns = require('dns');

function onConnected(callback){
    dns.resolve('www.google.com', function(err) {
        if (!err) callback();
    });
}

输出

using System;
using System.Collections.Generic;
using System.Linq;

namespace _51306985
{
    class Program
    {
        static List<List<string>> listOfList = new List<List<string>>();
        static int longestCol = 0;
        static void Main(string[] args)
        {
            FillTheList("M:\\StackOverflowQuestionsAndAnswers\\51306985\\testdata.csv");
            PadTheList();
            SpitItBackOut();
            SpitItOutToAFile("M:\\StackOverflowQuestionsAndAnswers\\51306985\\testdata.csv");
            Console.ReadLine();
        }

        private static void SpitItOutToAFile(string v)
        {
            string newPath = $"{System.IO.Path.GetDirectoryName(v)}\\{System.IO.Path.GetFileNameWithoutExtension(v)}_Rotated{System.IO.Path.GetExtension(v)}";
            using (System.IO.StreamWriter sw = new System.IO.StreamWriter(newPath))
            {
                for (int i = 0; i < longestCol; i++)
                {
                    string lineToWrite = string.Empty;
                    for (int b = 0; b < listOfList.Count; b++)
                    {
                        lineToWrite += $"{listOfList[b][i]},";
                    }
                    lineToWrite = lineToWrite.Substring(0, lineToWrite.Length - 1);//remove the hanging comma
                    if (lineToWrite != "")
                    {
                        sw.WriteLine(lineToWrite);
                    }

                }
            }
        }

        private static void SpitItBackOut()
        {
            for (int i = 0; i < longestCol; i++)
            {
                string lineToWrite = string.Empty;
                for (int b = 0; b < listOfList.Count; b++)
                {
                    lineToWrite += $"{listOfList[b][i]},";
                }
                lineToWrite = lineToWrite.Substring(0, lineToWrite.Length - 1);//remove the hanging comma
                if (lineToWrite != "")
                {
                    Console.WriteLine(lineToWrite);
                }

            }
        }

        private static void PadTheList()
        {
            foreach (List<string> item in listOfList)
            {
                while (item.Count < longestCol)
                {
                    item.Add("");
                }
            }
        }

        private static void FillTheList(string v)
        {
            using (System.IO.StreamReader sr = new System.IO.StreamReader(v))
            {
                string currentLine = string.Empty;
                while ((currentLine = sr.ReadLine()) != null)
                {
                    listOfList.Add(currentLine.Split(',').ToList());
                    if (listOfList.Last().Count > longestCol)
                    {
                        longestCol = listOfList.Last().Count;
                    }
                }
            }
        }
    }
}

答案 1 :(得分:1)

肯定有一种更有效的方法,但是我认为这是一种易于理解的方法:

1。)将数据放入数据表,例如喜欢:

StreamReader sr1 = new StreamReader("C:\\Users\\moki\\Downloads\\Input.csv");  //create the streamreader to read the input .csv
DataTable mydata = new DataTable();  //create an empty DataTable.....
string[] arr;                        //....and an array in which you will store the elemnets of each line
int i = 0;                           //just a variable to help counting where you are in your data
bool mydatasetup = false;            //a variable to check in the loop if you already added the necessary number of columns to the datatable 

        using (sr1)
        {
            while (sr1.EndOfStream == false)    //read the whole file
            {
                string line = sr1.ReadLine();    //get a line from the file

                if (line != null && line != String.Empty) //check if there is content in the line
                {
                     arr = line.Split(';');    //split the line at each ";" and put the elements in the array

                    if(mydatasetup == false)   //after reading the first line add as many columns to your datatable as you will need..... 
                    {
                        for (int u = 0; u < arr.Length; u++)
                        {
                            mydata.Columns.Add();
                        }
                        mydatasetup = true; //...but only do this once (otherwise you wil have an unneccessary big datatable
                    } 

                     mydata.Rows.Add();   //add a row in you datatable in which you will store the data of the line

                     for (int j = 0; j < arr.Length; j++)    //go throught each element in your array and put it into your datatable
                        {
                            if (arr[j] != "")
                            {
                                mydata.Rows[i][j] = arr[j];
                            }
                        }
                     i = i + 1; //increase the counter so that the program knows it has to fill the data from the next line into the next row of the datatable
                  }
              }
           }

2。)然后,您可以遍历数据表的列,并将每行的内容添加到Stringbuilder(由此转置数据),然后将其另存为.csv:

StringBuilder sb = new StringBuilder();  //create a stringbuilder

      for (int u = 0; u < mydata.Columns.Count; u++)   //loop through the COLUMNS of your datatable....
            {
            for (int i = 0; i < mydata.Rows.Count; i++)  //....but for each column go through each row in the datatable first  
                    {
                        sb.Append(mydata.Rows[i][u].ToString()); // and add the elements to the stringbuilder - here the transposing is actually done

                        if (i < mydata.Rows.Count - 1)   //add a deliminator after each element because you want a .csv as output again 
                        {
                            sb.Append(';');       
                        }     
                    }
            sb.AppendLine(); //add another line to your stringbuilder in which you will store the next column of your datatable
            }

File.WriteAllText("C:\\Users\\moki\\Downloads\\Output.csv", sb.ToString());  //finally create the output .csv  

您当然可以将这两个步骤结合在一起。

答案 2 :(得分:1)

以防万一,如果有人想用几行代码使用Cinchoo ETL来做到这一点,

string csv = @"A1;B1;C1;D1;E1
A2;B2;C2;D2;E2
A3;B3;C3;D3;E3
A4;B4;C4;D4;E4
A5;B5;C5;D5;E5
";

StringBuilder sb = new StringBuilder();
using (var p = ChoCSVReader.LoadText(csv)
    .WithDelimiter(";")
    .ThrowAndStopOnMissingField(false)
    )
{
    using (var w = new ChoCSVWriter(sb)
        .WithDelimiter(";")
        )
    {
        w.Write(p.Cast<ChoDynamicObject>().Transpose(false));
    }
}

Console.WriteLine(sb.ToString());

输出:

A1;A2;A3;A4;A5
B1;B2;B3;B4;B5
C1;C2;C3;C4;C5
D1;D2;D3;D4;D5
E1;E2;E3;E4;E5