Delete columns from CSV then save in different folder path - c#

I need a script that opens a CSV from a specific file path, deletes specific columns and then exports the CSV to a specified folder.
Due to other scripts that will be integrated with this at a later stage, I have decided to do this using C#.
I have previously used Perl and achieved the desired result, but it isn't suitable for my application.
I found this link where I found this code;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace CSV
{
class CSV
{
private Dictionary<Tuple<int, int>, string> _data;
private int _rows;
private int _cols;
public int Rows { get { return _rows; } }
public int Cols { get { return _cols; } }
public CSV()
{
Clear();
}
public void Clear()
{
_rows = 0;
_cols = 0;
_data = new Dictionary<Tuple<int, int>, string>();
}
public void Open(StreamReader stream, char delim = ',')
{
string line;
int col = 0;
int row = 0;
Clear();
while ((line = stream.ReadLine()) != null)
{
if (line.Length > 0)
{
string[] values = line.Split(delim);
col = 0;
foreach (var value in values)
{
this[col, row] = value;
col++;
}
row++;
}
}
stream.Close();
}
public void Save(StreamWriter stream, char delim = ',')
{
for (int row = 0; row < _rows; row++)
{
for (int col = 0; col < _cols; col++)
{
stream.Write(this[col, row]);
if (col < _cols - 1)
{
stream.Write(delim);
}
}
stream.WriteLine();
}
stream.Flush();
stream.Close();
}
public string this[int col, int row]
{
get
{
try
{
return _data[new Tuple<int, int>(col, row)];
}
catch
{
return "";
}
}
set
{
_data[new Tuple<int, int>(col, row)] = value.ToString().Trim();
_rows = Math.Max(_rows, row + 1);
_cols = Math.Max(_cols, col + 1);
}
}
static void Main(string[] args)
{
CSV csv = new CSV();
csv.Open(new StreamReader(#"C:\mid\Dev\CSV_Splitter\VR_Path\New\Import_User_Sample_en.csv"));
csv[0, 0] = "Column0";
csv[1, 1] = "100";
csv[2, 2] = "200";
csv[3, 3] = "300";
csv[4, 4] = "400";
csv.Save(new StreamWriter(#"C:\mid\Dev\CSV_Splitter\VR_Path\Proccessed\test_out.csv"));
}
}
}
This uses C# to open a CSV file, manipulate it and save it in a new path.
I want to delete columns 0, 1, 2 and 3 from the csv file instead of manipulating the data.
Can anyone help?

You can use code you posted, just change Save method, initialize col variable with 4 and you should be done.
public void Save(StreamWriter stream, char delim = ',')
{
if(_cols > 4)
{
for (int row = 0; row < _rows; row++)
{
for (int col = 4; col < _cols; col++)
{
stream.Write(this[col, row]);
if (col < _cols - 1)
{
stream.Write(delim);
}
}
stream.WriteLine();
}
}
stream.Flush();
stream.Close();
}
Update:
To exclude 10th column, skip writing data in the 10th position.
public void Save(StreamWriter stream, char delim = ',')
{
if(_cols > 4)
{
for (int row = 0; row < _rows; row++)
{
for (int col = 4; col < _cols; col++)
{
if(col != 10)
{
stream.Write(this[col, row]);
if (col < _cols - 1)
{
stream.Write(delim);
}
}
}
stream.WriteLine();
}
}
stream.Flush();
stream.Close();
}

Related

C# EPPlus not evaluating formula SUM(A3:B3)

I have just started working with EPPlus. i have data table which has some numeric data and formula. when i load data table by EPPlus and save to excel then formula not evaluated i found when i open the same excel file. formula lies in excel cell as string like SUM(A3:B3)
To evaluate formulate i have tried many options of EPPLUS and those are listed here
pack.Workbook.Worksheets["Test"].Calculate();
pack.Workbook.Worksheets["Test"].Cells["A3"].Calculate();
pack.Workbook.Worksheets["Test"].Cells["B3"].Calculate();
ws.Calculate();
Here i am referring my full sample code where formula not working. please have a look and tell me what i need to add in my code to evaluate formula.
private void button1_Click(object sender, EventArgs e)
{
DataTable dt = GetDataTable();
string path = #"d:\EPPLUS_DT_Excel.xlsx";
Stream stream = File.Create(path);
using (ExcelPackage pack = new ExcelPackage())
{
ExcelWorksheet ws = pack.Workbook.Worksheets.Add("Test");
ws.Cells["A1"].LoadFromDataTable(dt, false);
//pack.Workbook.Worksheets["Test"].Calculate();
//pack.Workbook.Worksheets["Test"].Cells["A3"].Calculate();
//pack.Workbook.Worksheets["Test"].Cells["B3"].Calculate();
ws.Calculate();
pack.SaveAs(stream);
stream.Close();
MessageBox.Show("Done");
}
}
public DataTable GetDataTable()
{
string strSum = "", strColName, strImmediateOneUp = "", strImmediateTwoUp = "";
int startsum = 0;
int currow = 0;
bool firstTimeSum = true;
int NumRows = 3;
int NumColumns = 2;
DataTable dt = new DataTable();
for (int col = 0; col < NumColumns; col++)
{
strColName = GenerateColumnText(col);
DataColumn datacol = new DataColumn(strColName, typeof(object));
dt.Columns.Add(datacol);
}
for (int row = 0; row < NumRows; row++)
{
dt.Rows.Add();
for (int col = 0; col < NumColumns; col++)
{
if (row < 2)
{
dt.Rows[row][col] = Convert.ToInt32(new Random().Next(1, NumRows));
}
else
{
if (firstTimeSum)
{
if (row - currow == 2)
{
currow = row;
startsum = 0;
firstTimeSum = false;
}
else
{
startsum = 1;
}
}
else
{
if (row - currow == 3)
{
currow = row;
startsum = 0;
}
}
if (startsum == 0)
{
strColName = GenerateColumnText(col);
strImmediateOneUp = strColName + ((row + 1) - 1).ToString();
strImmediateTwoUp = strColName + ((row + 1) - 2).ToString();
strSum = string.Format("+SUM({0}:{1})", strImmediateTwoUp, strImmediateOneUp);
dt.Rows[row][col] = strSum;
}
else
{
dt.Rows[row][col] = Convert.ToInt32(new Random().Next(1, NumRows));
}
}
}
startsum = 1;
}
return dt;
}
private string GenerateColumnText(int num)
{
string str = "";
char achar;
int mod;
while (true)
{
mod = (num % 26) + 65;
num = (int)(num / 26);
achar = (char)mod;
str = achar + str;
if (num > 0) num--;
else if (num == 0) break;
}
return str;
}
When adding a formula to a cell you use the Formula property. When you load a range from a DataTable using LoadFromDataTable it has no way of knowing that some of the values are meant to be interpreted as formulas.
You can use LoadDataTable to populate the cells on which the formulas will operate, but for the formulas you'll need to set the Formula property.

Read array 2D and output as table C#

I am new at programming in C# and I'm trying to display to whole content of a matrix in the format of a table, however what I got so far is to read the enum and read one line from the matrix. Instead I need to read multiple lines from the matrix and output as a table.
when I run the program I get to insert data twice in row and the output should've been this data inside a table, but only one line is being shown.
Here's the code:
static int getInsertIndex(string[,] matrix)
{
for (int j = 0; j < matrix.GetLength(0); j++)
{
if (string.IsNullOrEmpty(matrix[j, 0])) return j;
}
return -1;
}
private static void InsertData<T>(string[,] matrix)
{
// int newId = generateId(ref id);
int n = getInsertIndex(matrix), id = 1;
matrix[n, 0] = Convert.ToString(id++);
int x = matrix.GetLength(1) - 1;
matrix[n, x] = "true";
for (var j = 1; j < matrix.GetLength(1); j++)
{
do
{
Console.Write($"\nInsert {GetHeader<T>(j)}: ");
matrix[0, j] = Console.ReadLine();
} while (string.IsNullOrEmpty(matrix[0, j]));
}
}
private static void ListData<T>(string[,] matrix)
{
var array = new string[matrix.GetUpperBound(1)];
for (var l = 0; l < matrix.GetLength(0); l++)
{
for (var i = 0; i < array.Length; i++)
{
array[i] = matrix[0, i];
}
}
PrintRow(array);
PrintLine();
}
private static string GetHeader<T>(int i) => Enum.GetName(typeof(T), i);
private static void ShowHeader<T>(string[,] matrix)
{
var array = new string[matrix.GetUpperBound(1)];
for (var i = 0; i < array.Length; i++)
{
array[i] = GetHeader<T>(i);
}
PrintLine();
PrintRow(array);
PrintLine();
}
private static void PrintLine()
{
Console.WriteLine(new string('-', Console.WindowWidth - 1));
}
private static void PrintRow(IReadOnlyCollection<string> columns)
{
var width = (Console.WindowWidth - 1 - columns.Count) / columns.Count;
var row = columns.Aggregate("|", (current, column) => current + AlignCentre(column, width) + "|");
Console.WriteLine(row);
}
static string AlignCentre(string text, int width)
{
text = text.Length > width ? text.Substring(0, width - 3) + "..." : text;
return string.IsNullOrEmpty(text)
? new string(' ', width)
: text.PadRight(width - (width - text.Length) / 2).PadLeft(width);
}
enum ClientHeader { Id, Name, Surname, Addres, CodPostal, Telephone, Email, State };
private static void Main()
{
var client = new string[4, 7];
InsertData<ClientHeader>(client);
Console.Clear();
InsertData<ClientHeader>(client);
ShowHeader<ClientHeader>(client);
ListData<ClientHeader>(client);
}
}
}
There are 2 issues:
1) In the InsertData() function, you want to update the n th row.
Replace
matrix[0, j] = Console.ReadLine();
by
matrix[n, j] = Console.ReadLine();
2) In the ListData() function you want to show each row, so you need to move the array variable into the first for loop. Replace array[i] = matrix[0, i] with array[i] = matrix[l, i] because you are displaying the l th row.
private static void ListData<T>(string[,] matrix)
{
for (var l = 0; l < matrix.GetLength(0); l++)
{
var array = new string[matrix.GetUpperBound(1)];
for (var i = 0; i < array.Length; i++)
{
array[i] = matrix[l, i];
}
PrintRow(array);
}
PrintLine();
}
Try following :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
namespace ConsoleApplication1
{
public class Program
{
private static void Main()
{
List<List<string>> data = new List<List<string>>() {
new List<string>() { "Name", "Age", "Weight"},
new List<string>() { "John", "33", "180"},
new List<string>() { "Mary", "32", "125"},
new List<string>() { "Harry", "40", "200"}
};
DataTable dt = new DataTable();
for (int i = 0; i < data.Count; i++)
{
if (i == 0)
{
foreach (string col in data[i])
{
dt.Columns.Add(col);
}
}
else
{
dt.Rows.Add(data[i].ToArray());
}
}
}
}
}

