[英]Delete row in a CSV file and show in DataGridView using c#
我要删除CSV文件中的行时遇到问题,我有此代码,但只删除包含该行的字段。
例:
CSV档案:
ID,Name,Lastname,Country
1,David,tod,UK
2,Juan,Perez,Germ
3,Pepe,Lopez,Col
第一次迭代,发送ID 1以删除该行:
ID,Name,Lastname,Country
David,tod,UK
2,Juan,Perez,Germ
3,Pepe,Lopez,Arg
只需删除我想要的ID,但不要删除整行
预期的结果将是这样的:
ID,Name,Lastname,Country
2,Juan,Perez,Arg
3,Pepe,Lopez,Col
这是我的代码,我在做什么错? 我从未在C#中使用过csv :(
string searchid = "1";
string[] values = File.ReadAllText("C:\\registros.csv").Split(new char[] { ',' });
StringBuilder ObjStringBuilder = new StringBuilder();
for (int i = 0; i < values.Length; i++)
{
if (values[i].Contains(searchid))
continue;
ObjStringBuilder.Append(values[i] + ",");
}
ObjStringBuilder.ToString().Remove(ObjStringBuilder.Length - 1);
File.WriteAllText("\\registros.csv", ObjStringBuilder.ToString());
另一个问题是如何在Windows窗体的datagridview中显示CSV文件。 我有这个逻辑,不知道这是否正确,但是我怎么显示呢?
public DataTable ConvertCSVtoDataTable()
{
StreamReader sr = new StreamReader("\\registros.csv");
string[] headers = sr.ReadLine().Split(',');
DataTable dt = new DataTable();
foreach (string header in headers)
{
dt.Columns.Add(header);
}
while (!sr.EndOfStream)
{
string[] rows = Regex.Split(sr.ReadLine(), ",(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)");
DataRow dr = dt.NewRow();
for (int i = 0; i < headers.Length; i++)
{
dr[i] = rows[i];
}
dt.Rows.Add(dr);
}
return dt;
}
谢谢!
您可以使用以下链接从CSV删除行
和
您可以使用以下代码将CSV转换为DataTable。 如果您的csv文件使用定界符作为,
public DataTable ReadCSV(String FilePath, Boolean IsHeader)
{
string strConn = null;
string folderpath = null;
try
{
folderpath = FilePath.Substring(0, FilePath.LastIndexOf("\\") + 1);
string FileName = Path.GetFileName(FilePath);
if (IsHeader == true)
{
strConn = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=" + folderpath + ";" + "Extended Properties=\"text;HDR=YES\"";
}
else
{
strConn = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=" + folderpath + ";" + "Extended Properties=\"text;HDR=NO\"";
}
OleDbConnection Conn = new OleDbConnection();
Conn.ConnectionString = strConn;
Conn.Open();
string s1 = "select * from [" + FileName + "]";
OleDbDataAdapter da1 = new OleDbDataAdapter(s1, Conn);
DataSet dtall = new DataSet();
da1.Fill(dtall);
Conn.Close();
return dtall.Tables[0].Copy();
}
catch (Exception ex)
{
Exception excep = new Exception("CSV : " + ex.Message);
throw excep;
}
}
实现的第一件事是使用“,”作为分隔符。 您应该分割换行符'\\ n'或逐行读取文件,如下所示:
var lines = new List<string>();
var file = new System.IO.StreamReader("c:\\registros.csv");
string line;
while((line = file.ReadLine()) != null)
{
lines.Add(line);
}
file.Close();
然后,您可以查找以您要查找的ID开头的行。 找到它后,从列表中删除该行。
for(int i=0; i++; i<lines.Count)
{
if (lines[i].StartsWith(searchid))
{
lines.RemoveAt(i);
break;
}
}
下一步是将结果写回到文件中:
File.WriteAllLines("c:\\registros.csv", lines);
关于您的第二个问题,我在这里在stackoverflow上找到了类似的问题。 第一步是创建DataTable,然后必须将表绑定到将显示数据的表控件。
读写CSV文件并不像最初看起来那么简单。 单元格可以包含嵌入式逗号,甚至可以包含换行符。 以下是CSV阅读器的一种实现,可以选择将其作为后台工作程序异步运行。 此实现返回一个标准DataTable
,可以轻松地将其绑定到DataGridView
:
grid.DataSource = dataTable;
CsvReader类:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.IO;
using System.Linq;
using System.Text;
namespace CsvReaderExample
{
public class CsvReader
: BackgroundWorker
{
string[] m_lines;
public DataTable DataTable { get; private set; }
public CsvReader(string[] lines)
{
m_lines = lines;
WorkerReportsProgress = true;
WorkerSupportsCancellation = true;
}
public DataTable RunWorker()
{
return DataTable = ParseCsvLines();
}
protected override void OnDoWork(DoWorkEventArgs e)
{
base.OnDoWork(e);
e.Result = DataTable = ParseCsvLines();
}
private DataTable ParseCsvLines()
{
if (m_lines.Length == 0)
return null;
var table = new DataTable();
var columns = table.Columns;
var columnNames = GetRowValues(m_lines[0]);
foreach (var columnName in columnNames)
{
var name = columnName;
int number = 2;
while (columns.Contains(name))
name += " " + number++;
columns.Add(name);
}
var rows = table.Rows;
for (int index = 1, linesCount = m_lines.Length; index < linesCount; index++)
{
if (CancellationPending)
return null;
var line = m_lines[index];
var values = GetRowValues(line);
int valueCount = values.Count;
if (valueCount > columns.Count)
{
int columnNumber = columns.Count;
while (columns.Contains(columnNumber.ToString()))
columnNumber++;
columns.Add(columnNumber.ToString());
}
rows.Add(values.ToArray());
if (WorkerReportsProgress)
ReportProgress(100 * index / linesCount);
}
return table;
}
const char COMMA = ',',
DOUBLE_QUOTE = '"',
VERTICAL_BAR = '|';
private List<string> GetRowValues(string line)
{
var builder = new StringBuilder();
var values = new List<string>();
var inDoubleQuotes = false;
var maxIndex = line.Length - 1;
for (int index = 0; index <= maxIndex; index++)
{
char c = line[index];
if (c == DOUBLE_QUOTE)
{
if (index == 0)
{
inDoubleQuotes = true;
continue;
}
if (index < maxIndex)
{
var nextIndex = index + 1;
if (nextIndex < maxIndex)
{
if (line[nextIndex] == DOUBLE_QUOTE)
{
index++;
if (inDoubleQuotes)
builder.Append(DOUBLE_QUOTE);
continue;
}
}
}
inDoubleQuotes = !inDoubleQuotes;
continue;
}
if (c == COMMA)
{
if (inDoubleQuotes)
{
builder.Append(c);
continue;
}
values.Add(builder.ToString());
builder = new StringBuilder();
continue;
}
builder.Append(c);
}
values.Add(builder.ToString());
return values;
}
#region Sanitise cells with new line characters
public static void SanitiseCellsWithNewLineCharacters(string fileName)
{
var text = File.ReadAllText(fileName, Encoding.Default);
text = text.Replace("\r\n", "\n");
text = text.Replace("\r", "\n");
using (var writer = File.CreateText(fileName))
{
var inDoubleQuotes = false;
foreach (char c in text)
{
if (c == '\n' && inDoubleQuotes)
{
writer.Write(VERTICAL_BAR);
continue;
}
if (c == DOUBLE_QUOTE)
{
if (inDoubleQuotes)
inDoubleQuotes = false;
else
inDoubleQuotes = true;
}
writer.Write(c);
}
}
}
#endregion
}
}
您可以按以下方式同步读取DataTable
:
var lines = File.ReadAllLines("C:\\registros.csv");
var csvReader = new CsvReader(lines);
var dataTable = csvReader.RunWorker();
然后,您可以使用以下方法从DataTable
删除行:
private static void RemoveById(DataTable dataTable, int id)
{
var column = dataTable.Columns["ID"];
if (column == null)
return;
var rows = dataTable.Rows;
for (int index = rows.Count - 1; index >= 0; index--)
{
var row = rows[index];
var value = row ["ID"];
if (value == null)
continue;
if (value.Equals(id))
{
rows.RemoveAt(index);
return;
}
}
}
称它为:
RemoveById(dataTable, 1);
简单易懂! `
第一个问题的解决方案是:
****读和写回CSV文件!****
string searchid = "1";
string[] values = File.ReadAllText(@"Complete Path Of File").Split(new char[] { '\n' });
StringBuilder ObjStringBuilder = new StringBuilder();
for (int i = 0; i < values.Length - 1; i++)
{
if (values[i].StartsWith(searchid) == false)
{
ObjStringBuilder.Append(values[i]+"\n");
}
}
File.WriteAllText(@"Complete Path Of File", ObjStringBuilder.ToString());
}
回答您的第二个疑问:
****从CSV文件动态填充DataGridView!****
解决的逗号(,)问题:
DataTable dtDataSource = new DataTable();
string[] fileContent = File.ReadAllLines(@"..\\Book1.csv");
if (fileContent.Count() > 0)
{
//Create data table columns dynamically
string[] columns = fileContent[0].Split(',');
for (int i = 0; i < columns.Count(); i++)
{
dtDataSource.Columns.Add(columns[i]);
}
//Add row data dynamically
for (int i = 1; i < fileContent.Count(); i++)
{
string[] rowData = fileContent[i].Split(',');
string[] realRowData = new string[columns.Count()];
StringBuilder collaboration = new StringBuilder();
int v = 0;
//this region solves the problem of a cell containing ",".
#region CommaSepProblem
for (int j = 0, K = 0; j < rowData.Count(); j++, K++)
{
//After splitting the line with commas. The cells containing commas will also be splitted.
//Fact: if a cell contains special symbol in excel that cell will be saved in .csv contained in quotes E.g A+B will be saved "A+B" or A,B will be saved as "A,B"
//Our code splits everything where comma is found. So solution is:
//Logic: After splitting if a string contains even number of DoubleQuote then its perfect cell otherwise, it is splitted in multiple cells of array.
if ((rowData[j].Count(x => x == '"') % 2 == 0))//checks if the string contains even number of DoubleQuotes
{
realRowData[K] = quotesLogic((rowData[j]));
}
else if ((rowData[j].Count(x => x == '"') % 2 != 0))//If Number of DoubleQuotes are ODD
{
int c = rowData[j].Count(x => x == '"');
v = j;
while (c % 2 != 0)//Go through all the next array cell till it makes EVEN Number of DoubleQuotes.
{
collaboration.Append(rowData[j] + ",");
j++;
c += rowData[j].Count(x => x == '"');
}
collaboration.Append(rowData[j]);
realRowData[K] = quotesLogic(collaboration.ToString());
}
else { continue; }
}
#endregion
dtDataSource.Rows.Add(realRowData);
}
if (dtDataSource != null)
{
dataGrid1.ItemsSource = dtDataSource.DefaultView;
}
}
也添加此方法:
string quotesLogic(string collaboration)
{
StringBuilder after = new StringBuilder(collaboration);
if (after.ToString().StartsWith("\"") && after.ToString().EndsWith("\""))//removes 1st and last quotes as those are system generated
{
after.Remove(0, 1);
after.Remove(after.Length - 1, 1);
int count = after.Length - 1;
//FACT: if you try to add DoubleQuote in a cell in excel. It'll save that quote as 2 times DoubleQuote(Like "") which means first DoubleQuote is to give instruction to CPU that the next DoubleQuote is not system generated.
while (count > 0)//This loop find twice insertion of 2 DoubleQuotes and neutralise them to One DoubleQuote.
{
if (after[count] == '"' && after[count - 1] == '"')
{
after.Remove(count, 1);
}
count--;
}
}
return after.ToString();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.