NPOI文件导入操作
using EntMSM.SmsDbContext; using NPOI.HSSF.UserModel; using NPOI.SS.UserModel; using NPOI.XSSF.UserModel; using System; using System.Collections; using System.Collections.Generic; using System.Configuration; using System.Data; using System.Data.OleDb; using System.Data.SqlClient; using System.IO; using System.Linq; using System.Text; using System.Text.RegularExpressions; using System.Web.Mvc; namespace EntMSM.Controllers { public class ContactsController : BaseController { EntSmsDbContext esd = new EntSmsDbContext(); /// <summary> /// iqueryable转datatable /// </summary> /// <param name="enumerable"></param> /// <returns></returns> public static DataTable ConvertToDataTable(IQueryable<EntMSM.Models.ContactList> database) { DataTable table = new DataTable(); table.Columns.Add("编号", typeof(long)); table.Columns.Add("姓名", typeof(string)); table.Columns.Add("电话", typeof(string)); table.Columns.Add("邮箱", typeof(string)); table.Columns.Add("公司", typeof(string)); foreach (EntMSM.Models.ContactList info in database) { DataRow row = table.NewRow(); row["编号"] = info.Id; row["姓名"] = info.LinkName; row["电话"] = info.LinkMobile; row["邮箱"] = info.LinkEmails; row["公司"] = info.LinkCompany; table.Rows.Add(row); } return table; } /// <summary> /// ASP.NET MVC导出CSV文件 /// </summary> /// <returns></returns> public ActionResult DataSetToCsv() { //定义模版(标题、内容字段、格式化参数) string[] template = new string[] { "编号,", "姓名,", "电话,", "邮箱,", "公司,","分组名" }; string contactsfileName = DateTime.Now.Year.ToString() + DateTime.Now.Month.ToString() + DateTime.Now.Day.ToString() + DateTime.Now.Hour.ToString() + DateTime.Now.Minute.ToString() + DateTime.Now.Second.ToString(); System.IO.MemoryStream output = new System.IO.MemoryStream(); System.IO.StreamWriter writer = new System.IO.StreamWriter(output, System.Text.Encoding.Default); //输出标题 int lenght = template.GetLength(0); for (int i = 0; i < lenght; i++) writer.Write(template[i]); writer.WriteLine(); //输出内容 EntMSM.Models.Users curr = Session["LoginUser"] as EntMSM.Models.Users; //通过lambda表达式实现多表连接查询 显示对应的 短信账户名称 和角色权限对应名称 var contactsList = esd.ContactLists.AsEnumerable().Join(esd.Groupss, a => a.Groups_Id, b => b.Id, (a, b) => new { a.Id, a.LinkCompany, a.LinkEmails, a.LinkMobile, a.LinkName, a.Uses_Id, b.Name }).Where(a => a.Uses_Id == curr.Id).DefaultIfEmpty(); //var contactsList = esd.ContactLists.Where(u => u.Uses_Id == curr.Id); //List<EntMSM.Models.ContactList> lstUser = contactsList.Where(a=>a.Uses_Id==curr.Id).ToList(); if (contactsList != null) { foreach (var user in contactsList) { writer.Write(user.Id + ","); writer.Write("\"" + System.Web.HttpUtility.HtmlDecode(user.LinkName) + "\","); writer.Write(System.Web.HttpUtility.HtmlDecode(user.LinkMobile) + ","); writer.Write("\"" + System.Web.HttpUtility.HtmlDecode(user.LinkEmails) + "\","); writer.Write("\"" + System.Web.HttpUtility.HtmlDecode(user.LinkCompany) + "\","); writer.Write(user.Name); writer.WriteLine(); } } writer.Flush(); output.Position = 0; return File(output, "text/comma-separated-values", contactsfileName + ".csv"); } #region Oledb方式读取EXCEL 导入通讯录 /// <summary> /// Oledb方式读取EXCEL /// </summary> /// <param name="fileNamePath">文件路径</param> /// <returns>DataTable</returns> private DataTable ReadExcelByOledb(string fileNamePath, EntMSM.Models.Users currentUser) { string connStr = "Provider=Microsoft.Ace.OleDb.12.0;" + "data source=" + fileNamePath + ";Extended Properties='Excel 12.0; HDR=Yes; IMEX=1'"; OleDbConnection oledbconn1 = new OleDbConnection(connStr); oledbconn1.Open(); DataTable _table = oledbconn1.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[] { null, null, null, "TABLE" }); string strTableName = string.Empty; if (_table.Rows.Count > 0) { strTableName = _table.Rows[0]["TABLE_NAME"].ToString().Trim(); string sql = string.Format("SELECT * FROM [{0}]", strTableName); _table = new DataTable(); OleDbDataAdapter da = new OleDbDataAdapter(sql, oledbconn1); _table.Columns.Add(new DataColumn("Uses_Id", typeof(int))); _table.Columns["Uses_Id"].DefaultValue = currentUser.Id;//设置该列默认值 da.Fill(_table); } oledbconn1.Close(); return _table; } /// <summary> /// 利用NPOI读取Excel /// </summary> IWorkbook hssfworkbook; public DataTable ImportExcelFile(string fileNamePath, string groupsId, EntMSM.Models.Users currentUser) { #region//初始化信息 string fileType = fileNamePath.Split('.')[1].Trim(); try { using (FileStream file = new FileStream(fileNamePath, FileMode.Open, FileAccess.Read)) { if (fileType == "xlsx") { hssfworkbook = new XSSFWorkbook(file); } else { hssfworkbook = new HSSFWorkbook(file); } } } catch (Exception e) { throw e; } #endregion ISheet sheet = hssfworkbook.GetSheetAt(0); System.Collections.IEnumerator rows = sheet.GetRowEnumerator(); DataTable dt = new DataTable(); dt.Columns.Add("Id", typeof(Int32)); dt.Columns.Add("Uses_Id", typeof(Int32)); dt.Columns.Add("LinkName", typeof(string)); dt.Columns.Add("LinkMobile", typeof(string)); dt.Columns.Add("LinkEmails", typeof(string)); dt.Columns.Add("LinkCompany", typeof(string)); dt.Columns.Add("Groups_Id", typeof(Int32)); rows.MoveNext(); while (rows.MoveNext()) { IRow row = null; if (fileType == "xlsx") { row = (XSSFRow)rows.Current; } else { row = (HSSFRow)rows.Current; } DataRow dr = dt.NewRow(); for (int i = 0; i < 5; i++) { ICell cell = row.GetCell(i); if (i == 0) { if (cell == null) { dr[i] = null; } else { dr[i] = cell.ToString(); } } else if (i == 1) { dr[i] = currentUser.Id; dr[i + 1] = cell.ToString(); } else if (i == 4) { dr[i+1] =int.Parse(groupsId); } else { if (cell == null) { dr[i + 1] = null; } else { dr[i + 1] = cell.ToString(); } } } dt.Rows.Add(dr); } return dt; } /// <summary> /// 读取csv /// </summary> /// <param name="filepath"></param> /// <returns></returns> private DataTable ReadCsv(string filepath,string groupsId ,EntMSM.Models.Users currentUser) { base.IsLogin(); StreamReader sr; string strTol = string.Empty; string strTemp = string.Empty; DataTable dt = new DataTable(); EntMSM.Models.Users curr = Session["LoginUser"] as EntMSM.Models.Users; int count = 0;//导入成功的计数 try { sr = new StreamReader(filepath, Encoding.Default); dt.Columns.Add("Id", typeof(Int32)); dt.Columns.Add("Uses_Id", typeof(Int32)); dt.Columns.Add("LinkName", typeof(string)); dt.Columns.Add("LinkMobile", typeof(string)); dt.Columns.Add("LinkEmails", typeof(string)); dt.Columns.Add("LinkCompany", typeof(string)); dt.Columns.Add("Groups_Id",typeof(Int32)); strTemp = sr.ReadLine();//跳过头部 strTemp = sr.ReadLine();//跳过模板号码 if (strTemp.Split(',').Length > 5) { //针对360手机助手导出的通讯录导入 while (!string.IsNullOrEmpty(strTemp))//如果还有数据,继续读数据 { count++; DataRow row = dt.NewRow(); string tel = strTemp.Split(',')[2].Trim('"').Trim(' '); row["Id"] = 0; row["Uses_Id"] = currentUser.Id; row["LinkName"] = strTemp.Split(',')[1].Trim('"').Trim(' '); row["LinkMobile"] = tel; row["LinkEmails"] = strTemp.Split(',')[3].Trim('"').Trim(' '); row["LinkCompany"] = strTemp.Split(',')[4].Trim('"').Trim(' '); row["Groups_Id"] =int.Parse(groupsId); dt.Rows.Add(row); strTemp = sr.ReadLine();//读取下一行 } } else { //普通格式的文档导入 while (!string.IsNullOrEmpty(strTemp))//如果还有数据,继续读数据 { count++; DataRow row = dt.NewRow(); string tel = strTemp.Split(',')[2].Trim('"').Trim(' '); row["Id"] = 0; row["Uses_Id"] = currentUser.Id; row["LinkName"] = strTemp.Split(',')[1].Trim('"').Trim(' '); row["LinkMobile"] = tel; row["LinkEmails"] = strTemp.Split(',')[3].Trim('"').Trim(' '); row["LinkCompany"] = strTemp.Split(',')[4].Trim('"').Trim(' '); row["Groups_Id"] =int.Parse(groupsId); dt.Rows.Add(row); strTemp = sr.ReadLine();//读取下一行 } } } catch (Exception) { dt = null; throw; } sr.Close();//关闭流 return dt; } /// <summary> /// 判断两个DataTable中,第一个dataTable中在第二个dataTable中不存在的记录集 /// </summary> /// <param name="returnTable">返回的不重复的结果集</param> /// <param name="table1">即将导入的数据集</param> /// <param name="table2">数据库中的数据集</param> /// <param name="fieldsStr">字段名</param> /// <returns></returns> public static DataTable ComPare2DataTable(DataTable table1, DataTable table2, string fieldsStr) { try { DataTable returnTable = new DataTable(); returnTable = table1.Clone(); //for循环将数据库中的table2的每行数据转换为一个字符串,保存的HashTable中 Hashtable hashtable = new Hashtable(); DataRow[] dataRows = table2.Select(""); string[] fieldArr = fieldsStr.Split(','); foreach (DataRow row in dataRows) { string rowStr = ""; for (int i = 0; i < fieldArr.Length; i++) { Object obj = row[fieldArr[i]]; if (!String.IsNullOrEmpty(obj.ToString())) { rowStr += obj.ToString(); } } hashtable.Add(rowStr, ""); } //将要导入的DataTable,将每一行数据转换为字符串之后,在hashTable中找是否存在这个key,存在的加入返回的DataTable中,反之不加入。 DataRow[] dataRows1 = table1.Select(); foreach (DataRow row in dataRows1) { string rowStr1 = ""; for (int i = 0; i < fieldArr.Length; i++) { Object obj = row[fieldArr[i]]; if (!String.IsNullOrEmpty(obj.ToString())) { rowStr1 += obj.ToString(); } } if (!hashtable.ContainsKey(rowStr1)) { returnTable.Rows.Add(row.ItemArray); } } return returnTable; } catch (Exception ex) { throw ex; } } /// <summary> /// 文档上传 读取文档内容并保存到 数据库 /// </summary> /// <param name="context"></param> /// <returns></returns> public string UploadFile() { string result = "导入失败!"; try { base.IsLogin(); int sucCount = 0; int allCount = 0; string reqs = Request.Form["fileName"]; string groupsId=Request.Form["groupsId"]; string strPath = Server.MapPath("/UpLoadFile/" + reqs); EntMSM.Models.Users curr = Session["LoginUser"] as EntMSM.Models.Users; DataTable dt = null; DataTable dt1 = ConvertToDataTable(esd.ContactLists.Where(a => a.Uses_Id == curr.Id)); dt1.Columns["电话"].ColumnName = "LinkMobile"; if (reqs.Split('.')[1].ToUpper() == "CSV") { dt = ReadCsv(strPath, groupsId, curr);//csv } else { dt = ImportExcelFile(strPath, groupsId, curr); //ReadExcelByOledb(strPath, curr);//xls // dt.Columns["电话"].ColumnName = "LinkMobile"; } allCount = dt.Rows.Count; //去掉重复行 ,重复数据过滤 DataTable dd = DeleteSameRow(dt, "LinkMobile");//去除上传文件中重复的数据 DataTable ddt = ComPare2DataTable(dd, dt1, "LinkMobile");//出去已经存在数据库中的重复数据 int currCount = ddt.Rows.Count; for (int i = 0; i < ddt.Rows.Count; ) { //ddt.Rows[i][2] = System.Web.HttpUtility.HtmlEncode(ddt.Rows[i][2].ToString()); //ddt.Rows[i][3] = System.Web.HttpUtility.HtmlEncode(ddt.Rows[i][3].ToString()); //ddt.Rows[i][4] = System.Web.HttpUtility.HtmlEncode(ddt.Rows[i][4].ToString()); //ddt.Rows[i][5] = System.Web.HttpUtility.HtmlEncode(ddt.Rows[i][5].ToString()); if (ddt.Rows[i][2].ToString().Trim() == "" || ddt.Rows[i][2] == null || ddt.Rows[i][3].ToString().Trim() == "" || ddt.Rows[i][3] == null || ddt.Rows[i][4].ToString().Trim() == "" || ddt.Rows[i][4] == null) { ddt.Rows[i].Delete(); } else { if (!IsChiOrEng(ddt.Rows[i][2].ToString())) { ddt.Rows[i].Delete(); } else if (!IsPhone(ddt.Rows[i][3].ToString())) { ddt.Rows[i].Delete(); } else if (!IsEmail(ddt.Rows[i][4].ToString())) { ddt.Rows[i].Delete(); } else if (StrLenth(ddt.Rows[i][3].ToString())) { ddt.Rows[i].Delete(); } else if (StrLenth(ddt.Rows[i][4].ToString())) { ddt.Rows[i].Delete(); } else if (StrLenth(ddt.Rows[i][2].ToString())) { ddt.Rows[i].Delete(); } else { i++; } } } int twoCount = ddt.Rows.Count; if (currCount > 0) { sucCount = addTable(ddt); if (sucCount > 0) { result = "导入通讯录共计:" + allCount + "条\n\t导入成功:" + sucCount + "条\n\t过滤重复联系人:" + (allCount - currCount) + "条\n\t过滤错误数据:" + (currCount - twoCount) + "条"; } else { result = "导入通讯录共计:" + allCount + "条\n\t导入成功:" + sucCount + "条\n\t过滤重复联系人:" + (allCount - currCount) + "条\n\t过滤错误数据:" + (currCount - twoCount) + "条"; } } else { result = "导入通讯录共计:" + allCount + "条\n\t导入成功:" + sucCount + "条\n\t过滤重复联系人:" + (allCount - currCount) + "条\n\t过滤错误数据:" + (currCount - twoCount) + "条"; } if (System.IO.File.Exists(strPath)) //存在文件 { System.IO.File.Delete(strPath);//删除文件 } } catch { result = "文档内容格式有误,导入失败!"; } return result; } /// <summary> /// 替换html中的特殊字符 /// </summary> /// <param name="theString">需要进行替换的文本。</param> /// <returns>替换完的文本。</returns> public string HtmlEncode(string theString) { theString = theString.Replace(">", ">"); theString = theString.Replace("<", "<"); theString = theString.Replace("\"", """); theString = theString.Replace("\'", "'"); theString = theString.Replace("\n", "<br/> "); return theString; } #region 删除DataTable重复列,类似distinct /// <summary> /// 删除DataTable重复列,类似distinct /// </summary> /// <param name="dt">DataTable</param> /// <param name="Field">字段名</param> /// <returns></returns> public static DataTable DeleteSameRow(DataTable dt, string Field) { ArrayList indexList = new ArrayList(); // 找出待删除的行索引 for (int i = 0; i < dt.Rows.Count - 1; i++) { if (!IsContain(indexList, i)) { for (int j = i + 1; j < dt.Rows.Count; j++) { if (dt.Rows[i][Field].ToString() == dt.Rows[j][Field].ToString()) { indexList.Add(j); } } } } indexList.Sort(); // 排序 for (int i = indexList.Count - 1; i >= 0; i--)// 根据待删除索引列表删除行 { int index = Convert.ToInt32(indexList[i]); dt.Rows.RemoveAt(index); } return dt; } /// <summary> /// 判断数组中是否存在 /// </summary> /// <param name="indexList">数组</param> /// <param name="index">索引</param> /// <returns></returns> public static bool IsContain(ArrayList indexList, int index) { for (int i = 0; i < indexList.Count; i++) { int tempIndex = Convert.ToInt32(indexList[i]); if (tempIndex == index) { return true; } } return false; } #endregion /// <summary> /// 添加table /// </summary> /// <param name="dtt"></param> /// <returns></returns> public int addTable(DataTable dtt) { string a = ConfigurationManager.ConnectionStrings["EntSmsDbContext"].ToString(); SqlConnection con = new SqlConnection(a); SqlCommand cmd = new SqlCommand("select * from ContactList", con); SqlDataAdapter sda = new SqlDataAdapter(cmd); SqlCommandBuilder Builder = new SqlCommandBuilder(sda); sda.Fill(dtt); int states = sda.Update(dtt); return states; } /// <summary> /// 字符串长度 /// </summary> /// <param name="len"></param> /// <returns></returns> public bool StrLenth(string len) { if (IsChinese(len)) { if (len.ToString().Length > 25) { return true; } } else { if (len.ToString().Length > 50) { return true; } } return false; } /// <summary> /// 判断是否为Email /// </summary> /// <param name="s">字符串</param> /// <returns></returns> public static bool IsEmail(string s) { return Regex.IsMatch(s, @"^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$"); } /// <summary> /// 判断是否为手机号码格式 /// </summary> /// <param name="s">字符串</param> /// <returns></returns> public static bool IsPhone(string s) { return Regex.IsMatch(s, @"^(((13[0-9]{1})|14[0-9]{1}|15[0-9]{1}|18[0-9]{1})+\d{8})$"); } /// <summary> /// 判断是否为中文字符 /// </summary> /// <param name="s">字符串</param> /// <returns></returns> public static bool IsChinese(string s) { return Regex.IsMatch(s, @"[\u4e00-\u9fa5]"); } /// <summary> /// 验证用户名为中、英文 /// </summary> /// <param name="val"></param> /// <returns></returns> public static bool IsChiOrEng(string val) { string strRegex = @"[\u4e00-\u9fa5_a-zA-Z]"; return Regex.IsMatch(val, strRegex); } /// <summary> /// 判断是否为正整数 /// </summary> /// <param name="s">字符串</param> /// <returns></returns> public static bool IsInt(string s) { return Regex.IsMatch(s, @"^\d+$"); } #endregion /// <summary> /// 非法字符转换 /// </summary> /// <param name="str"></param> /// <returns></returns> public string ReplaceStr(string str) { //str=str.Replace(",",""); str = str.Replace("'", ""); str = str.Replace(";", ""); str = str.Replace(":", ""); str = str.Replace("/", ""); str = str.Replace("?", ""); str = str.Replace("<", ""); str = str.Replace(">", ""); str = str.Replace(".", ""); str = str.Replace("#", ""); str = str.Replace("%", ""); str = str.Replace("%", ""); str = str.Replace("^", ""); str = str.Replace("//", ""); str = str.Replace("@", ""); str = str.Replace("(", ""); str = str.Replace(")", ""); str = str.Replace("*", ""); str = str.Replace("~", ""); str = str.Replace("`", ""); str = str.Replace("$", ""); str = str.Replace("&", ""); str = str.Replace("\n", ""); return str; } } }