Display values from array 2D inside table C#

I am new at programming in C# and I'm trying to create a method that allows me to create a table and visualize the data inside of a matrix. However none of the methods I have tried seems to work as supposed.
Basically the method works to visualize the header which is the Enum, however I need to read the data from the matrix and the output has to be in the form of a table. HereĀ“s the code so far:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp3
{
enum clientHeader { Id, Name, Surname, Addres, Cod_Postal, Telephone, Email, State };
class Program
{
static void Main(string[] args)
{
string[,] client = new string[3, 7];
insertData<clientHeader>(client);
Console.Clear();
showHeader<clientHeader>(client);
listData<clientHeader>(client);
Console.ReadKey();
}
static void insertData<T>(string[,] matrix)
{
int x = matrix.GetLowerBound(1);
matrix[0, x] = "1";
for (int j = 1; j < matrix.GetLength(1); j++)
{
do
{
Console.Write($"\nInsert {GetHeader<T>(j)}: ");
matrix[0, j] = Console.ReadLine();
} while (String.IsNullOrEmpty(matrix[0, j]));
}
}
static void listData<T>(string[,] matrix)
{
for (int i = 0; i < matrix.GetLength(0); i++)
{
for (int j = 0; j < matrix.GetLength(1); j++)
{
Console.Write($"{matrix[i, j]}\t");
}
}
Console.WriteLine();
}
}
private static string GetHeader<T>(int i) => Enum.GetName(typeof(T), i);
static void showHeader<T>(string[,] matrix)
{
int x = matrix.GetUpperBound(1);
string[] array = new string[x];
for (int i = 0; i < array.Length; i++)
{
array[i] = GetHeader<T>(i);
}
PrintLine();
PrintRow(array);
PrintLine();
}
static int tableWidth = 120;
static void PrintLine()
{
Console.WriteLine(new string('-', tableWidth));
}
static void PrintRow(params string[] columns)
{
int width = (tableWidth - columns.Length) / columns.Length;
string row = "|";
foreach (string column in columns)
{
row += AlignCentre(column, width) + "|";
}
Console.WriteLine(row);
}
static string AlignCentre(string text, int width)
{
text = text.Length > width ? text.Substring(0, width - 3) + "..." : text;
if (string.IsNullOrEmpty(text))
{
return new string(' ', width);
}
else
{
return text.PadRight(width - (width - text.Length) / 2).PadLeft(width);
}
}
}
}
In the code below, the main modification I made was to have your ListData method act like your ShowHeader method, so that the data is aligned in columns underneath the header:
private static void ListData<T>(string[,] matrix)
{
var array = new string[matrix.GetUpperBound(1)];
for (var i = 0; i < array.Length; i++)
{
array[i] = matrix[0, i];
}
PrintRow(array);
PrintLine();
}
See if that works for you. Here's the full code with some other refactoring:
private static void InsertData<T>(string[,] matrix)
{
// Just add dummy data while testing
matrix[0, 0] = "1";
matrix[0, 1] = "FirstName";
matrix[0, 2] = "LastName";
matrix[0, 3] = "123 Main St";
matrix[0, 4] = "98765";
matrix[0, 5] = "(123) 456-7890";
matrix[0, 6] = "user#provider.com";
return;
matrix[0, matrix.GetLowerBound(1)] = "1";
for (var j = 1; j < matrix.GetLength(1); j++)
{
do
{
Console.Write($"\nInsert {GetHeader<T>(j)}: ");
matrix[0, j] = Console.ReadLine();
} while (string.IsNullOrEmpty(matrix[0, j]));
}
}
private static void ListData<T>(string[,] matrix)
{
var array = new string[matrix.GetUpperBound(1)];
for (var i = 0; i < array.Length; i++)
{
array[i] = matrix[0, i];
}
PrintRow(array);
PrintLine();
}
private static string GetHeader<T>(int i) => Enum.GetName(typeof(T), i);
private static void ShowHeader<T>(string[,] matrix)
{
var array = new string[matrix.GetUpperBound(1)];
for (var i = 0; i < array.Length; i++)
{
array[i] = GetHeader<T>(i);
}
PrintLine();
PrintRow(array);
PrintLine();
}
private static void PrintLine()
{
Console.WriteLine(new string('-', Console.WindowWidth - 1));
}
private static void PrintRow(IReadOnlyCollection<string> columns)
{
var width = (Console.WindowWidth - 1 - columns.Count) / columns.Count;
var row = columns.Aggregate("|", (current, column) => current + AlignCentre(column, width) + "|");
Console.WriteLine(row);
}
static string AlignCentre(string text, int width)
{
text = text.Length > width ? text.Substring(0, width - 3) + "..." : text;
return string.IsNullOrEmpty(text)
? new string(' ', width)
: text.PadRight(width - (width - text.Length) / 2).PadLeft(width);
}
enum ClientHeader { Id, Name, Surname, Addres, CodPostal, Telephone, Email, State };
private static void Main()
{
var client = new string[3, 7];
InsertData<ClientHeader>(client);
Console.Clear();
ShowHeader<ClientHeader>(client);
ListData<ClientHeader>(client);
GetKeyFromUser("\nDone! Press any key to exit...");
}
private static ConsoleKeyInfo GetKeyFromUser(string prompt)
{
Console.Write(prompt);
var key = Console.ReadKey();
Console.WriteLine();
return key;
}
Output
I tried doing like this, don't know if it's what you meant, however the program crashes. Still doesn't read second line, I think the variable text from the method AlignCenter is null for some reason.
private static void ListData<T>(string[,] matrix)
{
var array = new string[matrix.GetUpperBound(1)];
for (int j = 0; j < array.GetUpperBound(0); j++)
{
for (var i = 0; i < array.Length; i++)
{
array[i] = matrix[j, i];
}
PrintRow(array);
PrintLine();
}
}

