importing Data table to Excel text becomes numeric - c#

Hi just want to ask I am trying to import Datatables to excel and one of the columns becomes exponent like 444201000100100 becomes 4442exp8? here's my script
protected void btnExportfromDt_Click(object sender, EventArgs e)
{
string strFilename = "FinanceforBulkupload.xls";
UploadDataTableToExcel(LoadData(), strFilename);
}
protected void UploadDataTableToExcel(DataTable dtEmp,string filename)
{
string attachment = "attachment; filename="+filename;
Response.ClearContent();
Response.AddHeader("content-disposition", attachment);
Response.ContentType = "application/vnd.ms-excel";
string tab = string.Empty;
foreach (DataColumn dtcol in dtEmp.Columns)
{
Response.Write(tab + dtcol.ColumnName);
tab = "\t";
}
Response.Write("\n");
foreach (DataRow dr in dtEmp.Rows)
{
tab = "";
for (int j = 0; j < dtEmp.Columns.Count; j++)
{
Response.Write(tab + Convert.ToString(dr[j]));
tab = "\t";
}
Response.Write("\n");
}
Response.End();
}

Pre-append a single quote to the value before you store it. Instead of:
444201000100100
store:
'444201000100100

must write the cell formatted text but the method we're using to write the cell does not allow you to add formatting, you should try another method to write the Excel file

