I have few CSV file contains different data, I want to combine all this csv file into one ultimate CSV file which contains multiple sheets, under which this multiple csv are accommodated.
Till now my below code picks data from the directory and combines all CSV file into one big CSV file where it is appending the data which i do not want, instead I want multiple sheet in one file..
private void combineallcsv()
{
string txtConsolidated_OS_CSV = "C:\\NWDLS\\new";
if (txtConsolidated_OS_CSV != "")
{
int counter = 0;
string[] files = (Directory.GetFiles(txtConsolidated_OS_CSV.Trim()));
foreach (var file in files)
{
StringBuilder sb = new StringBuilder();
string filename = Path.GetFileNameWithoutExtension(file);
if (file.EndsWith(".csv"))
{
string[] rows = File.ReadAllLines(file);
for (int i = 0; i < rows.Length; i++)
{
if (i == 0)
{
if (counter == 0)
{
sb.Append(rows[i] + "\n");
counter++;
}
}
else
{
sb.Append(rows[i] + "\n");
}
}
}
string csvfile = txtConsolidated_OS_CSV + "\\Merged_OS.csv";
if (File.Exists(csvfile))
{
File.AppendAllText(csvfile, sb.ToString());
sb.Clear();
}
else
{
File.WriteAllText(csvfile, sb.ToString());
sb.Clear();
}
//using (StreamWriter writer = new StreamWriter(csvfile, true))
//{
// writer.Write(sb.ToString());
// writer.Dispose();
// writer.Close();
//}
}
counter = 0;
}
}
There's not such thing as "sheets" in CSV files. CSV files are just lines of text where fields are separated by some defined character. That's all.
You can use VSTO office interop or ADO.NET drivers to create "real" Excel sheets.
Related
I am using the file helpers library to construct a csv but I need to create one csv file per record.
var engine = new FileHelperEngine(typeof(SalesOrders));
int count = 0;
foreach (SalesOrders item in purchaseOrder)
{
count++;
string fileName = "SalesOrder_" + item.OrderNumber.ToString() + ".csv";
var feng = new FileHelperEngine<SalesOrders>();
string str1 = feng.WriteString(purchaseOrder);
List<SalesOrdersItems> _orderItemsForExport = SopOrderItems.Where(a => a.ORDER_NUMBER.ToString() == item.OrderNumber).ToList();
}
However this line
string str1 = feng.WriteString(purchaseOrder);
Is printing out all the contents instead of the item per csv. I think its just my logic is not correct.
foreach (SalesOrders item in purchaseOrder)
{
using (StreamWriter sw = new StreamWriter($"SalesOrder_{item.OrderNumber.ToString()}.csv"))
{
var lines = TakeAllStuffFrom(item); // like a collection of $"{SalesOrder.FirstField.Trim()};{SalesOrder.SecondField.Trim()}";
foreach (var line in lines)
{
sw.WriteLine(line);
}
}
}
Write example of what you expect to appear in your csv file and we will figure something out :)
I'm currently using the below code to compare two csv files with each other. I can select a column in the file and it will compare the rows in that column, it then writes the incorrect and correct rows into another csv file. But now I want to change the color the text 'this row is not the same' so that it's more noticeable. How can I do this?
public void comparing(int selectedRow, string filenaname, string filename2)
{
List<string> lines = new List<string>();
List<string> lines2 = new List<string>();
try
{
StreamReader reader = new StreamReader(System.IO.File.OpenRead(filename));
StreamReader read = new StreamReader(System.IO.File.OpenRead(filename2));
List<string> lijnen = new List<string>();
string line;
string line2;
string differencesFile= #"C:\Users\Mylan\Desktop\differences.csv";
while ((line = reader.ReadLine()) != null && (line2 = read.ReadLine()) != null)
{
string[] split = line.Split(Convert.ToChar(csvSeperator));
string[] split2 = line2.Split(Convert.ToChar(csvSeperator));
if (split[selectedRow] != split2[selectedRow])
{
lijnen.Add("This row is not the same:, " + line);
}
else if(test == test2)
{
System.Windows.Forms.MessageBox.Show("The whole file is the same");
break;
}
else
{
lines.Add("This row is the same:, " + line);
}
}
System.IO.File.WriteAllLines(differencesFile, lines);
System.Diagnostics.Process.Start(differencesFile);
reader.Dispose();
read.Dispose();
}
catch
{
}
}
}
}
I think it's impossible to do what you want with CSV files. Excel reads only the values and separate these in columns, that's all.
If you want to create an Excel file directly by code, you need to use for example the Open XML :
https://msdn.microsoft.com/en-gb/library/office/bb448854.aspx
This is what I use to create, edit Excel files (and Powerpoint files too). It's a bit tricky at beginning but it's a solution...
I have a flat file with comma separated values which need to be transfer to a datatable and the values on the first line is header name, will be used as columns name of the datatable. But Before that, I need to check if all required header (Some Mandatory headers) are available in the flat file. Please help me to develop a C# code to put the header validation.
`.
.
.
/getting full file path of Uploaded file and read all text
System.IO.StreamReader file = new System.IO.StreamReader(#path);
string line;
while ((line = file.ReadLine()) != null)
{
string[] linetemp = line.Split(new char[] { ',' });
if(tblcsv.Rows.Count==0)
{
foreach (string ColName in linetemp)
{
tblcsv.Columns.Add(ColName); //Creating columns with available headers names
}
}
tblcsv.Rows.Add();
.
.
.
`//remaining code
For example
If the flat file will contain
datetime,status,Assignee,Reporter,Duration,Col1,Col2,Remarks
1504451523568,Inprogress,ABC,BCD,120,True,B,comments...
1504451523567,Completed,DFG,BCD,120,True,B,comments...
1504451523566,unassigned,VNB,BCD,160,,B,comments...
1504451523565,Inprogress,ERT,FGH,150,True,,comments...
and I need to check that only First line have all mandaory header(like- datetime,Status,Assignee and Duration).
I tired to implement your particular requirement with a sample Csv file from online. Csv file can be found here, I may not have a sophisticated code, but tried to take a simplest way to solve this particular problem.
Below is the short version of code which is of your importance.
String firstLine;
var fileStream = new FileStream( # "C:\Users\user\Desktop\AssetsImportCompleteSample.csv", FileMode.Open,
FileAccess.Read);
using(var streamReader = new StreamReader(fileStream, Encoding.UTF8)) {
firstLine = streamReader.ReadLine();
}
var values = firstLine.Split(',');
for (int i = 0; i < values.Length; i++) {
values[i] = values[i].Trim();
}
if (values.Length == 4)
{
int count=0;
IList<string> newList = new List<string> { "MXASSETInterface", "SRM_SaaS_ES", "EN", "AddChange" };
for (int i = 0; i < values.Length; i++)
{
if (newList.Contains(values[i]))
{
count++;
newList.Remove(values[i]);
}
}
if (count == 4)
{
Console.WriteLine("head is correct");
}
else
{
Console.WriteLine("head is incorrect");
}
}
The complete console application can be found with below code, which can be run direct
class Program
{
static void Main(string[] args)
{
try
{
String firstLine;
var fileStream = new FileStream(#"C:\Users\user\Desktop\AssetsImportCompleteSample.csv", FileMode.Open,
FileAccess.Read);
using (var streamReader = new StreamReader(fileStream, Encoding.UTF8))
{
firstLine = streamReader.ReadLine();
}
if (firstLine != null)
{
var values = firstLine.Split(',');
Console.WriteLine(firstLine);
for (int i = 0; i < values.Length; i++)
{
values[i] = values[i].Trim();
Console.WriteLine(values[i]);
}
if (values.Length == 4)
{
int count=0;
IList<string> newList = new List<string> { "MXASSETInterface", "SRM_SaaS_ES", "EN", "AddChange" };
for (int i = 0; i < values.Length; i++)
{
if (newList.Contains(values[i]))
{
count++;
newList.Remove(values[i]);
}
}
if (count == 4)
{
Console.WriteLine("head is correct");
}
else
{
Console.WriteLine("head is incorrect");
}
}
else
{
Console.WriteLine("header is Invalid");
}
}
else
{
Console.WriteLine("header is Invalid");
}
Console.ReadLine();
}
catch (Exception e)
{
Console.WriteLine("Please check if file is available or path is correct", e.Message);
}
Console.ReadLine();
}
}
I suggest using CsvHelpet library for parsing the CSV file. It allows to define a class that represents a row in your file. Header names are property names by default or they can be mapped usimg fluent API.
var csv = new CsvReader( textReader ); var records = csv.GetRecords();
Get records will fail if some headers are missing.
I need to check certain columns of data to make sure there are no trailing blank spaces. At first thought I thought it would be very easy, but after attempting to achieve the goal I have got stuck.
I know that there should be 6-digits in the column I need to check. If there is less I will reject, if there are more I will trim the blank spaces. After doing that for the entire file, I want to write it back to the file with the same delimiters.
This is my attempt:
Everything seems to be working correctly except for writing the file.
if (File.Exists(filename))
{
using (StreamReader sr = new StreamReader(filename))
{
string lines = sr.ReadLine();
string[] delimit = lines.Split('|');
while (delimit[count] != "COLUMN_DATA_TO_CHANGE")
{
count++;
}
string[] allLines = File.ReadAllLines(#filename);
foreach(string nextLine in allLines.Skip(1)){
string[] tempLine = nextLine.Split('|');
if (tempLine[count].Length == 6)
{
checkColumn(tempLine);
writeFile(tempLine);
}
else if (tempLine[count].Length > 6)
{
tempLine[count] = tempLine[count].Trim();
checkColumn(tempLine);
}
else
{
throw new Exception("Not enough numbers");
}
}
}
}
}
public static void checkColumn(string[] str)
{
for (int i = 0; i < str[count].Length; i++)
{
char[] c = str[count].ToCharArray();
if (!Char.IsDigit(c[i]))
{
throw new Exception("A non-digit is contained in data");
}
}
}
public static void writeFile(string[] str)
{
string temp;
using (StreamWriter sw = new StreamWriter(filename+ "_tmp", false))
{
StringBuilder builder = new StringBuilder();
bool firstColumn = true;
foreach (string value in str)
{
if (!firstColumn)
{
builder.Append('|');
}
if (value.IndexOfAny(new char[] { '"', ',' }) != -1)
{
builder.AppendFormat("\"{0}\"", value.Replace("\"", "\"\""));
}
else
{
builder.Append(value);
}
firstColumn = false;
}
temp = builder.ToString();
sw.WriteLine(temp);
}
}
If there is a better way to go about this, I would love to hear it. Thank you for looking at the question.
edit:
file structure-
country| firstname| lastname| uniqueID (column I am checking)| address| etc
USA|John|Doe|123456 |5 main street|
notice the blank space after the 6
var oldLines = File.ReadAllLines(filePath):
var newLines = oldLines.Select(FixLine).ToArray();
File.WriteAllLines(filePath, newLines);
string FixLine(string oldLine)
{
string fixedLine = ....
return fixedLine;
}
The main problem with writing the file is that you're opening the output file for each output line, and you're opening it with append=false, which causes the file to be overwritten every time. A better approach would be to open the output file one time (probably right after validating the input file header).
Another problem is that you're opening the input file a second time with .ReadAllLines(). It would be better to read the existing file one line at a time in a loop.
Consider this modification:
using (StreamWriter sw = new StreamWriter(filename+ "_tmp", false))
{
string nextLine;
while ((nextLine = sr.ReadLine()) != null)
{
string[] tempLine = nextLine.Split('|');
...
writeFile(sw, tempLine);
I have a html table which I am trying to write to a csv file. I have the rows seperated by a \n in my array and when I print it to the csv file everything works except one problem I'm having. I want each comma value to be printed in the next column. Unfortunately it is not doing that. My current code writes all the values from each row in the html table to the correct rows in the csv.
try
{
string filepath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
StreamWriter sw = new StreamWriter(Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\spreadsheet.csv", true);
foreach (var i in valueArray)
{
if (i.ToString() == "\n")
{
sw.Write("\n");
}
else
{
{
sw.Write(i.ToString());
sw.Write("\t");//my failed attempt
}
}
}
sw.Flush();
sw.Close();
saveOK = true;
}
values in the array would look like : "first,second,third,fourth,fith,last,\n, first, ....,last,\n,"
in the csv it shows up as :
column 1 column 2
row1 :firstsecondthirdfourthfithlast
row2 :firstsecond....... last
foreach (var i in valueArray)
{
if (i.ToString() == "\n")
{
sw.Write(sw.NewLine);
}
else
{
sw.Write(i.ToString() + ",");
}
}