How to Export DataSet to notepad?

how to Export DataSet(multiple of Datatables) to a notepad. From c#
Note: NOT A SINGLE DataTable ,Multiple DataTables From DataSet;
I would suggest something simple, create a translator or download a bunch of other libraries available on the web.
you would most like go
public interfacte IExport
{
bool Export(Databale sometable);// this can also reference interface
//concrete implementation could also handle saving of file
}
then call on a concrete class to implement that value, use a Factory Patter, Dependency Injection, etc to supply the concrete type. Then you can keep adding as many converters to support as many file types as you'd like.
private void Write(System.Data.DataSet dts, string outputFilePath)
{
System.Data.DataTable dt = new System.Data.DataTable();
for (int z = 0; z < dts.Tables.Count; z++)
{
dt = dts.Tables[z];
int[] maxLengths = new int[dt.Columns.Count];
for (int i = 0; i < dt.Columns.Count; i++)
{
maxLengths[i] = dt.Columns[i].ColumnName.Length;
foreach (DataRow row in dt.Rows)
{
if (!row.IsNull(i))
{
int length = row[i].ToString().Length;
if (length > maxLengths[i])
{
maxLengths[i] = length;
}
}
}
}
using (StreamWriter sw = new StreamWriter(outputFilePath, true))
{
for (int i = 0; i < dt.Columns.Count; i++)
{
sw.Write(dt.Columns[i].ColumnName.PadRight(maxLengths[i] + 2));
}
sw.WriteLine();
foreach (DataRow row in dt.Rows)
{
for (int i = 0; i < dt.Columns.Count; i++)
{
if (!row.IsNull(i))
{
sw.Write(row[i].ToString().PadRight(maxLengths[i] + 2));
}
else
{
sw.Write(new string(' ', maxLengths[i] + 2));
}
}
sw.WriteLine();
}
sw.Close();
}
}
}

