C# 将数据网格视图导出到 csv 文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9943787/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Exporting datagridview to csv file
提问by PandaNL
I'm working on a application which will export my DataGridView called scannerDataGridView to a csv file.
我正在开发一个应用程序,它将我的 DataGridView 称为scannerDataGridView 导出到一个 csv 文件。
Found some example code to do this, but can't get it working. Btw my datagrid isn't databound to a source.
找到了一些示例代码来执行此操作,但无法使其正常工作。顺便说一句,我的数据网格不是数据绑定到源。
When i try to use the Streamwriter to only write the column headers everything goes well, but when i try to export the whole datagrid including data i get an exeption trhown.
当我尝试使用 Streamwriter 只写入列标题时一切顺利,但是当我尝试导出包括数据在内的整个数据网格时,我得到了一个例外。
System.NullReferenceException: Object reference not set to an instance of an object. at Scanmonitor.Form1.button1_Click(Object sender, EventArgs e)
System.NullReferenceException:未将对象引用设置为对象的实例。在 Scanmonitor.Form1.button1_Click(Object sender, EventArgs e)
Here is my Code, error is given on the following line:
这是我的代码,以下行给出了错误:
dataFromGrid = dataFromGrid + ',' + dataRowObject.Cells[i].Value.ToString();
dataFromGrid = dataFromGrid + ',' + dataRowObject.Cells[i].Value.ToString();
//csvFileWriter = StreamWriter
//scannerDataGridView = DataGridView
private void button1_Click(object sender, EventArgs e)
{
string CsvFpath = @"C:\scanner\CSV-EXPORT.csv";
try
{
System.IO.StreamWriter csvFileWriter = new StreamWriter(CsvFpath, false);
string columnHeaderText = "";
int countColumn = scannerDataGridView.ColumnCount - 1;
if (countColumn >= 0)
{
columnHeaderText = scannerDataGridView.Columns[0].HeaderText;
}
for (int i = 1; i <= countColumn; i++)
{
columnHeaderText = columnHeaderText + ',' + scannerDataGridView.Columns[i].HeaderText;
}
csvFileWriter.WriteLine(columnHeaderText);
foreach (DataGridViewRow dataRowObject in scannerDataGridView.Rows)
{
if (!dataRowObject.IsNewRow)
{
string dataFromGrid = "";
dataFromGrid = dataRowObject.Cells[0].Value.ToString();
for (int i = 1; i <= countColumn; i++)
{
dataFromGrid = dataFromGrid + ',' + dataRowObject.Cells[i].Value.ToString();
csvFileWriter.WriteLine(dataFromGrid);
}
}
}
csvFileWriter.Flush();
csvFileWriter.Close();
}
catch (Exception exceptionObject)
{
MessageBox.Show(exceptionObject.ToString());
}
采纳答案by PandaNL
Found the problem, the coding was fine but i had an empty cell that gave the problem.
发现了问题,编码很好,但我有一个空单元格出现了问题。
回答by l0calh0st
The line "csvFileWriter.WriteLine(dataFromGrid);" should be moved down one line below the closing bracket, else you'll get a lot of repeating results:
“csvFileWriter.WriteLine(dataFromGrid);”这一行 应该在结束括号下向下移动一行,否则你会得到很多重复的结果:
for (int i = 1; i <= countColumn; i++)
{
dataFromGrid = dataFromGrid + ',' + dataRowObject.Cells[i].Value.ToString();
}
csvFileWriter.WriteLine(dataFromGrid);
回答by Jonathan
LINQ FTW!
林克FTW!
var sb = new StringBuilder();
var headers = dataGridView1.Columns.Cast<DataGridViewColumn>();
sb.AppendLine(string.Join(",", headers.Select(column => "\"" + column.HeaderText + "\"").ToArray()));
foreach (DataGridViewRow row in dataGridView1.Rows)
{
var cells = row.Cells.Cast<DataGridViewCell>();
sb.AppendLine(string.Join(",", cells.Select(cell => "\"" + cell.Value + "\"").ToArray()));
}
And indeed, c.Value.ToString()will throw on null value, while c.Valuewill correctly convert to an empty string.
事实上,c.Value.ToString()会抛出空值,而c.Value会正确转换为空字符串。
回答by Adam White
A little known feature of the DataGridViewis the ability to programmatically select some or all of the DataGridCells, and send them to a DataObjectusing the method DataGridView.GetClipboardContent(). Whats the advantage of this then?
的一个鲜为人知的功能DataGridView是能够以编程方式选择部分或全部 DataGridCells,并DataObject使用 方法将它们发送到DataGridView.GetClipboardContent()。那这有什么好处呢?
A DataObjectdoesn't just store an object, but rather the representation of that object in various different formats. This is how the Clipboard is able to work its magic; it has various formats stored and different controls/classes can specify which format they wish to accept. In this case, the DataGridView will store the selected cells in the DataObject as a tab-delimited text format, a CSV format, or as HTML (*).
ADataObject不只是存储一个对象,而是该对象以各种不同格式的表示。这就是剪贴板能够发挥其魔力的方式;它存储了各种格式,不同的控件/类可以指定他们希望接受的格式。在这种情况下,DataGridView 会将选定的单元格以制表符分隔的文本格式、CSV 格式或 HTML (*) 格式存储在 DataObject 中。
The contents of the DataObject can be retrieved by calling the DataObject.GetData()or DataObject.GetText()methods and specifying a predefined data format enum. In this case, we want the format to be TextDataFormat.CommaSeparatedValue for CSV, then we can just write that result to a file using System.IO.Fileclass.
可以通过调用DataObject.GetData()或DataObject.GetText()方法并指定预定义的数据格式枚举来检索 DataObject 的内容。在这种情况下,我们希望格式为 TextDataFormat.CommaSeparatedValue for CSV,然后我们可以使用System.IO.Fileclass将该结果写入文件。
(*) Actually, what it returns is not, strictly speaking, HTML. This format will also contain a data header that you were not expecting. While the header does contain the starting position of the HTML, I just discard anything above the HTML tag like myString.Substring(IndexOf("<HTML>"));.
(*) 实际上,严格来说,它返回的不是HTML。此格式还将包含您不期望的数据标头。虽然标题确实包含 HTML 的起始位置,但我只是丢弃了 HTML 标记上方的任何内容,例如myString.Substring(IndexOf("<HTML>"));.
Observe the following code:
观察以下代码:
void SaveDataGridViewToCSV(string filename)
{
// Choose whether to write header. Use EnableWithoutHeaderText instead to omit header.
dataGridView1.ClipboardCopyMode = DataGridViewClipboardCopyMode.EnableAlwaysIncludeHeaderText;
// Select all the cells
dataGridView1.SelectAll();
// Copy selected cells to DataObject
DataObject dataObject = dataGridView1.GetClipboardContent();
// Get the text of the DataObject, and serialize it to a file
File.WriteAllText(filename, dataObject.GetText(TextDataFormat.CommaSeparatedValue));
}
Now, isn't that better? Why re-invent the wheel?
现在,那不是更好吗?为什么要重新发明轮子?
Hope this helps...
希望这可以帮助...
回答by José Algarra
I know this is probably already dead but I made a simple code that creates a CSV based on a DataGridView object and asks where you want to save it.
我知道这可能已经死了,但我制作了一个简单的代码,它基于 DataGridView 对象创建一个 CSV 并询问您要将它保存在哪里。
Its pretty straight forward, just paste de function and use it. It already has some basic exception handling so is pretty safe to use. enjoy.
它非常简单,只需粘贴 de 函数并使用它。它已经有一些基本的异常处理,所以使用起来非常安全。请享用。
private void SaveToCSV(DataGridView DGV)
{
string filename = "";
SaveFileDialog sfd = new SaveFileDialog();
sfd.Filter = "CSV (*.csv)|*.csv";
sfd.FileName = "Output.csv";
if (sfd.ShowDialog() == DialogResult.OK)
{
MessageBox.Show("Data will be exported and you will be notified when it is ready.");
if (File.Exists(filename))
{
try
{
File.Delete(filename);
}
catch (IOException ex)
{
MessageBox.Show("It wasn't possible to write the data to the disk." + ex.Message);
}
}
int columnCount = DGV.ColumnCount;
string columnNames = "";
string[] output = new string[DGV.RowCount + 1];
for (int i = 0; i < columnCount; i++)
{
columnNames += DGV.Columns[i].Name.ToString() + ",";
}
output[0] += columnNames;
for (int i = 1; (i - 1) < DGV.RowCount; i++)
{
for (int j = 0; j < columnCount; j++)
{
output[i] += DGV.Rows[i - 1].Cells[j].Value.ToString() + ",";
}
}
System.IO.File.WriteAllLines(sfd.FileName, output, System.Text.Encoding.UTF8);
MessageBox.Show("Your file was generated and its ready for use.");
}
}
EDIT: changed ';' to ',' since we are talking about CSV files
编辑:改变了';' 到 ',' 因为我们在谈论 CSV 文件
回答by GSIT Coder
Your code was almost there... But I made the following corrections and it works great. Thanks for the post.
你的代码就快到了……但我做了以下更正,效果很好。谢谢你的帖子。
Error:
错误:
string[] output = new string[dgvLista_Apl_Geral.RowCount + 1];
Correction:
更正:
string[] output = new string[DGV.RowCount + 1];
Error:
错误:
System.IO.File.WriteAllLines(filename, output, System.Text.Encoding.UTF8);
Correction:
更正:
System.IO.File.WriteAllLines(sfd.FileName, output, System.Text.Encoding.UTF8);
回答by threefx
I think this is the correct for your SaveToCSV function : ( otherwise Null ...)
我认为这对您的 SaveToCSV 函数是正确的:(否则为 Null ...)
for (int i = 0; i < columnCount; i++)
Not :
不是 :
for (int i = 1; (i - 1) < DGV.RowCount; i++)
回答by Manish sharma
Please check this code.its working fine
try
{
//Build the CSV file data as a Comma separated string.
string csv = string.Empty;
//Add the Header row for CSV file.
foreach (DataGridViewColumn column in dataGridView1.Columns)
{
csv += column.HeaderText + ',';
}
//Add new line.
csv += "\r\n";
//Adding the Rows
foreach (DataGridViewRow row in dataGridView1.Rows)
{
foreach (DataGridViewCell cell in row.Cells)
{
if (cell.Value != null)
{
//Add the Data rows.
csv += cell.Value.ToString().TrimEnd(',').Replace(",", ";") + ',';
}
// break;
}
//Add new line.
csv += "\r\n";
}
//Exporting to CSV.
string folderPath = "C:\CSV\";
if (!Directory.Exists(folderPath))
{
Directory.CreateDirectory(folderPath);
}
File.WriteAllText(folderPath + "Invoice.csv", csv);
MessageBox.Show("");
}
catch
{
MessageBox.Show("");
}

