简体   繁体   English

删除CSV文件中的行,并使用c#在DataGridView中显示

[英]Delete row in a CSV file and show in DataGridView using c#

I have a problem when I want to delete a row in a CSV File, I have this code but only deletes the field that contains the line. 我要删除CSV文件中的行时遇到问题,我有此代码,但只删除包含该行的字段。

Example: 例:

CSV File: CSV档案:

ID,Name,Lastname,Country 
1,David,tod,UK  
2,Juan,Perez,Germ
3,Pepe,Lopez,Col

First iteration, sending the id 1 to delete the line: 第一次迭代,发送ID 1以删除该行:

ID,Name,Lastname,Country
David,tod,UK
2,Juan,Perez,Germ
3,Pepe,Lopez,Arg

Just delete the id I want, but not the whole line 只需删除我想要的ID,但不要删除整行


The expected result would be that like this: 预期的结果将是这样的:

ID,Name,Lastname,Country
2,Juan,Perez,Arg
3,Pepe,Lopez,Col

this is my code, What am I doing wrong? 这是我的代码,我在做什么错? I have never used csv in C# :( 我从未在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()); 

Another question is how can I show the CSV file in a datagridview in Windows Forms. 另一个问题是如何在Windows窗体的datagridview中显示CSV文件。 I have this logic, don't know if this is correct, but how I can show it? 我有这个逻辑,不知道这是否正确,但是我怎么显示呢?

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;
}

Thanks! 谢谢!

You can delete row from CSV using below link 您可以使用以下链接从CSV删除行

Delete rows from CSV 从CSV删除行

and

You can convert the CSV into DataTable using the below code. 您可以使用以下代码将CSV转换为DataTable。 If your csv file uses delimiter as , 如果您的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;
        }
    }

The first thing that is wrong with your implementation is that you use ',' as the separator. 实现的第一件事是使用“,”作为分隔符。 You should either split on the new-line character '\\n' or read the file line by line as follows: 您应该分割换行符'\\ 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();

You could then look for the line that starts with the id you are looking for. 然后,您可以查找以您要查找的ID开头的行。 When you find it, remove the line from the list. 找到它后,从列表中删除该行。

for(int i=0; i++; i<lines.Count)
{
    if (lines[i].StartsWith(searchid)) 
    {
        lines.RemoveAt(i);
        break;
    }
}

Next step is to write the result back to the file: 下一步是将结果写回到文件中:

File.WriteAllLines("c:\\registros.csv", lines);

Regarding your second question, I found a similar Q/A on stackoverflow here . 关于您的第二个问题,我在这里在stackoverflow上找到了类似的问题。 First step is creating the DataTable, then you'll have to bind the table to the table control that will show the data. 第一步是创建DataTable,然后必须将表绑定到将显示数据的表控件。

Reading and writing CSV files is not as trivial as it first seems. 读写CSV文件并不像最初看起来那么简单。 Cells can have embedded commas, and even new line characters. 单元格可以包含嵌入式逗号,甚至可以包含换行符。 The following is one implementation of a CSV reader which can optionally be run asynchronously as a background worker. 以下是CSV阅读器的一种实现,可以选择将其作为后台工作程序异步运行。 This implementation returns a standard DataTable which can easily be bound to a DataGridView : 此实现返回一个标准DataTable ,可以轻松地将其绑定到DataGridView

grid.DataSource = dataTable;

The CsvReader class: 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
    }
}

You can read the DataTable synchronously as follows: 您可以按以下方式同步读取DataTable

var lines     = File.ReadAllLines("C:\\registros.csv");
var csvReader = new CsvReader(lines);
var dataTable = csvReader.RunWorker();

You could then remove row(s) from the DataTable with a method such as: 然后,您可以使用以下方法从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;
        }
    }
}

Call it: 称它为:

RemoveById(dataTable, 1);

SIMPLE & UNDERSTANDABLE! 简单易懂! ` `

Solution For your First Problem is: 第一个问题的解决方案是:

****Reading & Writing back to CSV File!**** ****读和写回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());

    }

Answer to your Second Doubt: 回答您的第二个疑问:

****Populating DataGridView dynamically from CSV File!**** ****从CSV文件动态填充DataGridView!****

Comma(,) Problem SOLVED: 解决的逗号(,)问题:

 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;
            }
        }

Add This Method Too: 也添加此方法:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM