[聚合文章] c# CsvHelper

c# 2016-09-28 3 阅读
Install-Package LumenWorks.Framework.IO

using LumenWorks.Framework.IO.Csv;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

namespace Utils
{
    public static class CsvHelper
    {
        #region Constants  

        /// <summary>  
        /// Defines the default delimiter character separating each field.  
        /// </summary>  
        public const char DefaultDelimiter = ',';


        /// <summary>  
        /// Defines the default quote character wrapping every field.  
        /// </summary>  
        public const char DefaultQuote = '"';

        /// <summary>  
        /// Defines the default escape character letting insert quotation characters inside a quoted field.  
        /// </summary>  
        public const char DefaultEscape = '"';

        /// <summary>  
        /// The space character.  
        /// </summary>  
        private const char SPACE = ' ';

        /// <summary>  
        /// The carriage return character. Escape code is <c>\r</c>.  
        /// </summary>  
        private const char CR = (char)0x0d;

        /// <summary>  
        /// The line-feed character. Escape code is <c>\n</c>.  
        /// </summary>  
        private const char LF = (char)0x0a;

        #endregion

        #region Write  

        public static void Write<T>(TextWriter writer, IEnumerable<T> items) where T : class
        {
            Type itemType = typeof(T);
            var props = itemType.GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance)
                .OrderBy(p => p.Name);

            Write(writer, props.Select(p => p.Name));

            foreach (var item in items)
            {
                Write(writer, props.Select(p =>
                {
                    var value = p.GetValue(item, null);
                    if (value == null) return null;
                    return value.ToString();
                }));
            }
        }

        public static void Write(TextWriter writer, IEnumerable<string> row)
        {
            Write(writer, row, DefaultDelimiter);
        }

        public static void Write(TextWriter writer, IEnumerable<string> row, char delimiter)
        {
            bool start = false;
            foreach (string str in row)
            {
                if (start == true)
                    writer.Write(delimiter);
                else
                    start = true;
                writer.Write(CsvString(str, delimiter));
            }
            writer.WriteLine();
        }

        private static string CsvString(string str, char delimiter)
        {
            if (string.IsNullOrEmpty(str)) return string.Empty;
            bool delimit = false;

            StringBuilder sb = new StringBuilder();

            foreach (char c in str)
            {
                if (c == delimiter || c == CR || c == LF)
                {
                    delimit = true;
                }
                else if (c == DefaultQuote)
                {
                    sb.Append(DefaultQuote);
                    delimit = true;
                }
                sb.Append(c);
            }

            if (delimit)
            {
                sb.Insert(0, DefaultEscape);
                sb.Append(DefaultEscape);
            }
            return sb.ToString();
        }

        #endregion

        public static IEnumerable<string[]> ReadCsv(this TextReader reader, int columnCount)
        {
            // open the file "data.csv" which is a CSV file with headers
            using (CsvReader csv = new CsvReader(reader, false))
            {
                // missing fields will not throw an exception,
                // but will instead be treated as if there was a null value
                csv.MissingFieldAction = MissingFieldAction.ReplaceByNull;
                // to replace by "" instead, then use the following action:
                //csv.MissingFieldAction = MissingFieldAction.ReplaceByEmpty;
                int fieldCount = Math.Min(csv.FieldCount, columnCount);
                //string[] headers = csv.GetFieldHeaders();
                while (csv.ReadNextRecord())
                {
                    string[] arr = new string[fieldCount];

                    for (int i = 0; i < arr.Length; i++)
                    {
                        arr[i] = csv[i];
                    }
                    yield return arr;
                }
            }
        }
    }
}

注:本文内容来自互联网,旨在为开发者提供分享、交流的平台。如有涉及文章版权等事宜,请你联系站长进行处理。