| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596 |
- /*******************************************************************************
- * Copyright(c) 2012 dongke All rights reserved. / Confidential
- * 类的信息:
- * 1.程序名称:CsvManager.cs
- * 2.功能描述:CSV文件与DataTable之间的转换
- * 编辑履历:
- * 作者 日期 版本 修改内容
- * 欧阳涛 2012/07/05 1.00 新建
- *******************************************************************************/
- using System.Collections;
- using System.Data;
- using System.Text;
- using System.Windows.Forms;
- namespace Dongke.IBOSS.PRD.Basics.Library
- {
- /// <summary>
- /// CSV文件与DataTable之间的转换
- /// </summary>
- public class CsvManager
- {
- #region 常量
- private const string ROW_END = "\r\n";
- #endregion
- #region 构造函数
- private CsvManager()
- {
- }
- #endregion
- #region 公开方法/函数
- #region ToDataTable()
- public static DataTable ToDataTable(string csv, bool isHeaderFirstRow)
- {
- return ToDataTable(csv, isHeaderFirstRow, ',', '\"');
- }
- public static DataTable ToDataTable(string csv, bool isHeaderFirstRow, char delim, char quote)
- {
- return Decode(csv, isHeaderFirstRow, delim, quote);
- }
- #endregion
- #region ToString()
- public static string ToString(DataTable table, bool isHeaderFirstRow)
- {
- return ToString(table, isHeaderFirstRow, ',', '\"');
- }
- public static string ToString(DataTable table, bool isHeaderFirstRow, char delim, char quote)
- {
- return Encode(table, isHeaderFirstRow, delim, quote);
- }
- public static string ToString(DataColumnCollection columns)
- {
- return ToString(columns, ',', '\"');
- }
- public static string ToString(DataColumnCollection columns, char delim, char quote)
- {
- StringBuilder sb = new StringBuilder();
- bool isFirst = true;
- foreach (DataColumn column in columns)
- {
- if (isFirst)
- {
- isFirst = false;
- }
- else
- {
- sb.Append(delim);
- }
- string item = column.Caption;
- if (string.IsNullOrEmpty(item))
- {
- item = column.ColumnName;
- }
- sb.Append(QuoteItem(item, delim, quote));
- }
- sb.Append(ROW_END);
- return sb.ToString();
- }
- public static string ToString(DataRow row)
- {
- return ToString(row, ',', '\"');
- }
- public static string ToString(DataRow row, char delim, char quote)
- {
- if (row == null)
- {
- return null;
- }
- StringBuilder sb = new StringBuilder();
- bool isFirst = true;
- foreach (DataColumn column in row.Table.Columns)
- {
- if (isFirst)
- {
- isFirst = false;
- }
- else
- {
- sb.Append(delim);
- }
- sb.Append(QuoteItem(row[column], delim, quote));
- }
- sb.Append(ROW_END);
- return sb.ToString();
- }
- public static string ToString(System.Windows.Forms.DataGridView dataGridView, bool isHeaderFirstRow)
- {
- return ToString(dataGridView, isHeaderFirstRow, ',', '\"');
- }
- public static string ToString(System.Windows.Forms.DataGridView dataGridView, bool isHeaderFirstRow, char delim, char quote)
- {
- return Encode(dataGridView, isHeaderFirstRow, delim, quote);
- }
- public static string ToString(DataGridViewRow row)
- {
- return ToString(row, ',', '\"');
- }
- public static string ToString(DataGridViewRow row, char delim, char quote)
- {
- if (row == null)
- {
- return null;
- }
- StringBuilder sb = new StringBuilder();
- bool isFirst = true;
- foreach (DataGridViewColumn column in row.DataGridView.Columns)
- {
- if (isFirst)
- {
- isFirst = false;
- }
- else
- {
- sb.Append(delim);
- }
- sb.Append(QuoteItem(row.Cells[column.Index].Value, delim, quote));
- }
- sb.Append(ROW_END);
- return sb.ToString();
- }
- public static string ToString(DataGridViewColumnCollection columns)
- {
- return ToString(columns, ',', '\"');
- }
- public static string ToString(DataGridViewColumnCollection columns, char delim, char quote)
- {
- StringBuilder sb = new StringBuilder();
- bool isFirst = true;
- foreach (DataGridViewColumn column in columns)
- {
- if (isFirst)
- {
- isFirst = false;
- }
- else
- {
- sb.Append(delim);
- }
- sb.Append(QuoteItem(column.HeaderText, delim, quote));
- }
- sb.Append(ROW_END);
- return sb.ToString();
- }
- public static string ToString<T>(T[] values, bool isHeaderFirstRow)
- {
- return ToString(values, isHeaderFirstRow, ',', '\"');
- }
- public static string ToString<T>(T[] values, bool isHeaderFirstRow, char delim, char quote)
- {
- if (values == null)
- {
- return null;
- }
- StringBuilder sbCsv = new StringBuilder();
- bool isFirst = true;
- object[] arrays = DataConvert.ToObjectArray(values);
- foreach (object value in arrays)
- {
- if (value == null)
- {
- return null;
- }
- if (isFirst)
- {
- isFirst = false;
- }
- else
- {
- sbCsv.Append(delim);
- }
- sbCsv.Append(QuoteItem(value, delim, quote));
- }
- return sbCsv.ToString();
- }
- #endregion
- #region QuoteItem()
- public static string QuoteItem(object value, char delim, char quote)
- {
- if (value == null)
- {
- value = string.Empty;
- }
- return QuoteItem(value.ToString(), delim, quote);
- }
- public static string QuoteItem(string item, char delim, char quote)
- {
- if (string.IsNullOrEmpty(item))
- {
- return item;
- }
- if (item.IndexOf(delim) >= 0 || item.IndexOf(quote) >= 0 || item.IndexOf("\r") >= 0 || item.IndexOf("\n") >= 0)
- {
- return quote + item.Replace(ROW_END, "\n").Replace(quote.ToString(), quote.ToString() + quote.ToString()) + quote;
- }
- else
- {
- return item;
- }
- }
- #endregion
- #region UnquoteItem()
- public static string UnquoteItem(object value, char quote)
- {
- if (value == null)
- {
- value = string.Empty;
- }
- return UnquoteItem(value.ToString(), quote);
- }
- public static string UnquoteItem(string item, char quote)
- {
- if (string.IsNullOrEmpty(item))
- {
- return item;
- }
- int length = item.Length;
- if (item.IndexOf(quote) == 0 && item.LastIndexOf(quote) == length - 1 && 2 <= length)
- {
- return item.Substring(1, length - 2).Replace(quote.ToString() + quote.ToString(), quote.ToString());
- }
- else
- {
- return item;
- }
- }
- #endregion
- #endregion
- #region 受保护的方法/函数
- #region Encode()
- protected static string Encode(DataTable table, bool isHeaderFirstRow, char delim, char quote)
- {
- if (table == null)
- {
- return null;
- }
- StringBuilder sbCsv = new StringBuilder();
- if (isHeaderFirstRow)
- {
- sbCsv.Append(ToString(table.Columns, delim, quote));
- }
- foreach (DataRow row in table.Rows)
- {
- sbCsv.Append(ToString(row, delim, quote));
- }
- return sbCsv.ToString();
- }
- protected static string Encode(System.Windows.Forms.DataGridView dataGridView, bool isHeaderFirstRow, char delim, char quote)
- {
- if (dataGridView == null)
- {
- return null;
- }
- StringBuilder sbCsv = new StringBuilder();
- if (isHeaderFirstRow)
- {
- sbCsv.Append(ToString(dataGridView.Columns, delim, quote));
- }
- foreach (DataGridViewRow row in dataGridView.Rows)
- {
- sbCsv.Append(ToString(row, delim, quote));
- }
- return sbCsv.ToString();
- }
- #endregion
- #region Decode()
- protected static DataTable Decode(string csv, bool isHeaderFirstRow, char delim, char quote)
- {
- DataTable table = new DataTable();
- DataRow row;
- string[,] result = Decode(csv, delim, quote);
- int nRowCount = result.GetLength(0);
- int nColumnCount = result.GetLength(1);
- for (int j = 0; j < nColumnCount; j++)
- {
- table.Columns.Add("Column" + j.ToString(), typeof(string));
- }
- for (int i = 0; i < nRowCount; i++)
- {
- if (isHeaderFirstRow && i == 0)
- {
- for (int j = 0; j < nColumnCount; j++)
- {
- if (string.IsNullOrEmpty(result[i, j]) == false)
- {
- table.Columns[j].ColumnName = result[i, j];
- }
- }
- }
- else
- {
- row = table.NewRow();
- for (int j = 0; j < nColumnCount; j++)
- {
- if (string.IsNullOrEmpty(result[i, j]) == false)
- {
- row[j] = result[i, j];
- }
- }
- table.Rows.Add(row);
- }
- }
- return table;
- }
- protected static string[,] Decode(string csv, char delim, char quote)
- {
- int nRowCount, nColumnCount;
- csv = SanitizeCRLF(csv);
- GetCSVCount(csv, out nRowCount, out nColumnCount, delim, quote);
- string[,] result = new string[nRowCount, nColumnCount];
- int nPtrS = 0;
- int nPtrE = 0;
- string strLine;
- ArrayList aryCSVLine;
- int i = 0;
- while (nPtrE >= 0)
- {
- nPtrE = csv.IndexOf(ROW_END, nPtrS);
- if (nPtrE < 0)
- {
- strLine = csv.Substring(nPtrS);
- if (strLine == string.Empty)
- {
- break;
- }
- }
- else
- {
- strLine = csv.Substring(nPtrS, nPtrE - nPtrS);
- }
- aryCSVLine = DecodeLine(strLine, delim, quote);
- if (aryCSVLine.Count == 0)
- {
- break;
- }
- for (int j = 0; j < aryCSVLine.Count; j++)
- {
- result[i, j] = aryCSVLine[j].ToString();
- }
- nPtrS = nPtrE + ROW_END.Length;
- i++;
- }
- return result;
- }
- #endregion
- #region GetCSVCount()
- protected static void GetCSVCount(string csv, out int rowCount, out int columnCount, char delim, char quote)
- {
- int nPtrS = 0;
- int nPtrE = 0;
- string strLine;
- ArrayList aryCSVLine;
- rowCount = 0;
- columnCount = 0;
- while (nPtrE >= 0)
- {
- nPtrE = csv.IndexOf(ROW_END, nPtrS);
- if (nPtrE < 0)
- {
- strLine = csv.Substring(nPtrS);
- }
- else
- {
- strLine = csv.Substring(nPtrS, nPtrE - nPtrS);
- }
- aryCSVLine = DecodeLine(strLine, delim, quote);
- if (aryCSVLine.Count == 0)
- {
- break;
- }
- if (columnCount < aryCSVLine.Count)
- {
- columnCount = aryCSVLine.Count;
- }
- nPtrS = nPtrE + ROW_END.Length;
- rowCount++;
- }
- }
- #endregion
- #region SanitizeCRLF()
- private static string SanitizeCRLF(string csv)
- {
- if (string.IsNullOrEmpty(csv))
- {
- return csv;
- }
- int index = 0;
- int maxLength = csv.Length;
- StringBuilder result = new StringBuilder();
- while (index < maxLength)
- {
- int preIndex = index;
- index = csv.IndexOf('"', index);
- if (index < 0)
- {
- result.Append(csv.Substring(preIndex, maxLength - preIndex));
- break;
- }
- result.Append(csv.Substring(preIndex, index - preIndex));
- int startIndex = index;
- int endIndex = startIndex;
- while (endIndex < maxLength)
- {
- endIndex = csv.IndexOf('"', endIndex + 1);
- if (endIndex < 0)
- {
- break;
- }
- if (endIndex + 1 < maxLength && csv.ToCharArray(endIndex + 1, 1)[0] == '"')
- {
- continue;
- }
- else
- {
- break;
- }
- }
- if (endIndex < 0)
- {
- result.Append(csv.Substring(startIndex, maxLength));
- break;
- }
- else
- {
- string escapedString = csv.Substring(startIndex, endIndex - startIndex + 1);
- escapedString = escapedString.Replace("\r\n", "\n");
- result.Append(escapedString);
- }
- index = endIndex + 1;
- }
- return result.ToString();
- }
- #endregion
- #region DecodeLine()
- protected static ArrayList DecodeLine(string csvLine, char delim, char quote)
- {
- ArrayList aryCSV = new ArrayList();
- int nPtrS = 0;
- int nPtrM = 0;
- int nPtrE = 0;
- string strBuf;
- int nCsvLength = csvLine.Length;
- if (nCsvLength == 0)
- {
- return aryCSV;
- }
- while (nPtrE >= 0)
- {
- nPtrS = nPtrM = nPtrE;
- strBuf = string.Empty;
- if (nPtrE >= nCsvLength)
- {
- break;
- }
- if (csvLine[nPtrE] == quote)
- {
- nPtrE++;
- while (nPtrE >= 0)
- {
- nPtrM = nPtrE;
- nPtrE = csvLine.IndexOf(quote, nPtrE);
- if (nPtrE < 0)
- {
- strBuf += csvLine.Substring(nPtrM);
- break;
- }
- else
- {
- strBuf += csvLine.Substring(nPtrM, nPtrE - nPtrM);
- }
- nPtrM = nPtrE;
- if (nPtrE + 1 < nCsvLength && csvLine[nPtrE + 1] == quote)
- {
- nPtrE += 2;
- strBuf += quote;
- continue;
- }
- else
- {
- nPtrM++;
- nPtrE++;
- break;
- }
- }
- }
- if (nPtrE >= 0)
- {
- nPtrE = csvLine.IndexOf(delim, nPtrE);
- if (nPtrE >= 0)
- {
- strBuf += csvLine.Substring(nPtrM, nPtrE - nPtrM);
- }
- else
- {
- strBuf += csvLine.Substring(nPtrM);
- }
- aryCSV.Add(strBuf);
- }
- if (nPtrE < 0)
- {
- break;
- }
- nPtrE++;
- }
- return aryCSV;
- }
- #endregion
- #endregion
- }
- }
|