繁体   English   中英

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

[英]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删除行

您可以使用以下代码将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.

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