Introduction
This article shows you two methods to read data from CSV (Comma Separated File) file:- First method: Reading CSV file without any specific library
- Second method: Reading CSV File using
LinqToCsv
lib
Using the Code
Before we begin the explanation of example, let's know about CSV file.a) CSV File
A Comma Separated File stores tabular data (text, number) in plain text each line of file is a record, and each record consists of many fields separated by delimiter (',' , ';' , etc.).Example of CSV content:
Name 1,12/12/2015
Name 2,12/11/2015
User must choose between the method of parsing CSV file (with or not using the
LinqToCsv
library), click on the Parser button to send an HTTP request to the
server to analyze CSV file (that exists in server Resources) and return a
result as List
.In this application, we considered the first record of CSV file as header:
b) First Method
The following example considers a CSV File as a plain text, and according to the definition of CSV, the parsing is done.1) First Implementation :
public IEnumerable<Person> Method1(string fileSrc, char sep)
{ //Without using LinqToCsv lib
var list = new List<Person>();
var reader = new StreamReader( fileSrc );
bool header = true;
while (!reader.EndOfStream)
{
//get the first line
var line = reader.ReadLine();
//specify the separator line
//Split : string is separated by a delimiter to form a table as result
if(header == true)
{ //escape first line
header = false;
}
else
{
var values = line.Split(sep);
Person person = new Person();
person.Name = values[0];
person.Date = values[1];
list.Add(person);
}
}
return list.AsEnumerable();
}
2) Exception :
Or this code cannot handle the case when we add separator character into data fields.
Example to better understand :
1) Edit CSV file by using an editor :
2) When you run parsing you will get a wrong result :
To improve it we will use the Microsoft.VisualBasic.FileIO.TextFieldParser (see documentation), the most suitable class for better analyse CSV file.
Then the code will be :
3) Second Implementation :
First, To use TextFieldParse you must add Microsoft.VisualBasic in your project references.
public IEnumerable<Person> Method1(string fileSrc, string sep)
{ //Without using LinqToCsv lib
var list = new List<Person>();
bool header = true;
using (TextFieldParser parser = new TextFieldParser(fileSrc))
{
parser.TextFieldType = Microsoft.VisualBasic.FileIO.FieldType.Delimited;
//specify the delimiter
parser.SetDelimiters(sep);
while (!parser.EndOfData)
{
//read Fileds
string[] fields = parser.ReadFields();
//Processing row
if (header == true)
{ //escape first line
header = false;
}
else
{
Person person = new Person();
person.Name = fields[0];
person.Date = fields[1];
list.Add(person);
}
}
}
return list.AsEnumerable();
}
- Correct Result :
c) Second Method
In this example, we used theLinqToCSV
Library to do the parsing.1) Requirements
Add theLinqToCsv
lib to your project references.2) Implementation
public IEnumerable<Person> Method2(string fileSrc, char sep)
{ //Using LinqToCsv lib
CsvFileDescription inputFileDescription = new CsvFileDescription
{
SeparatorChar = sep,//specify the separator line
FirstLineHasColumnNames = true //Header is in the first line
};
CsvContext csvContext = new CsvContext();
IEnumerable<Person> list =
csvContext.Read<Person>(fileSrc, inputFil, Description);
// Data is now available via variable list.
return list;
}
d) Extra Code for Two Methods
1) Code HTML
<div class="row">
<div class="col-lg-12">
<form class="form" method="POST"
action="/Home/Index">
<div class="form-group">
<label>Choose a method :</label>
<br>
<input type="radio" name="method"
value="0" checked />
Method 1 : without LinqToCSV lib<br>
<input type="radio" name="method"
value="1" /> Method 2 : LinqToCSV lib
</div>
<div class="form-group">
<input type="submit"
class="form-control btn btn-default"
value="Start parsing" />
</div>
</form>
</div>
</div>
<hr>
<div class="row">
<div class="col-lg-12">
<label>Parsing result :</label>
</div>
</div>
<div class="row">
<div class="col-sm-4">
<table class="table">
@if (@Model != null)
{
@Html.Raw("<thead><th>Names</th>
<th>Dates</th></thead><tbody>");
foreach (var elem in @Model as IEnumerable
<WebApplicationReadingCSVFile.Models.Person>)
{
@Html.Raw("<tr ><td>" +
@elem.Name + "</td><td>" +
@elem.Date + "</td></tr>");
}
@Html.Raw("</tbody>");
}
</table>
</div>
<div class="col-sm-8"></div>
</div>
2) Code C# ASP.NET MVC
- Class Person: It contains the record fields: public class Person
{
//CsvColumn is key word used by LinqToCSV
//CsvColumn : specify the Name of Header and the index of column
[CsvColumn(Name = "Names", FieldIndex = 1)]
public string Name { get; set; }
[CsvColumn(Name = "Dates", FieldIndex = 2)]
public string Date { get; set; }
}
- Action Index: is the entry point of the parsing methods: public ActionResult Index()
{
//get the selected radio value
string method = Request.Params["method"];
char sep = ';';
//initialize list
IEnumerable<Person> list = new List<Person>();
if (method != null && method != "")
{
//Get Server Path of CSV file
string fileSrc = Server.MapPath("~/Content/Files/CsvFile.csv");
//Build Result
if (method == "0")
{
list = Method1(fileSrc, sep);
}
else{
list = Method2(fileSrc, sep);
}
//return the list as Enumerable
}
return View(list);
}
e) Result
History of updates
v1 : we used split and LinqToCSV.v2 : we replaced split by using Microsoft.VisualBasic.FileIO.TextFieldParser due an error in parsing.
No comments:
Post a Comment