用Excel导了两天数据,各种问题,折磨客户也折磨了自己,以前没发现的问题一下子都暴露出来了
特意收集两篇Excel跟CSV读取相关的两篇文章
asp.net读取excel文件,将excel文件先上传,在读取,最后删除。
但有一个问题,那就是excel文件夹需要有读写的权限,IIS需要为asp.net用户开通权限的。
而且excel文件本身存在安全隐患,那就是它可以运行vba程序。所以从安全角度考虑,上传excel是个不好的方法。
今天介绍另一种方法,读取CVS文件。
Step1.拖一个fileupload和button控件。
Step2.双击button,在button事件中写下列代码。
protected void btnUpload_Click(object sender, EventArgs e)
{
if (FileUploadCVS.HasFile)
{
if (System.IO.Path.GetExtension(FileUploadCVS.FileName) == ".csv")
{
DataTable dt = GetdataFromCVS(FileUploadCVS);
}
}
}
Step3. 写读取CVS文件的函数。
public static DataTable GetdataFromCVS(FileUpload fileload)
{
DataTable dt = newDataTable();
StreamReader sr = newStreamReader(fileload.PostedFile .InputStream);
string strTitle = sr.ReadLine();
string[] strColumTitle = strTitle.Split(','); //CVS 文件默认以逗号隔开
for (int i = 0; i < strColumTitle.Length; i++)
{
dt.Columns.Add(strColumTitle[i]);
}
while (!sr.EndOfStream)
{
string strTest = sr.ReadLine();
string[] strTestAttribute = strTest.Split(',');
DataRow dr = dt.NewRow();
for (int i = 0; i < strColumTitle.Length; i++)
{
dr[strColumTitle[i]] = strTestAttribute[i];
}
dt.Rows.Add(dr);
}
return dt;
}
记得加上System.IO 命名空间。StreamReader 是在这个namespace下的。很多跟输入输出相关的累都在这个命名空间下
经常用到csv文件,一直用odbc进行读取,但是在unicode编码的时候读取不正确,有时候就算是ANSI编码,如一列数据混编,读取也不正确。不清楚是不是个人电脑的问题。只好自己写个来实现简单的读取,解析含","及"""号CSV文件。
更新1:使用中发现有些软件生存csv文件时,所有数据默认带有"",以前代码处理带引号空字段数据不正确。
代码如下,默认用UTF8编码,一次性读取整个CSV文件,若谁试用了此段代码,有问题请反馈给我,谢谢。
/// <summary>
/// 读取csv文件到DataTable
/// </summary> /// <param name="filepath"></param> /// <returns></returns> static private DataTable ReadCsv(string filepath) { DataTable dt = new DataTable("NewTable"); DataRow row; string[] lines = File.ReadAllLines(filepath, Encoding.UTF8); string[] head = lines[0].Split(','); int cnt = head.Length; for (int i = 0; i < cnt; i++) { dt.Columns.Add(head[i]); } for (int i = 0; i < lines.Length; i++) { lines[i].Trim(); if ((string.IsNullOrWhiteSpace(lines[i]))) { continue; } try { row = dt.NewRow(); row.ItemArray = GetRow(lines[i], cnt); dt.Rows.Add(row); } catch { } } return dt; } /// <summary> /// 解析字符串 获取 该行的数据 已经处理,及"号 /// </summary> /// <param name="line">该行的内容</param> /// <param name="cnt">总的条目数</param> /// <returns></returns> static private string[] GetRow(string line, int cnt) { //line = line.Replace("\"\"", "\""); //若空数据加引号替换不正确 string[] strs = line.Split(','); if (strs.Length == cnt) { return RemoveQuotes(strs); } List<string> list = new List<string>(); int n = 0, begin = 0; bool flag = false; for (int i = 0; i < strs.Length; i++) { //没有引号 或者 中间有引号 直接添加 if (strs[i].IndexOf("\"") == -1 || (flag == false && strs[i][0] != '\"')) { list.Add(strs[i]); continue; } //其实有引号,但该段没有,号,直接添加 n = 0; foreach (char ch in strs[i]) { if (ch == '\"') { n++; } } if (n % 2 == 0) { list.Add(strs[i]); continue; } //该段有引号 有 ,号,下一段增加后添加 flag = true; begin = i; i++; for (i = begin + 1; i < strs.Length; i++) { foreach (char ch in strs[i]) { if (ch == '\"') { n++; } } if (strs[i][strs[i].Length - 1] == '\"' && n % 2 == 0) { StringBuilder sb = new StringBuilder(); for (; begin <= i; begin++) { sb.Append(strs[begin]); if (begin != i) { sb.Append(","); } } list.Add(sb.ToString()); break; } } } return RemoveQuotes(list.ToArray()); } /// <summary> /// 将解析的数据 去除多余的引号 /// </summary> /// <param name="strs"></param> /// <returns></returns> static string[] RemoveQuotes(string[] strs) { for (int i = 0; i < strs.Length; i++) { //若该项数据为空 但csv文件中加上双引号 if (strs[i] == "\"\"") { strs[i] = ""; continue; } //若该项数据头和尾加上引号 if (strs[i].Length > 2 && strs[i][0] == '\"' && strs[i][strs[i].Length - 1] == '\"') { strs[i] = strs[i].Substring(1, strs[i].Length - 2); } //若该项数据中间有引号 strs[i] = strs[i].Replace("\"\"", "\""); } return strs; }