What I'm trying to accomplish
My app generates some tabular data
I want the user to be able to launch Excel and click "paste" to place the data as cells in Excel
Windows accepts a format called "CommaSeparatedValue" that is used with it's APIs so this seems possible
Putting raw text on the clipboard works, but trying to use this format does not
NOTE: I can correctly retrieve CSV data from the clipboard, my problem is about pasting CSV data to the clipboard.
What I have tried that isn't working
Clipboard.SetText()
System.Windows.Forms.Clipboard.SetText(
"1,2,3,4\n5,6,7,8",
System.Windows.Forms.TextDataFormat.CommaSeparatedValue
);
Clipboard.SetData()
System.Windows.Forms.Clipboard.SetData(
System.Windows.Forms.DataFormats.CommaSeparatedValue,
"1,2,3,4\n5,6,7,8",
);
In both cases something is placed on the clipboard, but when pasted into Excel it shows up as one cell of garbarge text: "–§žý;pC¦yVk²ˆû"
Update 1: Workaround using SetText()
As BFree's answer shows SetText with TextDataFormat serves as a workaround
System.Windows.Forms.Clipboard.SetText(
"1\t2\t3\t4\n5\t6\t7\t8",
System.Windows.Forms.TextDataFormat.Text
);
I have tried this and confirm that now pasting into Excel and Word works correctly. In each case it pastes as a table with cells instead of plaintext.
Still curious why CommaSeparatedValue is not working.
The .NET Framework places DataFormats.CommaSeparatedValue on the clipboard as Unicode text. But as mentioned at http://www.syncfusion.com/faq/windowsforms/faq_c98c.aspx#q899q, Excel expects CSV data to be a UTF-8 memory stream (it is difficult to say whether .NET or Excel is at fault for the incompatibility).
The solution I've come up with in my own application is to place two versions of the tabular data on the clipboard simultaneously as tab-delimited text and as a CSV memory stream. This allows the destination application to acquire the data in its preferred format. Notepad and Excel prefer the tab-delimited text, but you can force Excel to grab the CSV data via the Paste Special... command for testing purposes.
Here is some example code (note that WinForms-equivalents from the WPF namespaces are used here):
// Generate both tab-delimited and CSV strings.
string tabbedText = //...
string csvText = //...
// Create the container object that will hold both versions of the data.
var dataObject = new System.Windows.DataObject();
// Add tab-delimited text to the container object as is.
dataObject.SetText(tabbedText);
// Convert the CSV text to a UTF-8 byte stream before adding it to the container object.
var bytes = System.Text.Encoding.UTF8.GetBytes(csvText);
var stream = new System.IO.MemoryStream(bytes);
dataObject.SetData(System.Windows.DataFormats.CommaSeparatedValue, stream);
// Copy the container object to the clipboard.
System.Windows.Clipboard.SetDataObject(dataObject, true);
Use tabs instead of commas. ie:
Clipboard.SetText("1\t2\t3\t4\t3\t2\t3\t4", TextDataFormat.Text);
Just tested this myself, and it worked for me.
I have had success pasting into Excel using \t (see BFree's answer) as column separators and \n as row separators.
I got the most success defeating formatting issues by using a CSV library (KBCsv) to write the data into a CSV file in the temp folder then open it in Excel with Process.Start(). Once it is in Excel the formatting bit is easy(er), copy-paste from there.
string filePath = System.IO.Path.GetTempPath() + Guid.NewGuid().ToString() + ".csv";
using (var streamWriter = new StreamWriter(filePath))
using (CsvWriter csvWriter = new CsvWriter(streamWriter))
{
// optional header
csvWriter.WriteRecord(new List<string>(){"Heading1", "Heading2", "YouGetTheIdea" });
csvWriter.ValueSeparator = ',';
foreach (var thing in YourListOfThings ?? new List<OfThings>())
{
if (thing != null)
{
List<string> csvLine = new List<string>
{
thing.Property1, thing.Property2, thing.YouGetTheIdea
};
csvWriter.WriteRecord(csvLine);
}
}
}
Process.Start(filePath);
BYO Error handing & logging.
Related
I'm generating the head of different CSV files so my users can see the format
var output = new MemoryStream()
var writer = new StreamWriter(output, Encoding.UTF8);
//this function gets the row depending of the enumerator name in this format a;b;c;d
var header = ModelosCsv.GetCsvByEnum("HeadRowFileLoad");
writer.WriteLine(header);
writer.Flush();
output.Position = 0;
return File(output, "application/csv", "format.csv");
The code is creating the CSV correctly but if they open the CSV with excel and save it, excel will overwrite all the ";" for triple spaces.
If I edit the result with notepad++ and put back the ";" excel won't do it again.
I have opened both archives with excel and clicked "save as", the first one (freshly generated by c#) is set as default as "text archive" the second one (edited by notepad++) is set as CSV.
Am I missing something code?
How could I do to stop excel messing up my archives?
I found the solution in this answered question
Export to CSV using MVC, C# and jQuery
var header = ModelosCsv.GetCsvByEnum("HeadRowFileLoad");
return File(new System.Text.UTF8Encoding().GetBytes(header), "application/csv", "format.csv");
This way Excel identifies the archive as CSV and editing wont break the format.
I'm trying to read a file as string. But it seems that the data is corrupted.
string filepaths = Files[0].FullName;
System.IO.StreamReader myFile = new System.IO.StreamReader(filepaths);
string datas = myFile.ReadToEnd();
but in datas, it contains "pk0101" etc instead of original data. I'm doing this so I can replace a placeholder with this string data,datas. And finally when I replace,gets replaced text as 0101 etc. Is it because of the content in datas. How can I read the file as string. Your help will be greatly appreciated. Thank You.
*.docx is a file format which in raw view represents xml document. Take a look here to become more familiar with this format definition.
For working with office formats Microsoft recommends to use Open Xml SDK at DocumentFormat.OpenXml library.
Here is a great article for learning how to work with Word files.
It works as follows:
using (var wordDocument = WordprocessingDocument.Open(string.Empty, false))
{
var body = wordDocument.MainDocumentPart.Document.Body;
var text = body.GetFirstChild<Paragraph>().InnerText;
}
Also, take a look at this SO question: How do I read data from a word with format using the OpenXML Format SDK with c#?
I have this block of code and want to insert headers before it writes. I have tried various ways but it keeps reading and mixing the headers with the data being written to file. I tried adding the heading outside the if block but it still makes no difference, I also tried adding it right after the file is created but same result. I would like to know how to add it without it mixing with the data
using (StreamWriter stream = new StreamWriter("cross_check.xls", true))
{
if (stream == null)
{
MessageBox.Show("File can't be written");
}
else
{
stream.WriteLine();
stream.Write(search.Text);
stream.Write("\t ");
stream.Write(textBox1.Text);
MessageBox.Show("Data Added Successfully");
}
You can include the header when you write data to file. But if you have some existing files which need modification and if the content of your excel file is text contents (which seems to be, based on the question), you can simply use File.ReadAllLines and File.WriteAllLines this way:
var file = #"d:\file.xls";
var lines = System.IO.File.ReadAllLines(file).ToList();
lines.Insert(0, "Some text");
System.IO.File.WriteAllLines(file, lines);
Using File.ReadAllLines you have all lines of your file and you can perform additional processing on file contents too. For example you can split all lines by a delimiter and manipulate each cell or add new columns and so on. Also you can shape the result into a data structure like DataTable and show it in DataGridView to edit them and save them back to the file again.
I have a WPF that reads an excel file and removes hidden characters and writes the data as pipe delimited to a text file. Works pretty good. Now I am trying to keep the cell formatting that excel has. For test purposes I have a zip code field in excel. The cell has value 047300134 and a custom format of 00000-0000. I would like the data written to be 04730-0134. The only process I saw that using String.Format. Here is how I tried to code it.
dfCellFormat = range[NumRow, lngColCnt].DisplayFormat;
strNumberFormat = dfCellFormat.NumberFormat;
strCellData = Convert.ToString(values[NumRow, lngColCnt]);
strNumberFormat = "{0:" + strNumberFormat.Replace("0","#") + "}";
strCellData = String.Format(strNumberFormat, strCellData);
The result is just 047300134, the format is not applied.
Is there a way to accomplish what I am trying to do?
Thank you
I am trying to get the content of attachment. It may be an excel file, Document file or text file whatever it is but I want to store it in database so here I am using this code: -
foreach (FileAttachment file in em.Attachments)// Here em is type of EmailMessage class
{
Console.Write("Hello friends" + file.Name);
file.Load();
var stream = new System.IO.MemoryStream(file.Content);
var reader = new System.IO.StreamReader(stream, UTF8Encoding.UTF8);
var text = reader.ReadToEnd();
reader.Close();
Console.Write("Text Document" + text);
}
So By printing file.name is showing attachment file name but while printing 'text' on the console it is working if the attachment is .txt type but if it is .doc or .xls type then it is showing some symbolic result. I am not getting any text result. Am I doing something wrong or missing something. I want text result of any kind of file attachment . Please help me , I am beginner in C#
What you are seeing is what is actually in the file. Try opening one with Notepad.
There is no built-in way in .NET to show the "text contents" of arbitrary file formats. You'll have to create (preferably using third-party libraries that already solve this problem) some kind of logic that extracts plaintext from rich text documents.
See for example How to extract text from Pdf, Word and Excel documents?, Extract text from pdf and word files, and so on.
First, what do you expect when reading a binary file?
Your result is exactly what is expected. A text file can be shown as a string, but a doc or xls file is a binary file. You will see the binary content of the file. You will need to use a tool/lib to get the text/content from a binary file in human readable format.
TXT type is simple,DOC or XLS are much more complex.You can see TXT because is just text,DOC or XLS or PPT or something else needs to be interpreted by other mechanism.
See,for example,you have different colors or font sizes on a Word document,or a chart in an Excel document,how can you show that in a simple TextBox or RichTextBox?Short answer,you can't.