portal
portal

Reputation: 31

Export DataGrid to text file

I'm new to programming (1st year of learning at college) and I'm working on a small application.

I have a window where user can retrieve data from SQL to DataGrid and a Button for exporting some data from a DataGrid data to a text file.

This is the code I've used to get data from SQL:

SqlConnection con = new SqlConnection("Server = localhost;Database = autoser; Integrated Security = true");
SqlCommand cmd = new SqlCommand("selectproduct", con); // Using a Store Procedure.
cmd.CommandType = CommandType.StoredProcedure;
DataTable dt = new DataTable("dtList");
cmd.Parameters.AddWithValue("@Code", txtbarcode.Text);

SqlDataAdapter da = new SqlDataAdapter(cmd);
da.Fill(dt);
data.ItemsSource = dt.DefaultView;
SqlDataAdapter adapt = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
adapt.Fill(ds);
con.Close();
int count = ds.Tables[0].Rows.Count;
if (count == 0)
{
    MessageBox.Show("This product doesn't excist");
    SystemSounds.Hand.Play();
}
else if (count == 1)
{
    lblinfo.Visibility = Visibility.Visible;
    SystemSounds.Asterisk.Play();

}

And this one is the code I used to write text file:

{
    using (StreamWriter writer = new StreamWriter("D:\\test.txt", true))
    {
        writer.WriteLine("Welcome");
        writer.WriteLine("E N T E R N E T");
    }

    using (StreamWriter writer = new StreamWriter("D:\\test.txt", true))
    {
        writer.WriteLine(data.Items);
    }


    using (StreamWriter writer = new StreamWriter("D:\\test.txt", true))
    {
        writer.WriteLine(data.Items);
    }
    // Append line to the file.
    using (StreamWriter writer = new StreamWriter("D:\\test.txt", true))
    {
        writer.WriteLine("---------------------------------------");
        writer.WriteLine("             Thank You!   ");
        writer.WriteLine("        " + DateTime.Now + "              ");
    }
}

When I Open the text file i get this data

Welcome
E N T E R N E T
System.Windows.Controls.ItemCollection -   Why isn't show the data grid 
data

---------------------------------------
    Thank You   
    7/26/2018 12:38:37 PM   

My question is: Where is my mistake that cause the data from the DataGrid to don't be showed in correct way?
Thanks in advance

Upvotes: 1

Views: 1812

Answers (3)

ASH
ASH

Reputation: 20362

Look at the sample code here. This will do what you want.

public static void WriteDataToFile(DataTable submittedDataTable, string submittedFilePath)
        {
            int i = 0;
            StreamWriter sw = null;

            sw = new StreamWriter(submittedFilePath, false);

            for (i = 0; i < submittedDataTable.Columns.Count - 1; i++)
            {

                sw.Write(submittedDataTable.Columns[i].ColumnName + ";");

            }
            sw.Write(submittedDataTable.Columns[i].ColumnName);
            sw.WriteLine();

            foreach (DataRow row in submittedDataTable.Rows)
            {
                object[] array = row.ItemArray;

                for (i = 0; i < array.Length - 1; i++)
                {
                    sw.Write(array[i].ToString() + ";");
                }
                sw.Write(array[i].ToString());
                sw.WriteLine();

            }

            sw.Close();
        }

Also, take a look at this.

using System;
using System.Web;
using System.IO;
using System.Data;

namespace WebApplication1
{
    public partial class WebForm1 : System.Web.UI.Page
    {
        protected void Button1_Click(object sender, EventArgs e)
        {
            StreamWriter swExtLogFile = new StreamWriter("D:/Log/log.txt",true);
            DataTable dt = new DataTable();
           //Adding data To DataTable
            dt.Columns.Add("ID");
            dt.Columns.Add("Name");
            dt.Columns.Add("Address");
            dt.Rows.Add(1, "venki","Chennai");
            dt.Rows.Add(2, "Hanu","London");
            dt.Rows.Add(3, "john","Swiss");

            int i;
            swExtLogFile.Write(Environment.NewLine);
            foreach (DataRow row in dt.Rows)
            {  
                object[] array = row.ItemArray;
                for (i = 0; i < array.Length - 1; i++)
                {
                   swExtLogFile.Write(array[i].ToString() + " | ");
                }
                swExtLogFile.WriteLine(array[i].ToString());             
            }
            swExtLogFile.Write("*****END OF DATA****"+DateTime.Now.ToString());
            swExtLogFile.Flush();
            swExtLogFile.Close();

        }
    }
}

Upvotes: 0

Bizhan
Bizhan

Reputation: 17145

This is because data.Items is an ItemCollection and not a string.

All objects return the output of their ToString method when are asked to represent their contents as string. Normally you would override this method but in this case you can't.

So you need to tell the compiler how to retrieve the representative information from that collection. You can use either of these queries to fetch desired information out of the data grid:

var items = data.Items.AsQueryable().Cast<MyItemDataType>().Select(x => x.MyProperty);

var items = data.ItemsSource.Cast<MyItemDataType>().Select(x => x.MyProperty);

var items = data.Items.SourceCollection.AsQueryable().Cast<MyItemDataType>().Select(x => x.MyProperty);

items is a collection so you need to convert it to a string:

var text = items.Aggregate((x,y)=> x+", "+y);

MyItemDataType differs in each query and you have to find out yourself which data type is being used and MyProperty is the property in that class which represents the text of a row.

Edit

You can use this code too. It does the same thing:

string text = "";
for (int i = 0; i < data.Items.Count; i++)
{
    text += data.Items[i].ToString();

    if(i < data.Items.Count - 1)
        text += ", ";
}
writer.WriteLine(text);

But pay attention to the data type of each item in data.Items[i].ToString(). For example if each item is of type int then data.Items[i].ToString() returns a string representing the value of that integer (e.g. 1 turns into "1") but if they are of other types (e.g. such as Customer or MyDataGridItem) you need to override ToString() method of that class to look something like this:

public class Customer{
    //...

    public override string ToString(){
        return this.Id + " " + this.Name;
    }
}

so if you cannot override this method for any reason you need to do the other approach:

string text = "";
for (int i = 0; i < data.Items.Count; i++)
{
    Customer customer = data.Items[i] as Customer;//cast is required since type of Items[i] is object
    text += (customer.Id + " " + customer.Name);

    if(i < data.Items.Count - 1)
        text += ", ";
}
writer.WriteLine(text);

furthermore, you can use a StringBuilder to speed up the string concatenation because += is slow on strings.

Upvotes: 2

Mong Zhu
Mong Zhu

Reputation: 23732

You are using currently the following overload of the WriteLine method:

public virtual void WriteLine(object value)

If you look at the documentation of StreamWriter.WriteLine(object) it says that it:

Writes the text representation of an object by calling the ToString method on that object, followed by a line terminator to the text string or stream.

This is the reason why you get the following nice line in your file:

System.Windows.Controls.ItemCollection

The documentation of Object.ToString() method reveals that the

default implementations of the Object.ToString method return the fully qualified name of the object's type.

You would need to iterate through the collection and write each entry separately into the file. I would also suggest to use directly the data source instead of writing from the DataGrid.

foreach (DataRow row in dt.Rows)
{  
    object[] array = row.ItemArray;
    writer.WriteLine(string.Join(" | ", array));        
}

Upvotes: 3

Related Questions