Incorrect date format while exporting to csv - c#

I am newbie to c# and I am trying to export table data from sqlite 3 database to csv but datetime format has changed in csv the format in sqlite 3 is:
2013-04-16 21:33:42.000
while datetime in csv is showing up like:
16/04/2013 21:33:42,
This is my code:
SQLiteConnection m_dbConnection;
//m_dbConnection = new SQLiteConnection("Data Source= C:/Users/IT-Administrator/Desktop/WebMobility.db; Version=3;");
m_dbConnection = new SQLiteConnection("Data source = F:/Explor/final test/WebMobility.db; Version=3;");
m_dbConnection.Open();
SQLiteCommand myCommand = new SQLiteCommand();
myCommand.Connection = m_dbConnection;
myCommand.CommandText = "select CompanyId,`DateTime`,Serial,ShortDeviceId,MatricolaA,Upper(Targa),CommonRoadDescription,RoadCivicNumber,GpsAddress,VerbaliVehicleTypeDescription,VehicleBrandDescription,VehicleModelDescription,CommonColorVehicleDescription,VerbaliRuleOneCode,VerbaliRuleOneDescription,VerbaliClosedNoteDescription,VerbaliRuleOnePoints,VerbaliMissedNotificationDescription from VerbaliData";
//myCommand.Connection = myConn;
DataTable data = new DataTable();
SQLiteDataAdapter myAdapter = new SQLiteDataAdapter(myCommand);
//myAdapter.SelectCommand = myCommand;
myAdapter.Fill(data);
dataGridView1.DataSource = data;
this.dataGridView1.Refresh();
if (dataGridView1.RowCount > 0)
{
string value = "";
DataGridViewRow dr = new DataGridViewRow();
StreamWriter swOut = new StreamWriter("F:/Explor/final test/finaltest12.csv");
//write header rows to csv
for (int i = 0; i <= dataGridView1.Columns.Count - 1; i++)
{
if (i > 0)
{
swOut.Write(",");
}
swOut.Write(dataGridView1.Columns[i].HeaderText);
}
swOut.WriteLine();
//write DataGridView rows to csv
for (int j = 0; j <= dataGridView1.Rows.Count - 1; j++)
{
if (j > 0)
{
swOut.WriteLine();
}
dr = dataGridView1.Rows[j];
for (int i = 0; i <= dataGridView1.Columns.Count - 1; i++)
{
if (i > 0)
{
swOut.Write(",");
}
value = dr.Cells[i].Value.ToString();
//replace comma's with spaces
value = value.Replace(',', ' ');
//replace embedded newlines with spaces
value = value.Replace(Environment.NewLine, " ");
swOut.Write(value);
}
}
swOut.Close();
}
m_dbConnection.Close();

