zoukankan      html  css  js  c++  java
  • 一段刚刚出炉的CSV文件转换为DataTable对象的代码

    CSV是以文本形式保存的表格数据,具体是每列数据使用逗号分割,每行数据使用CRLF( )来结尾,如果数据值包含逗号或CRLF则使用双引号将数值包裹,如果数据值包含双引号则使用两个双引号做为转义。

        public static class Common
        {
            public static DataTable CSVToDataTable(string path)
            {
                //第一行是否为列名
                bool firstColumnIsName = false;
    
                //文件读取的位置信息
                int current = 0;
    
                //当前是否为一个值的开始处
                bool isNewValueBegin = true;
    
                //当前是否为双引号范围
                bool isDoubleMarkMange = false;
    
                //存储数据
                List<List<string>> datatable = new List<List<string>>();
    
                #region 解析文件
                using (FileStream fs = new FileStream(path, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.ReadWrite))
                {
                    using (System.IO.StreamReader sr = new StreamReader(fs, Encoding.Default))
                    {
                        List<string> row = new List<string>();
    
                        string csv = sr.ReadToEnd();
    
                        string temp = "";
    
                        while (current < csv.Length)
                        {
                            char buffer = csv[current];
                            bool bufferNextExist = current + 1 < csv.Length;
                            char bufferNext = '';
                            if (bufferNextExist)
                            {
                                bufferNext = csv[current + 1];
                            }
    
                            if (isNewValueBegin && buffer == '"')
                            {
                                isDoubleMarkMange = true;
                            }
                            else if (buffer == ',' && isDoubleMarkMange == false)
                            {
                                row.Add(temp);
                                temp = "";
                                isNewValueBegin = true;
                            }
                            else if (isDoubleMarkMange && buffer == '"' && bufferNextExist && bufferNext == '"')
                            {
                                //如果在双引号范围内并且连续出现两个双引号则表示值中包含一个双引号
                                temp += buffer;
                                current++;
                            }
                            else if (isDoubleMarkMange && buffer == '"' && (bufferNextExist == false || (bufferNextExist && bufferNext != '"')))
                            {
                                //如果在双引号范围内并出现一个双引号则表示结束双引号范围
                                isDoubleMarkMange = false;
                            }
                            else if (buffer == '
    ' && bufferNextExist && bufferNext == '
    ')
                            {
                                //表示一个换行符,但是如果在双引号内则表示正常的文字换行
                                if (isDoubleMarkMange)
                                {
                                    temp += "
    ";
                                }
                                else
                                {
                                    row.Add(temp);
                                    datatable.Add(row);
                                    temp = "";
                                    row = new List<string>();
                                    isNewValueBegin = true;
                                }
                                current++;
                            }
                            else if (buffer == '
    ' && isDoubleMarkMange == false)
                            {
                                row.Add(temp);
                                datatable.Add(row);
                                temp = "";
                                row = new List<string>();
                                isNewValueBegin = true;
                            }
                            else
                            {
                                //正常字符
                                temp += buffer;
                            }
    
                            current++;
                        }
                    }
                }
                #endregion
    
                #region 转换为DataTable
                DataTable dt = new DataTable();
    
                if (datatable.Count > 0)
                {
                    int columns = datatable[0].Count;
                    for (int i = 0; i < datatable.Count; i++)
                    {
                        columns = Math.Max(columns, datatable[i].Count);
                    }
    
                    for (int i = 0; i < columns; i++)
                    {
                        DataColumn dc = new DataColumn("column" + i);
                        if (firstColumnIsName)
                            if (datatable[0].Count > i)
                                dc.ColumnName = datatable[0][i];
                        dt.Columns.Add(dc);
                    }
    
                    for (int i = firstColumnIsName ? 1 : 0; i < datatable.Count; i++)
                    {
                        DataRow dr = dt.NewRow();
    
                        for (int j = 0; j < datatable[i].Count; j++)
                        {
                            dr[j] = datatable[i][j];
                        }
                        dt.Rows.Add(dr);
                    }
                }
                #endregion
    
                return dt;
            }
    View Code
  • 相关阅读:
    ZOJ1450 BZOJ1136 BZOJ1137 HDU3932[最小圆覆盖]
    POJ 1755 Triathlon [半平面交 线性规划]
    POJ 3384 Feng Shui [半平面交]
    POJ 3525 Most Distant Point from the Sea [半平面交 二分]
    POJ 1279 Art Gallery [半平面交]
    POJ3335 POJ3130 POJ1474 [半平面交]
    POJ 3608 Bridge Across Islands [旋转卡壳]
    nginx访问量统计
    PV UV QPS 并发数
    PV、UV、IP之间的区别与联系
  • 原文地址:https://www.cnblogs.com/jgjgjg23/p/5970148.html
Copyright © 2011-2022 走看看