ScannerDataGridViewという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());
}
問題が見つかりました。コーディングは問題ありませんでしたが、問題のある空のセルがありました。
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()
はnull値をスローしますが、_c.Value
_は空の文字列に正しく変換されます。
DataGridView
のあまり知られていない機能は、DataGridCellの一部またはすべてをプログラムで選択し、メソッドDataGridView.GetClipboardContent()
を使用してDataObject
に送信する機能です。この利点は何ですか?
DataObject
はオブジェクトを保存するだけでなく、そのオブジェクトのさまざまな形式での表現を保存します。これが、クリップボードの魔法の働きです。さまざまな形式が保存されており、さまざまなコントロール/クラスがどの形式を受け入れるかを指定できます。この場合、DataGridViewは、選択されたセルをタブ区切りテキスト形式、CSV形式、またはHTML(*)としてDataObjectに保存します。
DataObjectの内容は、DataObject.GetData()
またはDataObject.GetText()
メソッドを呼び出して、事前定義されたデータ形式の列挙を指定することで取得できます。この場合、CSVの形式をTextDataFormat.CommaSeparatedValueにしたいので、System.IO.File
_クラスを使用してその結果をファイルに書き込むことができます。
(*)実際には、返されるのは厳密にはHTMLではありません。この形式には、予期しないデータヘッダーも含まれます。ヘッダーにはHTMLの開始位置が含まれていますが、 myString.Substring(IndexOf("<HTML>"));
のような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));
}
_
さて、それは良くないですか?なぜ車輪を再発明するのですか?
お役に立てれば...
私はこれがおそらくすでに死んでいることを知っていますが、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ファイルについて話しているため、「、」に
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("");
}
あなたのコードはほとんどそこにありました...しかし、私は次の修正を行いました。投稿いただきありがとうございます。
エラー:
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);
行「csvFileWriter.WriteLine(dataFromGrid);」閉じ括弧の下の1行下に移動する必要があります。そうしないと、多くの繰り返し結果が得られます。
for (int i = 1; i <= countColumn; i++)
{
dataFromGrid = dataFromGrid + ',' + dataRowObject.Cells[i].Value.ToString();
}
csvFileWriter.WriteLine(dataFromGrid);
これはSaveToCSV関数にとって正しいと思います:(そうでなければNull ...)
for (int i = 0; i < columnCount; i++)
しない:
for (int i = 1; (i - 1) < DGV.RowCount; i++)