DateTime columns have no formats. It is just the tool used to show the column content that formats the column value in a particular format.
Said that it is obvious that you need to do the same thing to print your value on the CSV file.
Inside your internal loop, check if the column is the datetime one and then format its value to your likes.
for (int i = 0; i <= dataGridView1.Columns.Count - 1; i++)
{
if (i > 0)
{
swOut.Write(",");
}
// Datetime column content transformed in a formatted string....
if(i == 1)
value = Convert.ToDateTime(dr.Cells[i].Value).ToString("yyyy-MM-dd hh:mm:ss.fff");
else
....
EDIT in case you have null or empty values in your cell then you need to check for that before trying to convert
// Datetime column content transformed in a formatted string....
if(i == 1)
{
object cellValue = dr.Cells[i].Value;
value = (cellValue == DBNull.Value ?
string.Empty : Convert.ToDateTime(cellValue).ToString("yyyy-MM-dd hh:mm:ss.fff");
}
This will write an empty column where the date is expected. This could be correct or not, depending on how the CSV file is required. Instead of an empty string you could save a predefined value.

if (i==1)
{
value = dr.Cells[i].Value.ToString();
if (value!null)
{
string dt=DateTime.Parse(value).ToString("yyyy/MM/dd hh:mm:ss");
swOut.Write(dt);
}
......
}

Related

How to read Excel to Datatable using NPOI C#

I'm Trying to read Excel to DataTable using NPOI.Every thing working fine but only issue is If we have any Column cell is empty in that row it is not reading .In Excel i have 4 row's with (each row have some empty values for cells).
Excel File Image : enter image description here
After Reading That Excel To data table :enter image description here
I want like this in data table
private DataTable GetDataTableFromExcel(String Path)
{
XSSFWorkbook wb;
XSSFSheet sh;
String Sheet_name;
using (var fs = new FileStream(Path, FileMode.Open, FileAccess.Read))
{
wb = new XSSFWorkbook(fs);
Sheet_name = wb.GetSheetAt(0).SheetName; //get first sheet name
}
DataTable DT = new DataTable();
DT.Rows.Clear();
DT.Columns.Clear();
// get sheet
sh = (XSSFSheet)wb.GetSheet(Sheet_name);
int i = 0;
while (sh.GetRow(i) != null)
{
// add neccessary columns
if (DT.Columns.Count < sh.GetRow(i).Cells.Count)
{
for (int j = 0; j < sh.GetRow(i).Cells.Count; j++)
{
DT.Columns.Add("", typeof(string));
}
}
// add row
DT.Rows.Add();
// write row value
for (int j = 0; j < sh.GetRow(i).Cells.Count; j++)
{
var cell = sh.GetRow(i).GetCell(j);
DT.Rows[i][j] = sh.GetRow(i).GetCell(j);
}
i++;
}
return DT;
}
Plese hlp me.
you may have to try something along this line. its workable code to read the excel using NPOI.
// read the current row data
XSSFRow headerRow = (XSSFRow)sheet.GetRow(0);
// LastCellNum is the number of cells of current rows
int cellCount = headerRow.LastCellNum;
// LastRowNum is the number of rows of current table
int rowCount = sheet.LastRowNum + 1;
bool isBlanKRow = false;
//Start reading data after first row(header row) of excel sheet.
for (int i = (sheet.FirstRowNum + 1); i < rowCount; i++)
{
XSSFRow row = (XSSFRow)sheet.GetRow(i);
DataRow dataRow = dt.NewRow();
isBlanKRow = true;
try
{
for (int j = row.FirstCellNum; j < cellCount; j++)
{
if (null != row.GetCell(j) && !string.IsNullOrEmpty(row.GetCell(j).ToString()) && !string.IsNullOrWhiteSpace(row.GetCell(j).ToString()))
{
dataRow[j] = row.GetCell(j).ToString();
isBlanKRow = false;
}
}
}
catch (Exception Ex)
{
}
if (!isBlanKRow)
{
dt.Rows.Add(dataRow);
}
}

Create an Excel file with the Excel interop class from SQL Database

I want to create an Excel file with the Excel interop class from the SQL Database. With SQL query, I had previously transferred the dataset into dataGridview. The result of the query is the data. However, I can't Print this data from the SQL database to Excel cells with the dataset.
private void linkLabel10_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
using (var fbd = new FolderBrowserDialog())
{
DialogResult result = fbd.ShowDialog();
if (result == DialogResult.OK && !string.IsNullOrWhiteSpace(fbd.SelectedPath))
{
string fileTest = fbd.SelectedPath.ToString() + "\\"+ comboBox1.Text.Substring(0, comboBox1.Text.IndexOf("*") - 1) +"-"+ comboBox2.Text.Substring(0, comboBox2.Text.IndexOf("(") - 1) +"-"+ comboBox2.Text.Substring(comboBox2.Text.IndexOf("(") + 1, 10) + ".xlsx";
MessageBox.Show(fileTest);
if (File.Exists(fileTest))
{
File.Delete(fileTest);
}
SqlDataAdapter da = new SqlDataAdapter("select PersonelKodu= ztSinifEgitimiDurum.KisiID, İsim= dbo.cdCurrAcc.FullName, Katılım = CASE WHEN Katilim = 1 THEN 'Katıldı' ELSE 'Katılmadı' END, ztSinifEgitimiDurum.ID FROM dbo.ztSinifEgitimiDurum INNER JOIN dbo.cdCurrAcc ON cdCurrAcc.CurrAccCode = ztSinifEgitimiDurum.KisiID AND cdCurrAcc.CurrAccTypeCode = ztSinifEgitimiDurum.KisiTipiID WHERE AtamaID =" + AtamaIDBul(), baglan);
DataSet ds = new DataSet();
Excel.Application Excel;
Excel.Worksheet excelWorkSheet;
Excel.Workbook excelWorkBook;
Excel = new Excel.Application();
excelWorkBook = Excel.Workbooks.Add();
excelWorkSheet = (Excel.Worksheet)excelWorkBook.Worksheets.get_Item(1);
excelWorkSheet.Cells[1, 1] = "some value";
excelWorkSheet.Name = "Ali";
foreach (DataTable table in ds.Tables)
{
for (int i = 1; i < table.Columns.Count + 1; i++)
{
excelWorkSheet.Cells[1, i] = table.Columns[i - 1].ColumnName;
MessageBox.Show(table.Columns[i - 1].ColumnName.ToString());
}
for (int j = 0; j < table.Rows.Count; j++)
{
for (int k = 0; k < table.Columns.Count; k++)
{
excelWorkSheet.Cells[j + 2, k + 1] = table.Rows[j].ItemArray[k].ToString();
}
}
}
// excelWorkSheet.Cells[1, 1] = "some value";
excelWorkBook.SaveAs(fileTest);
excelWorkBook.Close();
Excel.Quit();
}
}
}
You forgot to fill your DataSet, add this line
da.Fill(ds); after DataSet ds = new DataSet();
You can try this code to fill your sheet with values from a table:
ws.Activate();
foreach (DataTable dt in ds.Tables)
{
// Add column headers from the datatable
for (int Idx = 0; Idx < dt.Columns.Count; Idx++)
{
ws.Range["A1"].Offset[0, Idx].Value = dt.Columns[Idx].ColumnName;
}
// add data rows
for (int Idx = 0; Idx < dt.Rows.Count; Idx++)
{ // hey I did not invent this line of code, I found it somewhere on CodeProject.
// It works to add the whole row at once
ws.Range["A2"].Offset[Idx].Resize[1, dt.Columns.Count].Value = dt.Rows[Idx].ItemArray;
}
...
But you will have to add more worksheets for individual tables in case there is more than one table in your DataSet.
It is based on this article.

SSIS Export to Excel using Script Task

I'm trying to use a Script Task to export data to Excel because some of the reports I generate simply have too many columns to keep using a template file.
The most annoying part about using a template is: if something as simple as a column header changes, the metadata gets screwed forcing me to recreate my DataFlow. Because I use an OLE DB source, I need to use a Data Transformation task to convert between unicode and non-unicode character sets, then remap my Excel Destination to the "Copy of field x" in order for the Excel document to create properly.
This takes far too long and I need a new approach.
I have the following method in a script task using Excel = Microsoft.Office.Interop.Excel:
private void ExportToExcel(DataTable dataTable, string excelFilePath = null)
{
Excel.Application excelApp = new Excel.Application();
Excel.Worksheet workSheet = null;
try
{
if (dataTable == null || dataTable.Columns.Count == 0)
throw new System.Exception("Null or empty input table!" + Environment.NewLine);
excelApp.Workbooks.Add();
workSheet = excelApp.ActiveSheet;
for (int i = 0; i < dataTable.Columns.Count; i++)
{
workSheet.Cells[1, (i + 1)] = dataTable.Columns[i].ColumnName;
}
foreach (DataTable dt in dataSet.Tables)
{
// Copy the DataTable to an object array
object[,] rawData = new object[dt.Rows.Count + 1, dt.Columns.Count];
// Copy the column names to the first row of the object array
for (int col = 0; col < dt.Columns.Count; col++)
{
rawData[0, col] = dt.Columns[col].ColumnName;
}
// Copy the values to the object array
for (int col = 0; col < dt.Columns.Count; col++)
{
for (int row = 0; row < dt.Rows.Count; row++)
{
rawData[row + 1, col] = dt.Rows[row].ItemArray[col];
}
}
// Calculate the final column letter
string finalColLetter = string.Empty;
string colCharset = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int colCharsetLen = colCharset.Length;
if (dt.Columns.Count > colCharsetLen)
{
finalColLetter = colCharset.Substring((dt.Columns.Count - 1) / colCharsetLen - 1, 1);
}
finalColLetter += colCharset.Substring((dt.Columns.Count - 1) % colCharsetLen, 1);
workSheet.Name = dt.TableName;
// Fast data export to Excel
string excelRange = string.Format("A1:{0}{1}", finalColLetter, dt.Rows.Count + 1);
//The code crashes here (ONLY in SSIS):
workSheet.get_Range(excelRange, Type.Missing).Value2 = rawData;
// Mark the first row as BOLD
((Excel.Range)workSheet.Rows[1, Type.Missing]).Font.Bold = true;
}
List<int> lstColumnsToSum = new List<int>() { 9 };
Dictionary<int, string> dictColSumName = new Dictionary<int, string>() { { 9, "" } };
Dictionary<int, decimal> dictColumnSummation = new Dictionary<int, decimal>() { { 9, 0 } };
// rows
for (int i = 0; i < dataTable.Rows.Count; i++)
{
for (int j = 1; j <= dataTable.Columns.Count; j++)
{
workSheet.Cells[(i + 2), (j)] = dataTable.Rows[i][j - 1];
if (lstColumnsToSum.Exists(x => (x == j)))
{
decimal val = 0;
if (decimal.TryParse(dataTable.Rows[i][j - 1].ToString(), out val))
{
dictColumnSummation[j] += val;
}
}
}
}
//Footer
int footerRowIdx = 2 + dataTable.Rows.Count;
foreach (var summablecolumn in dictColSumName)
{
workSheet.Cells[footerRowIdx, summablecolumn.Key] = String.Format("{0}", dictColumnSummation[summablecolumn.Key]);
}
// check fielpath
if (excelFilePath != null && excelFilePath != "")
{
try
{
if (File.Exists(excelFilePath))
File.Delete(excelFilePath);
workSheet.Activate();
workSheet.Application.ActiveWindow.SplitRow = 1;
workSheet.Application.ActiveWindow.FreezePanes = true;
int row = 1;
int column = 1;
foreach (var item in dataTable.Columns)
{
Excel.Range range = workSheet.Cells[row, column] as Excel.Range;
range.NumberFormat = "#";
range.EntireColumn.AutoFit();
range.Interior.Color = System.Drawing.ColorTranslator.ToOle(System.Drawing.Color.LightGray);
column++;
}
Excel.Range InternalCalculatedAmount = workSheet.Cells[1, 9] as Excel.Range;
InternalCalculatedAmount.EntireColumn.NumberFormat = "#0.00";
InternalCalculatedAmount.Columns.AutoFit();
workSheet.SaveAs(excelFilePath);
}
catch (System.Exception ex)
{
throw new System.Exception("Excel file could not be saved! Check filepath." + Environment.NewLine + ex.Message);
}
}
else // no filepath is given
{
excelApp.Visible = true;
}
}
catch (System.Exception ex)
{
throw new System.Exception("ex.Message + Environment.NewLine, ex.InnerException);
}
}
The exception thrown is a System.OutOfMemoryException when trying to execute the following piece of code:
workSheet.get_Range(excelRange, Type.Missing).Value2 = rawData;
My biggest frustration is that this method works 100% in a regular C# application.
The DataTable contains about 435000 rows. I know it's quite a bit of data but I use this very method, modified of course, to split data across multiple Excel worksheets in one of my other applications, and that DataSet contains about 1.1m rows. So less than half of my largest DataSet should be a walk-in-the-park...
Any light shed on this matter would be amazing!

CSV to SQL - Add 1 day to a Date in a datacolumn

I am trying to add 1 day to all dates that are in a certain datacolumn ['RecordAddedDate']
csvData.Columns.AddRange(new DataColumn[3] {
new DataColumn("Manufacturer", typeof(string)),
new DataColumn("SupplierCode", typeof(string)),
new DataColumn("RecordAddedDate", typeof(DateTime))});
At the moment the moment I have this working:
for (int rowIndex = 0; rowIndex < csvData.Rows.Count; rowIndex++)
{
DateTime dt2 = DateTime.Parse(fieldData[2]);
var newDate = dt2.AddDays(1);
csvData.Rows[rowIndex][2] = newDate;
}
But it only adds 1 day to the first row read from the csv and doesn't add for the rest.
Any Help?
Here is the while loop which reads the data from the csv and adds the data
while (!csvReader.EndOfData)
{
string[] fieldData = csvReader.ReadFields();
//Making empty value as null
for (int i = 0; i < fieldData.Length; i++)
{
Console.WriteLine(fieldData[i]);
if (fieldData[i] == "")
{
fieldData[i] = null;
}
for (int rowIndex = 0; rowIndex < csvData.Rows.Count; rowIndex++)
{
DateTime dt2 = csvData.Rows[rowIndex].Field<DateTime>(2);
DateTime newDate = dt2.AddDays(1);
csvData.Rows[rowIndex][2] = newDate;
}
}
csvData.Rows.Add(fieldData);
Console.WriteLine("Rows count:" + csvData.Rows.Count);
}
}
return csvData;
What is fieldData[2]? You are always using this in the loop, so no wonder that you always get the same DateTime. If the table is already filled and you want to update a value use csvData.Rows[rowIndex][2] = csvData.Rows[rowIndex].Field<DateTime>(2).AddDays(1);
for (int rowIndex = 0; rowIndex < csvData.Rows.Count; rowIndex++)
{
DateTime dt2 = csvData.Rows[rowIndex].Field<DateTime>(2);
DateTime newDate = dt2.AddDays(1);
csvData.Rows[rowIndex][2] = newDate;
}

boolean value always coming false in csv import

I am importing a csv file wherein there are 10 columns. Among those there is Boolean column which could be (1 , true ,false, 0) .
I am reading the csv file and creating a data-table all is working fine except the boolean value field , it always return false.
Below code for creating the data tabel from csv.
public static DataTable GetDataTable(bool firstRowColumnName, string path)
{
StreamReader sr = new StreamReader(path);
string line = null;
DataTable dtResult = new DataTable();
if (firstRowColumnName)
{
line = sr.ReadLine();
string[] headers = line.Split(',');
for (int i = 0; i < headers.Length; i++)
{
dtResult.Columns.Add(headers[i]);
}
}
while ((line = sr.ReadLine()) != null)
{
if (line.Trim() != string.Empty)
{
string[] lineData = line.Split(',');
if (dtResult.Columns.Count == 0)
{
for (int i = 0; i < lineData.Length; i++)
{
dtResult.Columns.Add("Column" + i.ToString());
}
}
DataRow drNew = dtResult.NewRow();
for (int i = 0; i < lineData.Length; i++)
{
drNew[i] = lineData[i];
}
dtResult.Rows.Add(drNew);
}
}
return dtResult;
}
below is the code where i am reading the datatable.
machine is an object of a class.
machine.IsLaptop = dt.Rows[i]["Laptop"].ToString() == "1" || dt.Rows[i]["Laptop"].ToString().ToLower() == "true";
Kindly suggest why the value is always false.
Since you're working with string values, the value being read probably is " true " including the spaces.
Try using Convert.ToBoolean and/or with Convert.ToInt32 to translate your values.
http://msdn.microsoft.com/en-us/library/system.convert.toboolean%28v=vs.110%29.aspx
You may need some logic to handle cases where you do not get a Boolean.TrueString or Boolean.FalseString. In that case you can Boolean.TryParse

Categories