我需要读取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();
我的结果
答案 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