简体   繁体   中英

Read CSV files in C#

I have the following code that imports excel documents and parses them so I can manipulate the data before it is saved to the database.

I can parse .xlsx and .xls files just fine but cannot figure out how to use my existing code for .csv files

the customer I am working for wants to use .csv file type to accept special characters.

OpenFileDialog opener = new OpenFileDialog();
opener.Filter = "Excel Files| *.xlsx;*.xls;*.csv;";
if (opener.ShowDialog() == DialogResult.Cancel)
    return;

FileStream streamer = new FileStream(opener.FileName, FileMode.Open);
IExcelDataReader reader;
if (Path.GetExtension(opener.FileName) == ".xls")
{
    reader = ExcelReaderFactory.CreateBinaryReader(streamer);
}
else if (Path.GetExtension(opener.FileName) == ".csv")
{

    *** Need Something Here to read CSV Files that will work with 
        the rest of code***
}
else
{
    reader = ExcelReaderFactory.CreateOpenXmlReader(streamer);
}
DataSet results = reader.AsDataSet();
results.Tables[0].Rows[0].Delete();
results.AcceptChanges();


foreach (System.Data.DataTable table in results.Tables)
{
    foreach (DataRow dr in table.Rows)
    {
       >>> Do Something With the Data
    }
}
private void ReadCSVFile(string filepath)
{
    //receiverList = new List<ReceiverUser>();

    try
    {
        if (filepath == string.Empty)
            return;

        using (StreamReader sr = new StreamReader(FileUpload1.PostedFile.InputStream))
        {
            string line;

            while ((line = sr.ReadLine()) != null)
            {
                SplitLine(line);
            }
        }

        #region row add test
        DataTable dt = new DataTable();

        if (dt.Columns.Count == 0)
        {
            dt.Columns.Add("Name", typeof(string));
            dt.Columns.Add("Mail", typeof(string));
            dt.Columns.Add("Amount", typeof(double));
        }

        DataRow NewRow;
/*
        foreach (var item in receiverList)
        {
            NewRow = dt.NewRow();
            NewRow[0] = item.Name + " " + item.Surname;
            NewRow[1] = item.Mail;
            NewRow[2] = item.Amount;
            dt.Rows.Add(NewRow);
        }
*/


        grdRec.DataSource = dt;
        grdRec.DataBind();

        #endregion
    }
    catch (Exception)
    {

    }

}//end of function

This function reads a CSV file, load parameters to Datatable and set datasource of grid as Datatable. This is an ASP.NET WebfoRM CODE.

Assuming your IExcelDataReader is a third party package that reads Excel files (a pretty safe bet) and it does not natively handle CSV (that part I'm not sure about), then you can always just handle the CSV completely separately.

OLE has a nice CSV reader, so something like this should work.

List<DataTable> tables = new List<DataTable>();

if (Path.GetExtension(opener.FileName) == ".csv")
{
    OleDbConnection conn = new OleDbConnection(string.Format(
        @"Provider=Microsoft.Jet.OleDb.4.0; Data Source={0};" +
        "Extended Properties=\"Text;HDR=YES;FMT=Delimited\"",
        opener.FileName
    ));
    conn.Open();

    string sql = string.Format("select * from [{0}]", Path.GetFileName(opener.FileName));
    OleDbCommand cmd = new OleDbCommand(sql, conn);
    OleDbDataReader reader = cmd.ExecuteReader();

    DataTable dt = new DataTable();
    dt.Load(reader);
    tables.Add(dt);

    reader.Close();
}
else
{
    FileStream streamer = new FileStream(opener.FileName, FileMode.Open);
    IExcelDataReader reader = null;
    if (Path.GetExtension(opener.FileName) == ".xls")
        reader = ExcelReaderFactory.CreateBinaryReader(streamer);
    else
        reader = ExcelReaderFactory.CreateOpenXmlReader(streamer);
    DataSet results = reader.AsDataSet();
    results.Tables[0].Rows[0].Delete();
    results.AcceptChanges();

    foreach (DataTable table in results.Tables)
        tables.Add(table);
}

And then just reference your local list of datatables ( tables ) instead of Results.Tables, as that is now locally scoped to IExcelReader .

foreach (System.Data.DataTable table in tables)
{
    foreach (DataRow dr in table.Rows)
    {
       >>> Do Something With the Data
    }
}

If you can't use OLE for some reason, the .NET class library actually has a CSV parser. It's pretty well hidden, in my opinion, but it's nice:

http://odedcoster.com/blog/2012/03/28/did-you-know-a-net-csv-parser-that-comes-with-visual-studio/

Can you check below code?. This will be useful to you.

 OpenFileDialog opener = new OpenFileDialog();
   opener.Filter = "Excel Files| *.xlsx;*.xls;*.csv;";
if (opener.ShowDialog() == DialogResult.Cancel)
    return;

FileStream streamer = new FileStream(opener.FileName, FileMode.Open);
IExcelDataReader reader;
if (Path.GetExtension(opener.FileName) == ".xls")
{
    reader = ExcelReaderFactory.CreateBinaryReader(streamer);
}
else if (Path.GetExtension(opener.FileName) == ".csv")
{

   var reader = ExcelReaderFactory.CreateReader(stream, new ExcelReaderConfiguration() {

// Gets or sets the encoding to use when the input XLS lacks a CodePage
// record, or when the input CSV lacks a BOM and does not parse as UTF8. 
// Default: cp1252. (XLS BIFF2-5 and CSV only)
FallbackEncoding = Encoding.GetEncoding(1252),

// Gets or sets the password used to open password protected workbooks.
Password = "password",

// Gets or sets an array of CSV separator candidates. The reader 
// autodetects which best fits the input data. Default: , ; TAB | # 
// (CSV only)
AutodetectSeparators = new char[] { ',', ';', '\t', '|', '#' };
});
    }
    else
    {
        reader = ExcelReaderFactory.CreateOpenXmlReader(streamer);
    }
    DataSet results = reader.AsDataSet();
    results.Tables[0].Rows[0].Delete();
    results.AcceptChanges();


    foreach (System.Data.DataTable table in results.Tables)
    {
        foreach (DataRow dr in table.Rows)
        {
           >>> Do Something With the Data
        }
    }

Refer this link ExcelDataReader

您可以使用CSVHelper来避免手动编写 CVS 解析器

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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