我正在开发一个应用程序,它将名为scannerDataDataGridView的DataGridView导出到csv文件。
找到一些示例代码来执行此操作,但无法使其正常工作。顺便说一下,我的数据网格没有数据绑定到源。
当我尝试使用Streamwriter只编写列标题时,一切顺利,但是当我尝试导出包含数据的整个数据网格时,我会得到一个执行代码。
System.NullReferenceException:未将对象引用设置为实例 一个对象。在Scanmonitor.Form1.button1_Click(对象发送者, EventArgs e)
这是我的代码,错误在以下行中给出:
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());
}
答案 0 :(得分:31)
LINQ 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()));
}
事实上,c.Value.ToString()
将抛出空值,而c.Value
将正确转换为空字符串。
答案 1 :(得分:16)
DataGridView
的一个鲜为人知的功能是能够以编程方式选择部分或全部DataGridCell,并使用方法DataObject
将它们发送到DataGridView.GetClipboardContent()
。这有什么好处呢?
DataObject
并不只是存储一个对象,而是以各种不同的格式表示该对象。这就是剪贴板能够发挥其魔力的方式;它存储了各种格式,不同的控件/类可以指定它们希望接受的格式。在这种情况下,DataGridView会将选定的单元格作为制表符分隔的文本格式,CSV格式或HTML(*)存储在DataObject中。
可以通过调用DataObject.GetData()
或DataObject.GetText()
方法并指定预定义的数据格式枚举来检索DataObject的内容。在这种情况下,我们希望格式为CSV的TextDataFormat.CommaSeparatedValue,然后我们可以使用System.IO.File
类将该结果写入文件。
(*)实际上,它返回的内容严格来说不是HTML。此格式还包含您不期望的数据标头。虽然标题确实包含HTML的起始位置,但我只是丢弃HTML标记上方的任何内容,例如myString.Substring(IndexOf("<HTML>"));
。
请注意以下代码:
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));
}
现在,还不是更好吗?为什么重新发明轮子?
希望这会有所帮助......
答案 2 :(得分:7)
我知道这可能已经死了但是我做了一个简单的代码,它根据DataGridView对象创建一个CSV,并询问你要保存它的位置。
非常直接,只需粘贴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.");
}
}
编辑:改变了';' ','因为我们正在谈论CSV文件
答案 3 :(得分:2)
发现问题,编码很好,但我有一个空单元格来解决问题。
答案 4 :(得分:2)
你的代码几乎就在那里......但我做了以下修正,效果很好。谢谢你的帖子。
错误:
string[] output = new string[dgvLista_Apl_Geral.RowCount + 1];
校正:
string[] output = new string[DGV.RowCount + 1];
错误:
System.IO.File.WriteAllLines(filename, output, System.Text.Encoding.UTF8);
校正:
System.IO.File.WriteAllLines(sfd.FileName, output, System.Text.Encoding.UTF8);
答案 5 :(得分:2)
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("");
}
答案 6 :(得分:1)
行“csvFileWriter.WriteLine(dataFromGrid);”应该在结束括号下面一行向下移动,否则你会得到很多重复的结果:
for (int i = 1; i <= countColumn; i++)
{
dataFromGrid = dataFromGrid + ',' + dataRowObject.Cells[i].Value.ToString();
}
csvFileWriter.WriteLine(dataFromGrid);
答案 7 :(得分:0)
我认为这对你的SaveToCSV函数是正确的:(否则为空......)
for (int i = 0; i < columnCount; i++)
不是:
for (int i = 1; (i - 1) < DGV.RowCount; i++)