0

I'm fetching some records from SQL Server 2012 table. For that I've used DataTable. I want to write the fetched records to multiple CSV files.

I've used StringBuilder to write the column headers and fields to CSV file (single CSV file).

But, now the new requirement is to first filter the records based on columns and then write into multiple files.

  1. Suppose I've 5 columns col1, col2, col3, col4 and col5.
  2. I need to write col1,col2 and col5 to once CSV file and then col1,col3 and col4 to another CSV file.
  3. I also want to include a column - col0 as first column which will be added through code and is not present in database. This column will be derived from col3 and col5. something like this:

    dt.Columns.Add("col0", typeof(System.String)).SetOrdinal(0);

    row["col0"] = row["col3"] + "_" + row["col5"];

  4. Issue with the point 3 is I can't derive col0 unless I'm fetching both the rows - col3 and col5 from datatable (dt). It's giving me error

System.ArgumentException: Column 'col3' does not belong to table Selected.

Please let me know how to proceed?

code:

public static void CreateCSVFile(DataTable dt, string CSVPath, string CSVFileName, int FileSize)
{
    StringBuilder FirstLine = new StringBuilder();
    StringBuilder records = new StringBuilder();

    int num = 0;
    int length = 0;

    dt.Columns.Add("Update", typeof(System.String)).SetOrdinal(0);
    dt.Columns.Add("Key", typeof(System.String)).SetOrdinal(1);

    IEnumerable<string> columnNames = dt.Columns.Cast<DataColumn>().Select(column => column.ColumnName);
    FirstLine.Append(string.Join(",", columnNames));
    records.AppendLine(FirstLine.ToString());
    length += records.ToString().Length;

    int lastindex = dt.Rows.Count;
    foreach (var row1 in dt.Rows.Cast<DataRow>().Select((r, i) => new { Row = r, Index = i }))
    {
        DataRow row = row1.Row;
        row["Update"] = "Update";
        row["Key"] = row["Name"] + "_" + row["Code"];

        //Putting field values in double quotes
        IEnumerable<string> fields = row.ItemArray.Select(field =>
            string.Concat("\"", field.ToString().Replace("\"", "\"\""), "\""));

        records.AppendLine(string.Join(",", fields));
        length += records.ToString().Length;

        if (length > FileSize)
        {
            //Create a new file
            num++;
            File.WriteAllText(CSVPath + CSVFileName + DateTime.Now.ToString("yyyyMMddHHmmss") + num.ToString("_000") + ".csv", records.ToString());
            records.Clear();
            length = 0;
            records.AppendLine(FirstLine.ToString());
            length += records.ToString().Length;
        }
        else if (row1.Index == lastindex - 1 && length != 0 && length < FileSize)
        {
            //Create a new file
            num++;
            File.WriteAllText(CSVPath + CSVFileName + DateTime.Now.ToString("yyyyMMddHHmmss") + num.ToString("_000") + ".csv", records.ToString());
            records.Clear();
            length = 0;
            records.AppendLine(FirstLine.ToString());
            length += records.ToString().Length;
        }
    }
}
MD SARFARAZ
  • 117
  • 3
  • 17
  • 4
    Where are you stuck? Seems like a pretty straightforward solution with if statements and/or LINQ – Rob Apr 19 '16 at 06:19
  • I've edited the question, probably this will help to make the question more clear to you. Before writing the file I want to filter the columns and then write the file. – MD SARFARAZ Apr 19 '16 at 06:38
  • @Rob : I've used DataView to create view for the columns I want to select and then I'm trying to write the CSV. This is what I'm doing. `DataView view = new DataView(dt); DataTable New1Dt = view.ToTable("Selected", true, "col1","col2","col5"); DataView view = new DataView(dt); DataTable New2Dt = view.ToTable("Selected", true, "col1","col3","col4"); ` – MD SARFARAZ Apr 20 '16 at 07:25

0 Answers0