You can also format the destination column to be of type text (or whatever Excel format you'd prefer), to prevent it from doing this as well as removing leading zeros and other interpretations of the "General" cell formating rules.
As you're creating your output document on-the-fly, you'd need to set either specific columns or the entire worksheet to have this format rule. in VBA, this command is:
Columns("A:A").NumberFormat = "#" ' This is the Text format
In C#, you should be able to do something along the lines of:
Excel.Range rng = this.Application.get_Range("A:A");
rng.NumberFormat = "#";
However this would require a reference to the Excel object, and from your existing code it looks as though you're working without that for the moment.
Gary's Student's answer will work as well, but doing so will cause those cells to ignore any formatting that is applied later when it is opened in Excel. The user would be required to remove the leading ' manually to control the format as expected.

You have different options as others proposed.
Understand that you are generating a CSV and not an Excel file so you are limited.
Since a cell format is an excel property and cannot be specified in a CSV file, I would recommend creating an excel file (.xlsx) with EPPlus and write code to specify the column format as TravelinGuy suggested. http://epplus.codeplex.com/
If you want to stick to CSV then you are limited as to how the data will be displayed in Excel. Either you accept that Excel infers a number format from what it is reading or you put a leading quote...

Unfortunately, you have to manually perform minor encoding when sending data to Excel. This is true of the automation API as well as any text-based file formats like CSV or (as in your case) tab-separated files.
A robust solution must prepend a single ' character to a string in the following cases.
The string can be parsed as a number (Excel uses VariantChangeTypeEx, but since you're using C#, Double.TryParse will do the trick)
The string already already starts with a tick ('). (For example, if you have the string 'quoted', Excel will interpret it as quoted' unless you put another single tick at the front -- ''quoted'.)
The string starts with an = character. Even in the case of CSV files, Excel inteprets this to be a worksheet function. Putting a tick at the front prevents this (e.g. '=This is not a worksheet function).
If you still find this unacceptable, please know that you have no other option when you're writing text files manually like you're doing. If you object so strongly, you can try using the Open XML SDK or some other 3rd-party tool for building Excel workbooks. However, given what looks like a very simple use case, you'll almost certainly end up with a more complex solution that is slower and requires more code. I recommend just sucking it up and writing a simple routine that abides by the rules above.

Related

How to write tab-delimited text into excel sheet programmatically?

I have an object of StringBuilder which stores a tab-delimited text and I want to import it to an Excel sheet. In my application it can be achieved in two ways. From a dialog one can choose either copying the text to the clipboard (and then he/she can open a new Excel sheet and simply paste in Excel) or saving it directly to an Excel workbook. First option works perfectly fine and I want to implement the behaviour for saving directly.
The only way that I found on the internet is storing each line of the text to the string array and then each index of array will be new row in Excel sheet, so I can write each row by iterating the array.
for (int i = 0; i < exportStrings.Count; i++)
{
Excel.Range currentRange = (Excel.Range)xlWsh.Cells[i + 1, 1];
currentRange.Value = exportStrings[i];
}
But then it causes a problem for the first option. Since the text is now stored as a string array, I cannot easily copy it to the clipboard. That is why I decided to keep my text stored as a stringbuilder. I also tried to write the text to the very first cell in the Excel sheet, (since it works when I paste the text to first cell in Excel sheet manually in the first option) but it doesn't recognise the new line charactes.
Excel.Range currentRange = (Excel.Range)xlWsh.Cells[1, 1];
currentRange.Value2 = exportStrings.ToString();
Any idea how it can be done using stringbuilder? or how can I make it to recognise new line character?
You can always extract a string from your string builder, and then split it into lines, if you need a string array:
StringBuilder sb = new StringBuilder();
//fill sb with whatever data you need
if (option1)
{
//use stringbuilder, copy to clipboared
}
if (option2)
{
//convert to string array
String allText = sb.ToString();
string[] textLines = allText.Split(Environment.NewLine);
//write to Excel...
}
Admittedly, this is not perfect in terms of efficiency: You are creating an intermediate string, and then you again allocate memory for the string array. But I am going to assume that you are dealing with a limited amount of data, and that the interaction with Excel takes more time anyway than a few object allocations.

MS Office Automation transfer table from excel to word using PublishObjects.Add

For a project I'm working on, we need to copy data from Excel sheets into new tables within a Word document and have a strategy that works... in most cases.
First, we do
string file = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString() +
".mht");
object sheetObj = sheetName;
object trueObj = true;
Excel.PublishObject obj = workbook.PublishObjects.Add(Excel.XlSourceType.xlSourceSheet, file,
sheetObj);
obj.Publish(trueObj);
then
Document tempDocument = wordApp.Documents.Open(file);
and read templDocument into the targe Word doc.
...
In a couple of cases, we're seeing problems. (The problems are illustrated in the example files at http://thinkscience.us/office/examples.zip)
1) the big text files show text truncation between Excel and the exported .mht
2) the 'nutritional' files show the addition of several lines of white space between the Excel data and the .mht.
I've tried several variations on the parameters to PublishObjects.Add (using a range rather than an entire sheet). The add method includes an optional XlHtmlType parameter that only works with value XlHtmlType.xlHtmlStatic.
Has anyone used PublishObjects.Add or another strategy to transfer sheets from Excel to Word, preserving as much formatting as possible and not interfering with the system clipboard?
I found an article which might meet your needs, but it's not using Office automation, it's using a library called Spire.Office. Check: How to Maintain Formatting of Cells when Copying Cells from Excel to Word.

How To Parse a Scientific Notation Value Back To Original Value When Reading CSV In C#

I am working on a weather map application that imports csv files via a url. The date fields inside the csv are stored as a string like 201601280330, which would be today's date 1/28/2016 3:30. However, when reading the csv via a streamreader the value is coming back in scientific notation like 2.01601E+11. Nothing I have tried seems to return the whole value 201601280330.
For example:
var date = "2.01601E+11";
var d = Decimal.Parse(date, System.Globalization.NumberStyles.Float);
returns 201601000000 chopping off the remaining part of the string. Does anyone know a way to return the full value. When I save the csv locally as a text file the correct value 201601280330 is saved rather than 2.01601E+11. Anyway to get this in the code without having to save first? I am using the code below to read the csv file.
public static DataTable GetDataTableFromCSVFile(string path)
{
DataTable dt = new DataTable();
try
{
using (StreamReader sr = new StreamReader(path))
{
string[] headers = sr.ReadLine().Split(',');
foreach (string header in headers)
{
if (header.Contains("ERROR:"))
{
return null;
}
dt.Columns.Add(header);
}
while (!sr.EndOfStream)
{
string[] rows = sr.ReadLine().Split(',');
DataRow dr = dt.NewRow();
for (int i = 0; i < headers.Length; i++)
{
dr[i] = rows[i];
}
dt.Rows.Add(dr);
}
}
}
EDIT
Although this does not provide a technical answer to the problem I was experiencing it might provide a better explanation and help others if they experience this. Some of the example csv files sent to me for testing had been edited in Excel to make the csv smaller and then saved. After further testing, it looks like the issue occurs only for the csv files edited in Excel. Tentatively, this solves the problem for me since we won't be downloading the csv files and editing them in Excel, rather pulling them straight from a url. The code I posted above will read a the correct value without notation while for the csv edited in Excel it will only read the value with scientific notation. Unless I am wrong, I assume Excel must add something to edited csv files that prevents the value from being read correctly.
My original answer questioned whether you were using Excel, but as you hadn't mentioned that in your question I was rightly told that I was off topic, so I changed it. Now that you have provided a follow-up answer that does mention Excel I have changed it back, here is what I wrote originally:
Once the value has been converted into scientific notation it cannot be converted back. It is a limitation of Excel that is performing this conversion. If, when importing the data you choose a column type of Text (rather than General), then the data will be imported verbatim and Excel won't convert it into scientific notation.
As I suspected, it is Excel (not your code) that is changing the numerical data into scientific notation. I have seen this problem many times and suggest people DO NOT open CSV files using Excel. If you have to, then import rather than open so you can specify the data types of your numerical columns.
Although this does not provide a technical answer to the problem I was experiencing it might provide a better explanation and help others if they experience this. Some of the example csv files sent to me for testing had been edited in Excel to make the csv smaller and then saved. After further testing, it looks like the issue occurs only for the csv files edited in Excel. Tentatively, this solves the problem for me since we won't be downloading the csv files and editing them in Excel, rather pulling them straight from a url. The code I posted above will read a the correct value without notation while for the csv edited in Excel it will only read the value with scientific notation. Unless I am wrong, I assume Excel must add something to edited csv files that prevents the value from being read correctly.

Format number as text in CSV when open in both Excel and Notepad

I received a requirement to save data in CSV file and send it to customers.
Customers use both Excel and Notepad to view this file.
Data look like:
975567EB, 973456CE, 971343C8
And my data have some number end by "E3" like:
98765E3
so when open in Excel, it will change to:
9.8765E+7
I write a program to change this format to text by adding ="98765E3" to this in C#
while(!sr.EndOfStream) {
var line = sr.ReadLine();
var values = line.Split(',');
values[0] = "=" + "\"" + values[0] + "\""; //Change number format to string
listA.Add(new string[] {values[0], values[1], values[2], values[3]});
}
But with customer, who use Notepad to open CSV file, it will show like:
="98765E3"
How could I save number as text in CSV to open in both Excel and Notepad with the same result? Greatly appreciate any suggestion!
Don't Shoot the messenger.
Your problem is not the way you are exporting (creating...?) data in C#. It is with the way that you are opening the CSV files in Excel.
Excel has numerous options for importing text files that allow for the use of a FieldInfo parameter that specifies the TextFileColumnDataTypes property for each field (aka column) of data being brought in.
If you chose to double-click a CSV file from an Explorer folder window then you will have to put up with what Excel 'best-guesses' are your intended field types for each column. It's not going to stop halfway through an import process to ask your opinion. Some common errors include:
An alphanumeric value with an E will often be interpreted as scientific notation.
Half of the DMY dates will be misinterpreted as the wrong MDY dates (or vise-versa). The other half will become text since Excel cannot process something like 14/08/2015 as MDY.
Any value that starts with a + will produce a #NAME! error because Excel thinks you are attempting to bring in a formula with a named quality.
That's a short list of common errors. There are others. Here are some common solutions.
Use Data ► Get External Data ► From Text. Explicitly specify any ambiguous column data type; e.g. 98765E3 as Text, dates as either DMY, MDY, YMD, etc as the case may be. There is even the option to discard a column of useless data.
Use File ► Open ► Text Files which brings you through the same import wizard as the option above. These actions can be recorded for repeated use using either command.
Use VBA's Workbooks.OpenText method and specify each column's FieldInfo position and data type (the latter with a XlColumnDataType constant).
Read the import file into memory and process it in a memory array before dumping it into the target worksheet.
There are less precise solutions that are still subject to some interpretation from Excel.
Use a Range.PrefixCharacter to force numbers with leading zeroes or alphnumeric values that could conceivably be misinterpreted as scientific notation into the worksheet as text.
Use a text qualifier character; typically ASCII character 034 (e.g. ") to wrap values you want to be interpreted as text.
Copy and paste the entire text file into the target worksheet's column A then use the Range.TextToColumns method (again with FieldInfo options available for each column).
These latter two methods are going to cause some odd values in Notepad but Notepad isn't Excel and cannot process a half-million calculations and other operations in several seconds. If you must mash-up the two programs there will be some compromises.
My suggestion is to leave the values as best as they can be in Notepad and use the facilities and processes readily available in Excel to import the data properly.

Writing in an CSV file using C#

I'm looking for a way to write strings in a different cell of a CSV file.
I'm using this program,
private void button1_Click(object sender, EventArgs e)
{
string filePath = #"E:\test.csv";
string a = "a";
string b = "c";
string c = "d";
string d = "d";
File.WriteAllText(filePath, a);
// how can add the other strings in the next cells ?
}
What I need here is to write "a" in the first cell, "b" in the second cell, c ..
CSV is a pretty simple file format, especially if you don't need any cells to contain nested commas. CSV means comma-separated values, so you just need a way to construct a string with commas between each cell. This will work, although it is only for a single line:
File.WriteAllText(filePath, String.Join(",", a, b, c, d));
CSV is absolutely NOT a SIMPLE file format, it is a sufficiently elaborate format that is able to encompass almost any kind of data regardless of shape or size.
The CSV format is capable of dealing with optional parameters vs non optional, data with or without line breaks, and should be able to work with or without field escaping characters in any field without line breaks and is required to have field escaping characters in fields with line breaks.
You should not ever work with CSV files by hand, you should utilize FileHelpers to work with CSV files.
At this point I no longer use FileHelpers as my goto CSV parsing library I use CsvHelper from Josh Close.
If there are only 4 values, and a single row? (Which I assume is not the case?)
string csv = string.Format("{0},{1},{2},{3}\n", a,b,c,d);
File.WriteAllText(filePath, csv);
If the data is based on some sort of collection, give some more info.

Categories