I am exporting a csv file and getting the date field and phone number field masked as shown in the image below. The problem occurs only when I open the exported file in Microsoft Excel not on other platforms
What I want to do is remove the mask and show the birth date and number properly as: birth date: "12/11/2016" and number as "123456789".
Note: birth date is datetime AND cell_phone or mobile number is string
The code I used to create this is as follows:
foreach (EmployeeDataExportObject item1 in _obj_distinct_company)
{
sb.Append(string.Format("{0},{1},{2},{3},{4},{5},{6},{7},{8},{9},{10},{11},{12},{13},{14},{15},{16},{17},{18},{19},{20},{21}"
, item1.client_id
, item1.employee_number
, item1.employee_status_type
, item1.first_name.Replace(",", "")
, item1.middle_name.Replace(",", "")
, item1.last_name.Replace(",", "")
, '"' + item1.ssn.ToString() + '"'
, '"' + birth_date.ToString("MM-dd-yyyy") + '"' //problem is on this part
, Address.Replace(",", "")
, item1.address2.Replace(",", "")
, item1.city
, item1.state
, item1.zip_code
, item1.country
, '"' + item1.cell_phone.ToString().Replace("-", "").Replace("(", "").Replace(")", "").Replace(".", "").Replace(" ", "") + '"' //problem is on this part
, item1.pay_rate1
, item1.pay_rate_amount1.ToString("0.00")
, item1.pay_rate2
, item1.pay_rate_amount2.ToString("0.00")
, item1.employee_status_type
, item1.termination_reason.Replace(",", " ")
, item1.termination_date.ToString("MM-dd-yyyy"))
+ Environment.NewLine);
}
_fileName = item.company_name;
if (!Directory.Exists(paychex_folder))
Directory.CreateDirectory(paychex_folder);
filepath = paychex_folder + _fileName + ".csv";
File.WriteAllText(filepath, sb.ToString());
}
What do you mean by masked, can you attach a screenshot of the excel file?
If a column with a date in is not wide enough, the value is shown as ###### - is this the problem you are having?
It's actually easier to create an XLSX file using a library like EPPLus. XSLX files are zipped XML files which can be generated without having Excel installed. With EPPlus you can fill a sheet with data from a DataTable or collection with a simple call to LoadFromDatatable or LoadFromCollection, eg:
FileInfo targetFile = new FileInfo(targetFile);
using (var excelFile = new ExcelPackage(targetFile))
{
var sheet = excelFile.Workbook.Worksheets.Add("Sheet1");
sheet.LoadFromCollection(_obj_distinct_company, PrintHeaders: true);
excelFile.Save();
}
EPPlus takes care to serialize dates in the decimal format (OA Date) expected by Excel.
LoadFromCollection returns an ExcelRange object which you can use to further format rows and columns, or create a named table, eg:
var range1=sheet.LoadFromCollection(_obj_distinct_company, PrintHeaders: true);
var table = sheet.Tables.Add(range, "Companies");
table.TableStyle = TableStyles.Light2;
Related
When I insert in DB a string that contains special character as a "à" or a "é" from a FileInfo.GetFiles() item, I get issues and SQL save splitted special char. Non-special chars are OK.
For instance, "à" becomes "a`", and "é" becomes "e´". Did anyone get this kind of trouble?
Here is the code
DirectoryInfo di = new DirectoryInfo(path);
foreach (FileInfo fi in di.GetFiles())
{
Logger.LogInfo("Info: " + fi.Name);
}
Basically, if string is "sàrl", log saved "Info: sa`rl"
When I breakpoint trough VS, I see the string with "à" but when I log it, char are splitted.
My SQL collation is Latin CI AS (SQL_Latin1_General_CP1_CI_AS) and DB already host string with special char without problem.
Thanks folks
EDIT
I have trouble when I insert the fi.Name into the final table too:
public bool InsertFile(string fileName, Societe company, string remark, PersonnelAM creator)
{
string commandText = (#"INSERT INTO [dbo].[TB_DOCSOCIETE_COM] " +
"([IdtSOC] " +
",[NomDOC] " +
",[RemDOC] " +
",[DateDOC] " +
",[IdtPER]) " +
"VALUES " +
"(#company" +
",#fileName" +
",#remark" +
",#date" +
",#creator) SELECT ##IDENTITY");
var identity = CreateCommand(commandText,
new SqlParameter("#fileName", DAOHelper.HandleNullValueAndMinDateTime<string>(fileName)),
new SqlParameter("#company", DAOHelper.HandleNullValueAndMinDateTime<int>(company.Id)),
new SqlParameter("#remark", DAOHelper.HandleNullValueAndMinDateTime<string>(remark)),
new SqlParameter("#date", DAOHelper.HandleNullValueAndMinDateTime<DateTime>(DateTime.Now)),
new SqlParameter("#creator", DAOHelper.HandleNullValueAndMinDateTime<int>(creator.id))
).ExecuteScalar();
return int.Parse(identity.ToString()) > 0;
}
I'm using NLog so data is varchar(8000) for message column and code that logs message is
public static bool LogInfo(Exception ex, string message = "")
{
try
{
GetLogger().Log(LogLevel.Info, ex, message);
}
#pragma warning disable 0168
catch (Exception exception)
#pragma warning restore 0168
{
return false;
}
return true;
}
EDIT 2 :
To be clear about DB, those 3 lines:
Logger.LogInfo("BL1 " + "sàrl is right saved");
Logger.LogInfo("BL2 " + fi.Name + " is not right saved");
Logger.LogInfo("BL3 " + "sàrl" + " - " + fi.Name + " is not right too!");
Gave me that result in DB:
BL1 sàrl is right saved
BL2 ENTERPRISE Sa`rl - file.pdf is not right saved
BL3 sàrl - ENTERPRISE Sa`rl - file.pdf is not right too!
So it doesn't come from DB, it is an issue about the string (encoding?)
varchar(8000)
Make the column NVARCHAR. This is not a collation issue. Collations determine the sort order and comparison rules, not the storage. Is true that for non-unicode columns (varchar) the collation is used as hint to determine the code page of the result. But code page will only get you so far, as obviously a 1 byte encoding code page cannot match the entire space of the file system naming, which is 2 bytes encoding Unicode based.
Use an Unicode column: NVARCHAR.
If you want to understand what are you experiencing, just run this:
declare #a nvarchar(4000) = NCHAR(0x00E0) + N'a' + NCHAR(0x0300)
select #a, cast(#a as varchar);
Unicode is full of wonderful surprises, like Combining characters. You can't distinguish them visually, but they sure show up when you look at the actual encoded bytes.
Currently I am attempting to create a dictionary which maps a selected item form a list view with a corresponding string output in a rich text box. I would like to bold specific text in the string, which will always be the same (constant) and also adding dynamic text to the string that would change.
Something like this:
ID: 8494903282
Where ID is the constant text I need bolded and the numbers would be a dynamic ID that changes. I will need to have multiple lines with different data in this format which will be changing:
ID: 8494903282
Name: Some Name
Date: 3/15/2018
Currently I have a rich text box to output to and I am trying to use some string formatting to do what I want but this is not working correctly. Essentially I need a string value I can store in a dictionary so when an item gets selected I can just set the rtf property of the text box to the value of that dictionary item.
Below I have my current format string I am attempting to set the rtf property to:
string s1 = string.Format(#"{{\rtf1\ansi \b Commit ID: \b0 {0}\line}}", entry.ID);
string s2 = string.Format(#"{{\b Author: \b0 {0}\line}}", entry.Author);
string s3 = string.Format(#"{{\b Date: \b0 {0}\line}}", entry.Date.ToString("d"));
string s4 = Environment.NewLine + Environment.NewLine + entry.Message;
contents = (s1 + s2 + s3 + s4);
Then setting the rtf property of my rich text box:
LogContentsTB.Rtf = Logs[LogNamesLV.SelectedItems[0].Name];
Where logs is a dictionary of the form < string, string > that holds the format string for the specific item.
However, I get the following output rather than my expected output:
This is the correct form of output for the first item but nothing else appears. If there are any other ways to do this I am open to suggestion.
After doing some light reading on the rtf syntax I noticed that I was trying to close off each string with curly braces. Curly braces are used for RTF groups. For some reason the rich text box in windows forms did not play well with that.
Another thing to notice is that the string.format method was probably the main culprit for cause of issues with this type of formatting. In my answer I do not use it but rather just add the string directly into the rtf formatted string i.e. < format >< variable string >< ending format >
If you look at NetMage's response, you will notice he only puts an opening brace on the very first string, s1. This is to group the whole string. But we need to add a closing brace on the final string, s4, to finish the grouping. Below is the final code and screenshot that worked for my application.
string s1 = #"{\rtf1\ansi\b ID: \b0 " + entry.ID + #" \line\line";
string s2 = #"\b Author: \b0 " + entry.Author + #" \line\line";
string s3 = #"\b Date: \b0 " + entry.Date.ToString("d") + #" \line\line ";
string s4 = entry.Message + #"}";
contents = s1 + s2 + s3 + s4;
Thanks for pointing me in the right direction!
I think your RTF formatting is wrong. You could try:
string s1 = string.Format(#"{{\rtf1\ansi\r\b Commit ID:\b0 {0}\line\r", entry.ID);
string s2 = string.Format(#"\b Author: \b0 {0}\line\r", entry.Author);
string s3 = string.Format(#"\b Date: \b0 {0}\line\r", entry.Date.ToString("d"));
string s4 = Environment.NewLine + Environment.NewLine + entry.Message + "}}";
contents = (s1 + s2 + s3 + s4);
I have a program where I run a query and store data in a DataTable. I then allow the user to save that DataTable.WriteXML. The problem I have is that I want to read that saved file (XML file) into another DataTable with a different name - and it does not allow it! It gives me an error "Error while loading Results Table to File: Data Table: 'ImportTable' does not match to any DataTable in Source"
Now I believe this message is telling me that the XML contains a different table name than the DataTable I am trying to ReadXML into it. I have tried setting the TableName property to blank - but that does not make any difference.
So - my question is how do others get around this issue? I am using the standard DataTable.WriteXML(filename) - and DataTable.ReadXML method calls. AND due to some design issues - I do need to have the import DataTable named differently than the one used to export the data.
Is there a different way to write out and read in the data in the DataTable that will get around this issue?
Sample code - showing the issue
In the form load - create two tables - one named Export the other Import. Create a structure for Export - and populate it with 10 records.
private void Form_Main_Load(object sender, EventArgs e)
{
ExportTable = new DataTable("Export");
ImportTable = new DataTable("Import");
ExportTable.Columns.Add("ID", Type.GetType("System.Int32"));
ExportTable.Columns.Add("Name", Type.GetType("System.String"));
ExportTable.Columns.Add("Amount", Type.GetType("System.Int32"));
// Populate the first one
DataRow workRow;
for (int i = 0; i <= 9; i++)
{
workRow = ExportTable.NewRow();
workRow[0] = i;
workRow[1] = "CustName" + i.ToString();
workRow[2] = i;
ExportTable.Rows.Add(workRow);
}
}
Then create two buttons - one for exporting the data - the other for importing the data.
private void button_Export_Click(object sender, EventArgs e)
{
ExportTable.WriteXml("c:\\Temp\\TableOut.xml");
}
private void button_Import_Click(object sender, EventArgs e)
{
ImportTable.ReadXmlSchema("c:\\Temp\\TableOut.xml");
ImportTable.ReadXml("c:\\Temp\\TableOut.xml");
}
Run the program - export the data - then click on the Import button. When you do - you will get the error - "DataTable 'Import' does not match to any DataTable in source."
Now - I realize it is because the XML has the Export table name embedded in the XML. In my case I need to import that data into a DataTable with a different name - and I am wondering how (and if) others have dealt withi this in the past? Did you manually change the name in the XML? Did you temporarily change the datatable name? OR is there another better way around this issue of trying to use the READXML method of a DataTable?
Ok - I have been playing around with this - and have a solution. Not sure it is the best (and I would appreciate any comments as to how I might do this better).
Basically what I had to do was write the XML out to a string reader - change the table name for the schema and the record elements. Both the <> and tags.
Then when I read it in - I had to do the reverse - basically read the file into a string - then change all the table names back to what I needed them to be. Then I had to write the file out to disk (temporary file) - and then use the ReadXML method to read that temp file and then delete the file.
I am not sure why the ReadXML with a string reader did not work (it seems to be a valid parameter) - but I had found a few posts that stated there were issues with the READXML method and string readers - so I simply wrote it out to file and used READXML with the file name - and it worked fine.
I hope this helps others - even if it is not the 'best' solution - maybe someone else can improve on it.
Write XML
// Write XML
StringWriter sw = new StringWriter();
ResultDT.WriteXml(sw, XmlWriteMode.WriteSchema);
string OutputXML = sw.ToString();
// now replace the Table Name
OutputXML = OutputXML.Replace("<" + ResultDT.TableName + ">", "<" + "ExportTable" + ">");
OutputXML = OutputXML.Replace("</" + ResultDT.TableName + ">", "</" + "ExportTable" + ">");
OutputXML = OutputXML.Replace("MainDataTable=\"" + ResultDT.TableName + "\"", "MainDataTable=\"" + "ExportTable" + "\"");
OutputXML = OutputXML.Replace("name=\"" + ResultDT.TableName + "\"", "name=\"" + "ExportTable" + "\"");
System.IO.File.WriteAllText(fileName, OutputXML);
Read XML
// Read XML
InputXML = System.IO.File.ReadAllText(fileName);
// now replace the Table Name
InputXML = InputXML.Replace("<" + "ExportTable" + ">", "<" + ResultTable.TableName + ">");
InputXML = InputXML.Replace("</" + "ExportTable" + ">", "</" + ResultTable.TableName + ">");
InputXML = InputXML.Replace("MainDataTable=\"" + "ExportTable" + "\"", "MainDataTable=\"" + ResultTable.TableName + "\"");
InputXML = InputXML.Replace("name=\"" + "ExportTable" + "\"", "name=\"" + ResultTable.TableName + "\"");
string TempFileName = "TempDumpFile.idt";
System.IO.File.WriteAllText(TempFileName, InputXML);
ResultTable.ReadXmlSchema(TempFileName);
ResultTable.ReadXml(TempFileName);
System.IO.File.Delete(TempFileName);
I am making a program to manage different projects for a company, the idea is that you put some info and it writes it into an excel file.
The excel files are names ("FINANZAS - ") + Current Year
The idea is that it detects the current year with DateTime and if the excel file for that year doesnt exists it creates it. This is my code:
MyApp = new Excel.Application();
MyApp.Visible = false;
if (!File.Exists("FINANZAS - " + DateTime.Now.Year.ToString() + ".xlsx")) { File.Copy(rutaPlantilla, "FINANZAS ARAINCO - " + DateTime.Now.Year.ToString() + ".xlsx"); }
MyBook = MyApp.Workbooks.Open(#"C:\Users\Sebastian\Documents\Visual Studio 2015\Projects\Finanzas ARAINCO\Finanzas ARAINCO\bin\Debug\FINANZAS ARAINCO - " + DateTime.Now.Year.ToString() + ".xlsx");
MySheet = (Excel.Worksheet)MyBook.Sheets[1];
lastRow = MySheet.Cells.SpecialCells(Excel.XlCellType.xlCellTypeLastCell).Row + 1;
The problem comes when I try changing the date to test it with other years, I tried switching it to 2018 for testing but it throws me a TargetInvocationException on the last row (the one that, ironically, I use to detect the last row on excel)
I dont know if this is caused by something on the excel part of the code or if it has something to do with changing the date manually to 2018
I am currently developing an application in C# where I need to write a tab separated CSV file from the data that it retrieves from a MySQL Database. The database retrieval works fine.
The problem that I am having is writing the file. Between each variable that I am writing I am using the \t which I thought put a tab into the csv, therefore when opening in excel each variable will be in its own cell.
However for some reason it is not doing this it just writes the whole line as one long string. Below is an example of the code that I am code that I have written:
while (reader.Read())
{
int bankID = reader.GetInt16("ban_bankID");
int userID = reader.GetInt16("ban_userID");
string bankUsername = reader.GetString("ban_username");
string accountName = reader.GetString("ban_accountName");
string accountType = reader.GetString("ban_accountType");
decimal overdraft = reader.GetDecimal("ban_overdraft");
char defaultAccount = reader.GetChar("ban_defaultAccount");
string line = bankID + "\t" + userID + "\t" + bankUsername + "\t" + accountName + "\t"
+ accountType + "\t" + overdraft + "\t" + defaultAccount + "\n";
tw.WriteLine(line);
Thanks for your help with this problem.
The format is correct, a CSV expects the file to be COMMA Separated. When saving a Tab delimited file, typically just a txt extension is used (or some people save as .tsv) etc.
If you look at the Save As options in excel the option is Text (Tab Delimited) .txt
If I open the output generated by your sample code (stubbing in the data) everything loads in to Excel 2007 as you would expect.
The problem is your encoding.
You don't show your TextWriter instantiation, but it should look something like this:
TextWriter tw = new Stream(filename, false, Encoding.ASCII);
You should use the Text Import Wizard: Data / From Text. From there you can specify your delimiter to a tab.