C# Update CSV cell - c#

I'm just starting to code so all help is appreciated I have searched everywhere and couldn't find a way to do this, I need to update a specific cell in an CSV file using a button (for the update) and a combobox (that has the value in this case some names) thanks in advance :)

No need for interops, or other s$!^&... It's .csv, which is essentially text file where data is separated by semicolons and new lines (if not specially formatted)...
First, as #WynDiesel said, try to change data in .csv to some hard-coded value. Let's say you need to change data in cell [X, Y] (X-th column, Y-th row). The easiest (though not most efficient way) of doing this would be reading all lines of the .csv file with StreamReader or using other method and saving those lines to, let's say, string array which we will call rowsArray. Then access Y-th row, split it using semicolon delimiter and save the result to other string array (let's call this one dataArray).
string[] dataArray = string.Split(';', rowsArray[Y]);
Then change X-th value of that dataArray.
dataArray[X] = myNewValue;
After this, do
rowsArray[Y] = string.Join(";", dataArray)`.
Now you only need to write all the data back to the original file.
As for UI thing, just use OnClick event for the button, get the value of ComboBox and use the function we earlier created for writing that value to the .csv file.

Forget about the combobox/UI first.
You'll need to write a piece of code that can take a filename, read all the lines from that file, and then for a certain line in that file, break it down into fields (by a delimeter), then rebuild that line up with the new value you want in, build the file up again, and write it again. Once you have done this, you start building your UI around this.
Start breaking your problem down into smaller problems, and solve the smallest problem first.

You only need Micorosft.Office.Interop.Excel.dll
private void button_Click(object sender, EventArgs e)
{
var fileName = #"myexcel.xlsx";
if (File.Exists(fileName))
{
try
{
var excelApp = new Excel.Application();
var xlWorkBook = excelApp.Workbooks.Open(fileName);
var xlWorkSheet = (Excel.Worksheet)excelApp.ActiveSheet;
xlWorkSheet.Cells[1, "A"] = "Some thing";
xlWorkSheet.Cells[1, "B"] = "Other thing";
xlWorkSheet.SaveAs(fileName);
}
catch (Exception ex)
{
//some error handling;
}
}
}
You can read more about opening/writing/reading excel files here:
https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/interop/how-to-access-office-onterop-objects

Related

Microsoft Open SDK 2.0 to generate excel file using c#

Please refer link for the code i am using to generate excel file from data table. I am able to generate excel file successfully.
But the problem/Challenge/Question is as follows.
I Want to generate column as per the datatype so if Column value contains date the it cell format should be date(dd/mm/yyy) if number then numeric. ans so on...
I have tried to generate excel file as per data format you can see specific methods to generate cell value. But the problem is when user download the file it will gives the warning message that "Excel found unreadable content 'filename'. Do you want to recover the content of this workbook?". I don,t want that warning message should come.
If I am writing everything as text without format then file will open without any warning message and after downloading file, if user tries to format respective column in date or number format then also it will not allow user to format/slice & dice data in excel file.
Reference :- http://www.codeproject.com/Articles/263106/Export-Tabular-Data-in-CSV-and-Excel-Formats-Throu
Please let me know the solution if anybody has.
I am using DocumentFormat.OpenXml.dll
private Cell CreateTextCell(string header, UInt32 index, string text)
{
var cell = new Cell {DataType = CellValues.InlineString, CellReference = header + index};
var istring = new InlineString();
var t = new Text {Text = text};
istring.Append(t);
cell.Append(istring);
return cell;
}
private Cell CreateDateCell(string header, UInt32 index, DateTime sDate)
{
Cell cell = new Cell();
cell.DataType = CellValues.Date;
cell.CellReference = header + index;
cell.StyleIndex = UInt32Value.FromUInt32(14);
cell.CellValue = new CellValue { Text = sDate.ToOADate().ToString() };
return cell;
}
private Cell CreateNumberCell(string header, UInt32 index, string text)
{
Cell cell = new Cell();
cell.DataType = CellValues.Number;
cell.CellReference = header + index;
cell.CellValue = new CellValue(text);
return cell;
}
I have moved to EPPlus .net library to generate excel file and it is very easy to use.
Thanks.
I may not have the complete solution but you can try the below steps to find the root cause:
One of the reasons for unreadable content error (There are many reasons for this but considering that you are just writing from the datatable only).is if there is a mismatch between the StyleIndex/Datatype/Cellvalue format
To identify the root cause you can try:
Create a sample excel and directly write a cell (only a cell) with number, it that goes on fine, try the next datatype one by one.
Next try to write them one after the other.
Do this and sort down the types which are causing problems.
Next try to vary the StyleIndex/cellFormat with that type (you can check for examples online) till the format is fine without error. Once you are good with all types, you can try writing to the entire excel.
You can also use this method if you want to try something new using OpenXML (since you do not have well documented examples for everything Online)
Another way to identify issues is to use Openxml productivity tool and do a validation of the file.

Copy Excel RangeSelection to array in Windows Application

Thanks for any help in advance :)
Context
I am using SpreadsheetGear within my Windows Application and there are certain cases where a user will want to copy data from an open Excel application and paste the two dimensional grid into the SpreadsheetGear object in my application.
Motivation
I'm attempting to acquire information from the data in the clipboard in preparation for the paste to happen. The numbers of rows and columns of the data coming in needs to be determined before the paste happens so that the SpreadsheetGear control and other controls on the page are "ready" for the data.
Problem 1
How do I acquire such data from the Clipboard? I'm using
System.Windows.Forms.Clipboard.GetData(...)
but I'm not sure whether I should indicate the DataFormat to be CommaSeparatedValue (CSV) or Text. Will one way or the other work best? Is there another DataFormat that I am overlooking that could help me out?
Problem 2
I used this statement in the Immediate Window of Visual Studio 2012:
System.Diagnostics.Debug.WriteLine(Clipboard.GetText())
Interestingly, this returned a portion of the data I selected and copied in Excel. Is there a limit to the amount of data that the clipboard can handle from Excel? Or is there a way for my Windows App to help allocate more space on the clipboard, knowing the user is about the select data from Excel and copy that data to the clipboard?
Please let me know if I can provide more clarification. I'm a little lost and not sure about the scope of this issue. Thanks!
Here is what ended up working for me:
try
{
var data = Clipboard.GetDataObject();
var stream = (System.IO.Stream)data.GetData(DataFormats.CommaSeparatedValue);
var enc = new System.Text.UTF8Encoding();
var reader = new System.IO.StreamReader(stream, enc);
string data_csv = reader.ReadToEnd();
string[] data_csv_array = data_csv.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
...
}
catch (Exception e)
{
ErrorHandling.ShowError("There is no data on the Clipboard to paste.");=
}
The "..." indicates that I do something pretty particular with the data once I have it in array form. What I wanted to do was display the portion of my solution that would help people in general with a similar need.

append text to lines in a CSV file

This question seems to have been asked a million times around the web, but I cannot find an answer which will work for me.
Basically, I have a CSV file which has a number of columns (say two). The program goes through each row in the CSV file, taking the first column value, then asks the user for the value to be placed in the second column. This is done on a handheld running Windows 6. I am developing using C#.
It seems a simple thing to do. But I cant seem to add text to a line.
I cant use OleDb, as System.Data.Oledb isnt in the .Net version I am using. I could use another CSV file, and when they complete each line, it writes it to another CSV file. But the problems with that are - The file thats produced at the end needs to contain EVERY line (so what if they pull the batterys out half way). And what if they go back, to continue doing this another time, how will the program know where to start back from.
For every row, open the output file, append the new row to it, and then close the output file. To restart, count the number of rows in the existing output file from the previous run, which will give you your starting in the input file (i.e., skip that number of rows in the input file).
Edit: right at the start, use System.IO.File.Copy to copy the input file to the output file, so you have all the file in case of failure. Now open the input file, read a line, convert it, use File.ReadAllLines to read ALL of the output file into an array, replace the line you have changed at the right index in the array, then use File.WriteAllLines to write out the new output file.
Something like this:
string inputFileName = ""; // Use a sensible file name.
string outputFileName = ""; // Use a sensible file name.
File.Copy(inputFileName, outputFileName, true);
using (StreamReader reader = new StreamReader(inputFileName))
{
string line = null;
int inputLinesIndex = 0;
while ((line = reader.ReadLine()) != null)
{
string convertedLine = ConvertLine(line);
string[] outputFileLines = File.ReadAllLines(outputFileName);
if (inputLinesIndex < outputFileLines.Length)
{
outputFileLines[inputLinesIndex] = convertedLine;
File.WriteAllLines(outputFileName, outputFileLines);
}
inputLinesIndex++;
}
}

Insert data into text file

I want to insert the data at some positions in the text file without actually overwriting on the existing data. I have two text file. "one.txt" file have 1000 lines, "two.txt" file have 10000 lines. I want to read "one.txt" file content and insert into first 1000 lines of "two.txt" file content(Append the content of "one.txt" to the beginning of "two.txt").
Criteria:
Minimum code .
Less Memory consumption(irrespective of programming language )
Performance (will be considered based on size of the file).
just open up a streamreader for the first file, and a stream writer (in append mode) for the second file. As your reading the first 1000 lines from the first file, insert them into the second.
Something like this:
StreamReader sr = new StreamReader("one.txt");
StreamWriter sw = new StreamWriter("two.txt", true); //true for append
index i = 0;
while (i < 1000) {
sw.WriteLine(sr.ReadLine());
i++;
}
You may want to check for end of file on the StreamReader, but this will give you the general idea....
Based on the new information in OP:
You can use this same type of method, but just create a brand new file, reading the data from the first file, followed by the data from the second file. Once it's inside the new file, replace the original "two.txt".
If you're not limited to c# you can just do the following from a windows command line:
copy one.txt + two.txt three.txt
This would create the file you want, but it would be called three.txt. If you must have it in two.txt, you could simply rename two.txt to something else first and then do the copy append with two.txt as the third parm.
If you only have to do this once, here is some code that will do what you want. I did not compile this, but I believe there are no issues.
string[] linesOne = File.ReadAllLines(pathToFile1);
string[] linesTwo = File.ReadAllLines(pathToFile2);
List<string> result = new List<string>();
for(int i=0;i<1000;i++)
{
result.Add(linesOne[i]);
}
result.AddRange(linesTwo);
File.WriteAllLines(pathToFile2, result);
Hope this gets you started.
Bob

Accessing the content of the file

//Introduction
Hey, Welcome.....
This is the tutorial
//EndIntro
//Help1
Select a Stock
To use this software you first need to select the stock. To do that, simply enter the stock symbol in the stock text-box (such as "MSFT").
To continue enter "MSFT" in the stock symbol box.
//EndHelp1
//Help2
Download Stock Data
Next step is to to download the stock data from the online servers. To start the process simply press the "Update" button or hit the <ENTER> key.
After stock data is downloaded the "Refresh" button will appear instead. Press it when you want to refresh the data with the latest quote.
To continue make sure you are online and press the "Update" button
//EndHelp2
First time I want to display the content between //Introduction and //EndIntro then second time the content between //Help1 and //EndHelp1 and so on.
That's a very open-ended question - what sort of file? To read binary data from it you'd usually use:
using (Stream stream = File.OpenRead(filename))
{
// Read from the stream here
}
or
byte[] data = File.ReadAllBytes(filename);
To read text you could use any of:
using (TextReader reader = File.OpenText(filename))
{
// Read from the reader
}
or
string text = File.ReadAllText(filename);
or
string[] lines = File.ReadAllLines(filename);
If you could give more details about the kind of file you want to read, we could help you with more specific advice.
EDIT: To display content from an RTF file, I suggest you load it as text (but be careful of the encoding - I don't know what encoding RTF files use) and then display it in a RichTextBox control by setting the Rtf property. Make the control read-only to avoid the user editing the control (although if the user does edit the control, that wouldn't alter the file anyway).
If you only want to display part of the file, I suggest you load the file, find the relevant bit of text, and use it appropriately with the Rtf property. If you load the whole file as a single string you can use IndexOf and Substring to find the relevant start/end markers and take the substring between them; if you read the file as multiple lines you can look for the individual lines as start/end markers and then concatenate the content between them.
(I also suggest that next time you ask a question, you include this sort of detail to start with rather than us having to tease it out of you.)
EDIT: As Mark pointed out in a comment, RTF files should have a header section. What you've shown isn't really an RTF file in the first place - it's just plain text. If you really want RTF, you could have a header section and then the individual sections. A better alternative would probably be to have separate files for each section - it would be cleaner that way.
Not sure I understand your question correctly. But you can read and write content using System.IO.StreamReader and StreamWriter classes
string content = string.Empty;
using (StreamReader sr = new StreamReader("C:\\sample.txt"))
{
content = sr.ReadToEnd();
}
using (StreamWriter sw = new StreamWriter("C:\\Sample1.txt"))
{
sw.Write(content);
}
Your question needs more clarification. Look at System.IO.File for many ways to read data.
The easiest way of reading a text file is probably this:
string[] lines = File.ReadAllLines("filename.txt");
Note that this automatically handles closing the file so no using statement is need.
If the file is large or you don't need all lines you might prefer to reading the text file in a streaming manner:
using (StreamReader streamReader = File.OpenText(path))
{
while (true)
{
string line = streamReader.ReadLine();
if (line == null)
{
break;
}
// Do something with line...
}
}
If the file contains XML data you might want to open it using an XML parser:
XDocument doc = XDocument.Load("input.xml");
var nodes = doc.Descendants();
There are many, many other ways to read data from a file. Could you be more specific about what the file contains and what information you need to read?
Update: To read an RTF file and display it:
richTextBox.Rtf = File.ReadAllText("input.rtf");

Categories