Reading data from DataGridView in C#

How can I read data from DataGridView in C#? I want to read the data appear in Table. How do I navigate through lines?
something like
for (int rows = 0; rows < dataGrid.Rows.Count; rows++)
{
for (int col= 0; col < dataGrid.Rows[rows].Cells.Count; col++)
{
string value = dataGrid.Rows[rows].Cells[col].Value.ToString();
}
}
example without using index
foreach (DataGridViewRow row in dataGrid.Rows)
{
foreach (DataGridViewCell cell in row.Cells)
{
string value = cell.Value.ToString();
}
}
If you wish, you can also use the column names instead of column numbers.
For example, if you want to read data from DataGridView on the 4. row and the "Name" column.
It provides me a better understanding for which variable I am dealing with.
dataGridView.Rows[4].Cells["Name"].Value.ToString();
Hope it helps.
string[,] myGridData = new string[dataGridView1.Rows.Count,3];
int i = 0;
foreach(DataRow row in dataGridView1.Rows)
{
myGridData[i][0] = row.Cells[0].Value.ToString();
myGridData[i][1] = row.Cells[1].Value.ToString();
myGridData[i][2] = row.Cells[2].Value.ToString();
i++;
}
Hope this helps....
Code Example : Reading data from DataGridView and storing it in an array
int[,] n = new int[3, 19];
for (int i = 0; i < (StartDataView.Rows.Count - 1); i++)
{
for (int j = 0; j < StartDataView.Columns.Count; j++)
{
if(this.StartDataView.Rows[i].Cells[j].Value.ToString() != string.Empty)
{
try
{
n[i, j] = int.Parse(this.StartDataView.Rows[i].Cells[j].Value.ToString());
}
catch (Exception Ee)
{ //get exception of "null"
MessageBox.Show(Ee.ToString());
}
}
}
}
private void HighLightGridRows()
{
Debugger.Launch();
for (int i = 0; i < dtgvAppSettings.Rows.Count; i++)
{
String key = dtgvAppSettings.Rows[i].Cells["Key"].Value.ToString();
if (key.ToLower().Contains("applicationpath") == true)
{
dtgvAppSettings.Rows[i].DefaultCellStyle.BackColor = Color.Yellow;
}
}
}

Categories

Resources