LINQ to CSV library

  • 15723
  • 0
  • C#
  • 2010-12-13

LINQ to CSV library

Matt Perdeck開發的LINQ to CSV library提供強大的CSV檔存取功能,可讓我們很輕鬆的取出CSV檔內容,搭配使用Linq去做查詢的動作,也具備有CSV檔文件產出與例外處理的功能,使用上十分的彈性好用。

 

其具備以下特點:

  • 依循 CSV 檔格式
  • 可指定分隔符號
  • 支援延遲讀取
  • 支援存取檔案中的日期與數字格式
  • 可自動辨識各種不同的日期與數字格式
  • 可彈性的控制日期與數字的輸出格式
  • 支援不同的字集編碼 ( Encoding )
  • 完善的錯誤處理機制

 

使用前我們需至LINQ to CSV library下載程式專案,將其建置後取出LINQtoCSV.dll組件。

 

在使用上LINQ to CSV library也算是很容易上手的一個函式庫,因為我們不需要了解太多類別,主要要了解的有CsvContext、CsvFileDescription、與CsvColumnAttribute這三個,外加一些做例外處理用的例外類別(LINQ to CSV library這邊就有很詳細的類別與成員的介紹,故例外類別不在此多做著墨)。

 

CsvContext為主要我們要操控的類別,內有Read與Write方法兩種方法,皆具有許多的多載,用以讀取CSV檔的檔案內容,與寫入檔案內容至CSV檔案之中。

	Write<T>(IEnumerable<T> values, string fileName)
Write<T>(IEnumerable<T> values, string fileName, CsvFileDescription fileDescription)
Write<T>(IEnumerable<T> values, TextWriter stream)
Write<T>(IEnumerable<T> values, TextWriter stream, CsvFileDescription fileDescription)


Read<T>(string fileName)
Read<T>(string fileName, CsvFileDescription fileDescription)
Read<T>(StreamReader stream)
Read<T>(StreamReader stream, CsvFileDescription fileDescription)

 

CsvFileDescription為存取CSV檔所需要的一些細項描述,像是SeparatorChar屬性用以設定CSV檔資料的分隔符號、FirstLineHasColumnNames屬性用以指示資料的第一行是否含有欄位名稱、FileCultureName屬性用以指示CSV檔寫入與讀取時所要採用的文化語系...等等。

 

CsvColumnAttribute則是用以設定屬性與CSV檔欄位的對應方式,像是Name屬性可設定對應的欄位名稱、CanBeNull指示欄位資料是否可為空值、FieldIndex指示欄位的索引、OutputFormat指示輸出的格式...等等。

 

在做寫入CSV檔時,主要是先建立要寫入的資料內容,這邊的資料內容為具有CsvColumnAttribute修飾屬性的類別集合。像是下面這樣:

	public class Person 
    {
        [CsvColumn (Name="FirstName",FieldIndex =0)]
        public String FirstName { get; set; }

        [CsvColumn(Name = "LastName", FieldIndex = 1)]
        public String LastName { get; set; }

        [CsvColumn(Name = "Sex", FieldIndex = 2)]
        public String Sex { get; set; }

        [CsvColumn(Name = "Birthday", FieldIndex = 3)]
        public String Birthday { get; set; }

        public String Memo { get; set; }

        public override string ToString()
        {
            return string.Join(",", new string[] { FirstName, LastName, Sex, Birthday, Memo });
        }
    }

 

建立完後,透過CsvContext.Write,帶入資料內容與檔名就可將指定的內容寫入至CSV檔中

	const string FILE_NAME = "Persons.CSV";
            
            CsvContext cc = new CsvContext();
            Person[] persons = new Person[] 
            {
                new Person() { FirstName = "Larry", LastName = "Nung", Sex = "Boy", Birthday = "1980/04/19" }
            };

            cc.Write(persons, FILE_NAME);

 

讀檔的話則是透過CsvContext.Read,帶入檔名與泛型類別,檔案的內容就會讀出轉成指定的泛型類別集合。

	const string FILE_NAME = "Persons.CSV";            
            CsvContext cc = new CsvContext();   
            Var data = cc.Read<Person>(FILE_NAME);

 

完整範例

Person.cs

	using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using LINQtoCSV;

namespace ConsoleApplication1
{
    public class Person 
    {
        [CsvColumn (Name="FirstName",FieldIndex =0)]
        public String FirstName { get; set; }

        [CsvColumn(Name = "LastName", FieldIndex = 1)]
        public String LastName { get; set; }

        [CsvColumn(Name = "Sex", FieldIndex = 2)]
        public String Sex { get; set; }

        [CsvColumn(Name = "Birthday", FieldIndex = 3)]
        public String Birthday { get; set; }

        public String Memo { get; set; }

        public override string ToString()
        {
            return string.Join(",", new string[] { FirstName, LastName, Sex, Birthday, Memo });
        }
    }
}

 

Program.cs

	using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using LINQtoCSV;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            const string FILE_NAME = "Persons.CSV";
            
            CsvContext cc = new CsvContext();
            Person[] persons = new Person[] 
            {
                new Person() { FirstName = "Larry", LastName = "Nung", Sex = "Boy", Birthday = "1980/04/19" }
            };

            cc.Write(persons, FILE_NAME);

            Console.WriteLine("CSV File Content...");
            Console.WriteLine(System.IO.File.ReadAllText(FILE_NAME));

            Console.WriteLine("Read From CSV...");
            Console.WriteLine(cc.Read<Person>(FILE_NAME).FirstOrDefault().ToString());

            Console.WriteLine(new string('=', 50));
            CsvFileDescription cfd = new CsvFileDescription()
            {
                SeparatorChar = '\t',
                FirstLineHasColumnNames = true,
                EnforceCsvColumnAttribute =true             
            };

            cc.Write(persons, FILE_NAME,cfd);

            Console.WriteLine("CSV File Content...");
            Console.WriteLine(System.IO.File.ReadAllText(FILE_NAME));

            cfd = new CsvFileDescription()
            {
                SeparatorChar = '\t',
                FirstLineHasColumnNames = false ,
                EnforceCsvColumnAttribute = true
            };
            Console.WriteLine("Read From CSV...");
            Console.WriteLine(cc.Read<Person>(FILE_NAME, cfd).FirstOrDefault().ToString());
            
            Console.WriteLine(new string('=', 50));
            cfd = new CsvFileDescription()
            {
                FirstLineHasColumnNames = false,
                EnforceCsvColumnAttribute = true
            };

            cc.Write(persons, FILE_NAME, cfd);

            Console.WriteLine("CSV File Content...");
            Console.WriteLine(System.IO.File.ReadAllText(FILE_NAME));

            cfd = new CsvFileDescription()
            {
                SeparatorChar = '\t',
                FirstLineHasColumnNames = false,
                EnforceCsvColumnAttribute = true
            };
            Console.WriteLine("Read From CSV...");
            Console.WriteLine(cc.Read<Person>(FILE_NAME, cfd).FirstOrDefault().ToString());
        }
    }
}

 

運行結果如下:

image

 

Download

LinqToCSVDemo.zip

 

Link