I am trying to export datagrid's data to an excel sheet in C#. Using below code I managed to export it successfully
private void ExportToExcelAndCsv()
{
dataGrid.SelectAllCells();
dataGrid.ClipboardCopyMode = DataGridClipboardCopyMode.IncludeHeader;
ApplicationCommands.Copy.Execute(null, dataGrid);
String resultat = (string)Clipboard.GetData(DataFormats.CommaSeparatedValue);
String result = (string)Clipboard.GetData(DataFormats.Text);
dataGrid.UnselectAllCells();
System.IO.StreamWriter file1 = new System.IO.StreamWriter(#"C:\Users\Fisniku\Desktop\"+tipiL+".xls");
file1.WriteLine(result.Replace(',', ' '));
file1.Close();
}
My issue is that I have a column in String datatype in SQLServer containing data in format of fractions such as:
1/2
2/2
1/3
9/4
When data is exported in excel, that column becomes a date, and shows data like a date 01-Jan in Custom format.
After trying to modify the column in excel to text format, it looses value and becomes invalid.
How can I modify the code so it will preserve the same format as in datagrid?
I am assuming that this data in the grid originates from a SQL query or table based on the tags on your question. If that's the case, and if either the data is read-only or the data is in a datatable that is bound to the grid, then an easy way of accomplishing this is to use EPPlus instead of interop.
EPPlus has a single command to export a C# datatable (System.Data.DataTable) into a spreadsheet:
ws.Cells["A1"].LoadFromDataTable(dt, true);
And, per your original problem, it respects datatypes meaning it won't clobber leading zeroes on text fields that have all numbers, convert text that looks like a date into a date, etc.
If you're not using a datatable, you can always convert your content to a datatable (although there is a lot of overhead with this approach).
If you are married to interop, then just be sure you format the appropriate columns as text BEFORE you do the paste:
sheet.Range["A:A"].NumberFormat = "#";
You may need to format the cell as text. Take a look at this question:
Format an Excel column (or cell) as Text in C#?
Related
I am exporting a DataSet to excel that was generated by running an SQL script within my C# program. The DataSet correctly stores certain columns as datetimes, but from my understanding it does not store formatting information. It appears then that the formatting is given when call
ws.FirstCell().InsertTable(dt, false);
Which gives it the default format dd/mm/yyyy. Unfortunately I can't just select the whole range with ClosedXML and change the number format since come columns contain non-date numbers.
I suppose I could probably go through my data set, find which columns are date times, and format those columns accordingly with closedXML. I would imagine there has to be a better way though. Does anyone know an easy option for doing this with closed XML (or interop even)? I was unable to find anything on this.
EDIT:
Appears this is the only way at the moment... if anyone needs it (and manages to find this post) its easy enough to do:
//select which columns are dates and change default format
int colNum = 1;
foreach (DataColumn col in dt.Columns)
{
if (col.DataType == typeof(System.DateTime))
{
Console.WriteLine(colNum);
ws.Column(colNum).Style.NumberFormat.Format = "mmm-dd-yyyy";
}
colNum++;
}
ws.FirstCell().InsertTable(dt, false);
Our Excel 2013 xlsx file has tab "DEPTS" and this tab has a column called "1F/3F". Each cell in this column can have one of these values: "5", "Ati_3", "4", "Btu_4", etc.
Before today, I would move the contents of this tab to a dataset with this straightforward snippet. The dataset viewer would display all rows and all columns:
string connectionString = string.Format(ExcelConnstring, FileName);
string deptsSql = string.Format("SELECT * FROM [{0}$]", "DEPTS");
DataSet deptsDataset = new DataSet();
using (OleDbConnection con = new OleDbConnection(connectionString))
{
con.Open();
OleDbDataAdapter adapter = new OleDbDataAdapter(deptsSql, con);
adapter.Fill(deptsDataset);
con.Close();
}
return deptsDataset;
Today, I try to upload today's file, which is the same exact format. When I look at the contents of the dataset, I notice that the cells in column "1F/3F" that are not numerical are empty. It's reading all 40 rows, but those particular cells whose values could be "Ati_3", "Btu_4" (ie. not numeric) are being read as empty. The numeric values are being read correctly.
How can I compare an older file with this file? The file seems to be correct, and I have no idea how to check if something was added to that particular column that would cause the error.
Thanks.
The ADO.NET driver uses the data in each column (the first 10 rows or so) to determine its datatype, which is terrible but it is what it is. If you have a column which has numeric values in the first 10 or so rows, the driver treats that as a numeric column and will read any non-numeric values as null.
Cell formats in the excel document are not honored by the driver. If you want to ensure that the data is read as text, and you have control over the process that generates the excel document, you can force the column to be treated as text by inserting 10 or so dummy values (e.g. 'Ignore') and throw away those rows after you have read the contents.
By ensuring that the first 10 rows of a column contain text, the driver will correctly read the numeric and non-numeric values for that column (they will all be treated as text).
If you cannot control the creation of the file you are going to read you could switch to another technology to read the Excel document. Some alternatives include:
EPPlus (http://epplus.codeplex.com/) - safe to use on a server
Office Automation - not safe to use on a server
Sample code is
INSERT INTO OPENROWSET ('Microsoft.ACE.OLEDB.12.0', 'Excel 8.0;Database=E:\Application\PASpready\Files\NK\NKAll.xlsx;HDR=YES;','SELECT * FROM [All$]')
select ..... from table
All the data comes over as text and number decimals loose their format. How can i keep the data format in excel.
Try building that NKAll.xlsx file prior to exporting, as a template, having a dummy row of data with correct formats.
That might help excel infer the types correctly. If that works, then you can initially update the first row, and then insert all the rest.
I am using the CarlosAg.ExcelXmlWriter library to generate an Excel file in C#. If I treat all data as strings everything works fine, but I need some cells to be recognized by Excel as date fields. When I try to set the data type accordingly, the resulting Excel file fails to open in Excel 2003 (or Excel 2007 for that matter).
In Excel 2003, I get the following error on load:
Problems came up in the following area
during load: Table
I am using the following code to generate the DateTime cells that are causing the problem:
string val = DateTime.Now.ToString("MM/dd/yyyy");
row.Cells.Add(new WorksheetCell(val, DataType.DateTime));
Thanks.
I eventually figured this out. Thanks to Lance Roberts for nudging me in the right direction.
First, define a WorksheetStyle called dateStyle and set its NumberFormat property to a valid Excel date format:
Workbook book = new Workbook();
Worksheet sheet = book.Worksheets.Add("myWorksheet");
WorksheetStyle dateStyle = book.Styles.Add("dateStyle");
dateStyle.NumberFormat = "Dd Mmm Yy";
WorksheetRow row = book.Worksheets[0].Table.Rows.Add();
Then, export the date using the .NET "s" date format and add the cell:
string val = DateTime.Now.ToString("s");
row.Cells.Add(val, DataType.DateTime, "dateStyle");
I haven't used his library, but work in Excel a lot. I don't know what he's doing with a datatype for a cell, since they don't work that way. Dates in Excel cells are all integers with Date Formatting.
I would try to put the date in as an integer, the trick is converting your string to the correct integer. See this link for information on Excel's Date as Numbers methodology. I would then set the WorksheetStyle.NumberFormat Property.
I am using C# & MYSQL to develop a desktop application.
In one of my form I have a DataGridView (dgvBookings) and in my database table I have a table tblBookings which contains a field specialization of type BLOB.
I am selecting data with following query,
SELECT * FROM tblBookings WHERE IsActive=1;
and then binding the data with DataGridView as,
dgvBookings.DataSource = ds.Tables["allbookings"];
BUT after binding the data in gridview it shows Byte[] Array value for all rows of column specialization which is of BLOB type.
How yo solve this problem, I want the data in String format, whatever is written in that column should be show as it is there in the grid.
You'll have to convert the byte array to a string before using the DataSet:
DataTable allBookings = ds.Tables["allbookings"];
DataColumn column = allBookings.Columns.Add("NotABlobAnyMore", typeof(string));
foreach (DataRow row in allBookings.Rows) {
row[column] = Encoding.Unicode.GetString((byte[])row["specialization"]);
}
dgvBookings.DataSource = allBookings ;
In the sample I'm using Unicode, but you should use whatever encoding was used to generate the byte array (blob).
If you are going to allow updates on the new column, you'll have to convert the string back to an array of bytes (in the old column) before sending the data back to the database.
Sink the CellFormatting event and cast the byte array to a String, or cast the BLOB to a character type in your SQL query.
Well, the inherent problem with a BLOB is that it... isn't text. It is binary. It could be an image (jpg etc), an exe, or it could be text... but in which encoding? UTF8? Not simple. If it was a CLOB I'd hope it works OK - but otherwise I would fully anticipate that you'd have to parse the BLOB manually, otherwise how would it be interpreted?
For an arbitrary BLOB, the closest I can think of is to just show something like the hex... but with DataTable even that is a challenge. You could do it for a class via a TypeConverter...