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();
}
}
}
Related
I am working with a requirement for displaying a 2 dimensional array in a WPF window. The size of array can be up to 360*720. I have tried to use DataTable bound to a DataDrid, but it took so much time to load the grid and very RAM consuming. My example code is below.
public void SetData(double[][] array)
{
if(array.Length <= 0)
return;
DataTable table = new DataTable();
for (int i = 0; i < array[0].Length; i++)
{
table.Columns.Add(i.ToString(), typeof(double));
}
for (int i = 0; i < array.Length; i++)
{
DataRow row = table.NewRow();
for (int j = 0; j < array[i].Length; j++)
{
row[j] = array[i][j].ToString();
}
table.Rows.Add(row);
}
dataGrid.DataContext = table;
}
I created an array of double of which the dimension is 360 * 720 and called the SetData() method above. As a result, the RAM occupied by the program increased several GBs and very time consuming.
I wonder if there is a graceful way to solve this problem or there are some shortcomings in my code. Thank you.
Thanks for all these useful answers and comments which helped me a lot. After doing some search, I seemed to find out the reason why my code costs so much time to render the DataGrid. I wrapped up the grid with a ScrollViewer before. I removed it and it went very well. Here is the link where I found the tip.WPF DataGrid is very slow to render.
Thank you all.
Create a separate class that can return the enumerator as data.
class ArrayVisitor : IEnumerable<double[]>
{
private double[,] _data;
public ArrayVisitor()
{
}
public ArrayVisitor(double[,] data)
{
_data = data;
}
public double[,] Data
{
get { return _data; }
set { _data = value; }
}
#region IEnumerable<double[]> Members
public IEnumerator<double[]> GetEnumerator()
{
if (_data == null)
throw new ArgumentException("Data cannot be null.", "Data");
int len2d = _data.GetLength(1);
for (int i = 0; i < _data.GetLength(0); i++)
{
double[] arr = new double[len2d];
for (int j = 0; j < len2d; j++)
{
arr[j] = _data[i, j];
}
yield return arr;
}
}
#endregion
#region IEnumerable Members
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
#endregion
}
You can use Listview and Gridview as Databound controls.
private void Bindng2DArrayToListview2
(ListView listview, double[,] data, string[] columnNames)
{
Check2DArrayMatchColumnNames(data, columnNames);
GridView gv = new GridView();
for (int i = 0; i < data.GetLength(1); i++)
{
GridViewColumn col = new GridViewColumn();
col.Header = columnNames[i];
col.DisplayMemberBinding = new Binding("[" + i + "]");
gv.Columns.Add(col);
}
ArrayVisitor arrayVisitor = new ArrayVisitor(data);
listview.View = gv;
listview.ItemsSource = arrayVisitor;
}
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();
}
EDIT: Sorry guys, I was a little blind with this thing, I posted the "solution" below under the "problem".
ORIGINAL:
I can't seem to get behind this problem (even after searching a lot on SO):
I have a DataTable object that I want to "prepare" for data population like so:
My model class property (classname "DataMdl"):
private static DataTable _datatbl;
public DataTable datatbl
{
get { return _datatbl; }
set
{
_datatbl = value;
OnPropertyChanged(new PropertyChangedEventArgs("datatbl"));
}
}
Call of prepdatatable in a ViewModel-Method:
prepdatatable(DataMdl.datatbl, 5, 9)
My prepdatatable method:
private void prepdatatable(DataTable dt, int rowcount, int colcount)
{
dt = new DataTable();
int i = 0;
for (i = 0; i < colcount; i++)
{
dt.Columns.Add("col" + i);
}
for (i = 0; i < rowcount; i++)
{
dt.Rows.Add("row" + i);
}
}
After calling the above method I try to populate the DataTable in the method which called prepdatatable with
DataMdl.datatbl.Rows[0][0] = "..."
DataMdl.datatbl.Rows[0][1] = "..."
...
DataMdl.datatbl.Rows[1][0] = "..."
...
and so on
In this case I get a NullReferenceException on DataMdl.datatbl.
When I try to initialize DataMdl.datatbl outside of prepdatatable, I get a NullReferenceException inside on "dt" inside prepdatatable.
"SOLUTION":
Just make prepdatatable return a DataTable instead of void and then assign its value to the property DataMdl.datatbl:
private DataTable prepdatatable(int rowcount, int colcount)
{
var dt = new DataTable();
int i = 0;
for (i = 0; i < colcount; i++)
{
dt.Columns.Add("col" + i);
}
for (i = 0; i < rowcount; i++)
{
dt.Rows.Add("row" + i);
}
return dt;
}
and
DataMdl.datatbl = prepdatatable(5, 9);
Thanks for your concern.
What are you trying to do here?
for (i = 0; i < rowcount; i++)
{
var r = dt.NewRow();
dt.Rows.Add(r);
}
I have a feeling that this is the source of the exception. Take a look at this: How to add a new row to c# DataTable in 1 line of code? . It seems like you are trying to add a row that doesn't have a value. A new row is, by default, null, but initialized. Then, you try to add it to the datatable. Why don't you add rows like you are adding columns?
suppose that this is the initialization of your datatable and here you are calling the method
datatbl = new DataTable();
prepdatatable(datatbl, 5, 9);
this method will not take the datatable , it will take a copy from it , you are sending the datatable by value not by reference
private void prepdatatable(DataTable dt, int rowcount, int colcount)
{
int i = 0;
for (i = 0; i < colcount; i++)
{
dt.Columns.Add("col" + i);
}
for (i = 0; i < rowcount; i++)
{
var r = dt.NewRow();
dt.Rows.Add(r);
}
}
I will suppose that your method should work fine and the problem is only in the parameter sending way
just change
the method call to
prepdatatable(ref datatbl, 5, 9);
the header to
private void prepdatatable(ref DataTable dt, int rowcount, int colcount)
I apologize for this newbie question, but I'm looking for a simple solution.
I want to write a function that will return a datatable.
Like this:
public static DataTable DataTableCommaReplce(DataTable dt){..}
The function will check each data in DataTable.
If data contained one or more commas, the function will make that data in double quote.
For Example:
you,me⇒"you,me"
What's the best way to write this function?
Can any body help me?
I had solved with this code, but I want more simple solution.
If possible, I want no looping.
public static DataTable DataTableCommaReplce(DataTable dt)
{
int col = dt.Columns.Count;
foreach (DataRow dr in dt.Rows)
{
for (int i = 0; i < col; i++)
{
if (dr[i].ToString().IndexOf(",") > 0)
{
dr[i] = "\"" + dr[i].ToString() + "\"";
}
}
}
return dt;
}
This should work:
public static DataTable DataTableCommaReplce(DataTable dt) {
foreach (DataRow row in dt.Rows) {
foreach (DataColumn col in dt.Columns) {
string s = row[col] as string;
if (s != null) {
if (s.Contains(',')) {
row[col] = string.Format("\"{0}\"", s);
}
}
}
}
return dt;
}
Try the Following Code part. Hope it will help.
DataTable Tb = new DataTable();
for (int i = 0; i < Tb.Columns.Count; i++)
{
for (int j = 0; j < Tb.Rows.Count; j++)
{
if (Tb.Rows[j][i] != DBNull.Value)
{
if (Tb.Rows[j][i].ToString().IndexOf(',') != -1)
{
Tb.Rows[j][i] = "\"" + Tb.Rows[j][i].ToString() + "\"";
}
}
}
}
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;
}
}
}