using System; using System.Data; using System.Configuration; using System.Collections; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Web.UI.HtmlControls; using System.IO; using NPOI.HSSF.UserModel; using NPOI.SS.UserModel; using NPOI.XSSF.UserModel; using System.Xml; using System.Collections.Generic; using System.Data.OleDb; using WeiSha.Common; namespace Song.Site.Manage.Utility { public partial class ExcelInput : System.Web.UI.UserControl { #region 属性,事件 public event EventHandler Input; //文档上传后的临时存放路径 private string _tempPathConfig = "Temp"; //Excel链接字符串 string connStr = "Provider=Microsoft.Ace.OleDb.12.0;data source={0};Extended Properties='Excel 12.0; HDR=NO; IMEX=1'"; /// /// 数据模板的名称 /// public string TemplateName { get { object obj = ViewState["TemplateName"]; return (obj == null) ? "" : obj.ToString(); } set { ViewState["TemplateName"] = value; } } /// /// 数据模板的路径 /// public string TemplatePath { get { object obj = ViewState["TemplatePath"]; return (obj == null) ? "" : obj.ToString(); } set { ViewState["TemplatePath"] = value; } } /// /// 记录Excel列名与数据库字段对应关系的配置文件的文件名 /// public string Config { get { object obj = ViewState["Config"]; return (obj == null) ? "" : obj.ToString(); } set { ViewState["Config"] = value; } } public List Keys { get { return GetKeys(); } } private DataTable _sheetData; /// /// 当前需要导入的工作薄的数据集 /// public DataTable SheetDataTable { get { return _sheetData; } set { _sheetData = value; } } private List _errorDataRow = new List(); /// /// 导入失败的数据集 /// public List ErrorDataRows { get { return _errorDataRow; } } private Dictionary _dataRelation; /// /// Excel列名与数据库字段对应关系,前者为Excel列名(key值),后者为数据库字段名(value值) /// public Dictionary DataRelation { get { return _dataRelation; } set { _dataRelation = value; } } #endregion protected void Page_Load(object sender, EventArgs e) { if (!this.IsPostBack) { //下载模板 linkDataTmp.NavigateUrl = this.ResolveUrl(this.TemplatePath); linkDataTmp.Text = linkDataTmp.Text.Replace("{0}", this.TemplateName); } } /// /// 添加导入失败的行数 /// /// public void AddError(DataRow dr) { _errorDataRow.Add(dr); } /// /// 第一步:上传数据文件 /// /// /// protected void btnUp_Click(object sender, EventArgs e) { try { if (fuLoad.PostedFile.FileName != "") { fuLoad.UpPath = _tempPathConfig; fuLoad.IsMakeSmall = false; fuLoad.IsConvertJpg = false; fuLoad.SaveAs(); ViewState["dataFilePath"] = fuLoad.File.Server.FileFullName; //工作簿 DataTable table = this.GetSheets(fuLoad.File.Server.FileFullName); dlWorkBook.DataSource = table; dlWorkBook.DataBind(); //状态 ltSheetCount.Text = table.Rows.Count.ToString(); // lbState.Text = "正在操作文档 《" + fuLoad.File.Client.FileName + "》"; btnNext1.Visible = true; lbFile2.Text = fuLoad.File.Client.FileName; // fdPanel1.Visible = false; fdPanel2.Visible = true; lbError2.Text = ""; //如果只有一个工作簿,直接跳到下一步 if (table.Rows.Count == 1) { foreach (DataListItem dli in dlWorkBook.Items) { Button lb = (Button)dli.FindControl("btnWorkBook"); btnSheet_Click(lb, null); break; } } } } catch (Exception ex) { lbError1.Text = ex.Message; } } /// /// 第二步:工作薄选择的按钮事件 /// /// /// protected void btnSheet_Click(object sender, EventArgs e) { lbFile3.Text = lbFile2.Text; //当前操作的工作簿 string sheetText = ((Button)sender).Text; lbSheet3.Text = "【" + sheetText.Substring(0, sheetText.IndexOf(":")) + "】共" + sheetText.Substring(sheetText.IndexOf(":") + 1); //要操作的Excel文件名与工作表名 string xlsFile = ViewState["dataFilePath"].ToString(); //工作簿的索引 int sheetIndex = Convert.ToInt32(((Button)sender).CommandArgument); ViewState["sheetIndex"] = sheetIndex; try { //DataTable dtRows = SheetToDatatable(xlsFile, sheetIndex); //if (dtRows.Rows.Count < 1) throw new Exception("当前工作簿没有数据"); //获取工作薄的列 DataTable dtColumn = this.GetSheetColumn(xlsFile, sheetIndex); dlColumn.DataSource = dtColumn; dlColumn.DataBind(); //预置的列与字段的对应关系 DataTable dtConfig = getConfig(); //自动识别excel中字段与数据库中字符匹配 for (int i = 0; i < dlColumn.Items.Count; i++) { DataListItem dli = dlColumn.Items[i]; //列名 Label lb = (Label)dli.FindControl("lbColumn"); //绑定对应关系的配置 DropDownList ddl = (DropDownList)dli.FindControl("ddlColumnForField"); ddl.DataSource = dtConfig; ddl.DataTextField = "Column"; ddl.DataValueField = "Field"; ddl.DataBind(); ddl.Items.Insert(0, new ListItem("", "")); //自动设置对应关系 setDataList(lb.Text, ddl); if (i > 30) break; } fdPanel2.Visible = false; fdPanel3.Visible = true; lbError3.Text = ""; } catch (Exception ex) { lbError2.Text = ex.Message; } } /// /// 第三步:导入数据的按钮事件 /// /// /// protected void btnInput_Click(object sender, EventArgs e) { fdPanel5.Visible = false; btnOutpt.Visible = false; try { //实际的列与字段的关系 this._dataRelation = getColumnForField(); //工作薄的数据 string file = ViewState["dataFilePath"].ToString(); int sheetIndex = Convert.ToInt32(ViewState["sheetIndex"].ToString()); this._sheetData = this.SheetToDatatable(file, sheetIndex); //***************** //执行导入数据的事件 if (Input != null) this.Input(sender, e); // lbFile4.Text = lbFile3.Text; lbSheet4.Text = lbSheet3.Text; fdPanel3.Visible = false; fdPanel4.Visible = true; //导入结果的处理 lbErrorCount.Text = ErrorDataRows.Count.ToString(); lbSuccCount.Text = (SheetDataTable.Rows.Count - ErrorDataRows.Count).ToString(); if (ErrorDataRows.Count > 0) { fdPanel5.Visible = true; btnOutpt.Visible = true; //错误的数据 DataTable dtErr = SheetDataTable.Clone(); foreach (DataRow dr in ErrorDataRows) { dtErr.ImportRow(dr); } gvError.DataSource = dtErr; gvError.DataBind(); } } catch (Exception ex) { lbError3.Text = ex.Message; } } #region 操作Excel的方法 /// /// 通过Excel文档,创建对应的处理对象 /// /// /// private IWorkbook createWorkbook(string xlsFile) { //创建工作薄对象 IWorkbook workbook = null; using (FileStream file = new FileStream(xlsFile, FileMode.Open, FileAccess.Read)) { //根据扩展名判断excel版本 string ext = xlsFile.Substring(xlsFile.LastIndexOf(".") + 1); //WorkbookFactory.Create(file); if (ext.ToLower() == "xls") workbook = new HSSFWorkbook(file); if (ext.ToLower() == "xlsx") workbook = new XSSFWorkbook(file); } return workbook; } /// /// 从Excel中读取一个工作薄,生成Datatable对象。 /// /// /// /// private DataTable SheetToDatatable(string xlsFile, int sheetIndex) { DataTable dt = new DataTable(); //创建工作薄对象 IWorkbook workbook = createWorkbook(xlsFile); ISheet sheet = workbook.GetSheetAt(sheetIndex); System.Collections.IEnumerator rows = sheet.GetRowEnumerator(); try { rows.MoveNext(); //创建Datatable结构 HSSFRow firsRow = (HSSFRow)rows.Current; for (int i = 0; i < firsRow.LastCellNum; i++) { ICell cell = firsRow.GetCell(i); if (cell == null || string.IsNullOrWhiteSpace(cell.ToString())) continue; dt.Columns.Add(new DataColumn(cell.ToString(), getColumnType(cell.ToString()))); } //导入工作薄的数据 while (rows.MoveNext()) { HSSFRow row = (HSSFRow)rows.Current; DataRow dr = dt.NewRow(); for (int i = 0; i < dt.Columns.Count; i++) { ICell cell = row.GetCell(i); if (cell == null) continue; string value = cell.ToString(); //读取Excel格式,根据格式读取数据类型 switch (dt.Columns[i].DataType.FullName) { case "System.DateTime": //日期类型 if (DateUtil.IsValidExcelDate(cell.NumericCellValue)) { try { value = cell.DateCellValue.ToString(); } catch { value = cell.ToString(); } } else { value = cell.NumericCellValue.ToString(); } break; default: value = cell.ToString(); break; } dr[i] = WeiSha.Common.Param.Method.ConvertToAnyValue.Get(value).ChangeType(dt.Columns[i].DataType); } dt.Rows.Add(dr); } } catch { return dt; } return dt; } /// /// 获取列的数据类型 /// /// /// private System.Type getColumnType(string colname) { DataTable dtConfing = getConfig(); System.Type type=null; foreach (DataRow dr in dtConfing.Rows) { if (colname.ToLower().Trim() == dr["Column"].ToString().ToLower().Trim()) { if (dr["DataType"].ToString().ToLower().Trim() == "date") type = Type.GetType("System.DateTime"); } } if (type == null) type = Type.GetType("System.String"); return type; } /// /// 获取文档中的所有工作薄 /// /// /// private DataTable GetSheets(string xlsFile) { DataTable dt = new DataTable(); dt.Columns.Add(new DataColumn("Name")); dt.Columns.Add(new DataColumn("Count")); //创建工作薄对象 IWorkbook workbook = createWorkbook(xlsFile); int sheetNum = workbook.NumberOfSheets; for (int i = 0; i < sheetNum; i++) { DataRow dr = dt.NewRow(); dr["Name"] = workbook.GetSheetAt(i).SheetName; dr["Count"] = workbook.GetSheetAt(i).LastRowNum; dt.Rows.Add(dr); } return dt; } /// /// 获取工作薄的列表,即第一行的标题 /// /// /// /// private DataTable GetSheetColumn(string xlsFile, int sheetIndex) { DataTable dtSch = new DataTable("SheetStructure"); dtSch.Columns.Add(new DataColumn("Name", Type.GetType("System.String"))); //创建工作薄对象 IWorkbook workbook = createWorkbook(xlsFile); ISheet sheet = workbook.GetSheetAt(sheetIndex); System.Collections.IEnumerator rows = sheet.GetRowEnumerator(); rows.MoveNext(); //创建Datatable结构 IRow firsRow = (IRow)rows.Current; for (int i = 0; i < firsRow.LastCellNum; i++) { DataRow dr = dtSch.NewRow(); ICell cell = firsRow.GetCell(i); dr["Name"] = cell == null ? "(null)" + i : cell.ToString(); dtSch.Rows.Add(dr); } return dtSch; } #endregion #region 处理字段对比的方法 /// /// 通过字段,获取对应的列名 /// /// /// public string GetColumnForField(string field) { Dictionary dic = this._dataRelation; if (dic.Count < 1) return ""; foreach (KeyValuePair kvp in dic) { if (kvp.Value == field) return kvp.Key; } return ""; } /// /// 获取主键 /// /// public List GetKeys() { List keys = new List(); //配置文件的路径 string path = App.Get["ExcelInputConfig"].VirtualPath; string config = this.Server.MapPath(path + this.Config); if (!System.IO.File.Exists(config)) return keys; //填充表 XmlDocument resXml = new XmlDocument(); resXml.Load(config); //获取主键 XmlNode ele = resXml.LastChild; if (ele.Attributes["Keys"] == null) return keys; string[] keyscol = ele.Attributes["Keys"].Value.Split(','); //匹配项的配置数据 XmlNodeList nodes = resXml.GetElementsByTagName("item"); // foreach (string k in keyscol) { foreach (XmlNode n in nodes) { string column = ((XmlElement)n).Attributes["Column"].Value; string field = ((XmlElement)n).Attributes["Field"].Value; if (k.Trim().ToLower() == column.Trim().ToLower()) { keys.Add(field.Trim()); } } } return keys; } /// /// 通过列名,获取对应的字段 /// /// /// public string GetFieldForColumn(string column) { Dictionary dic = this._dataRelation; if (dic.Count < 1) return ""; foreach (KeyValuePair kvp in dic) { if (kvp.Key == column) return kvp.Value; } return ""; } /// /// 获取列名与字段名的对应关系的设置 /// private DataTable getConfig() { //构造表 DataTable dt = new DataTable(); dt.Columns.Add(new DataColumn("Column", Type.GetType("System.String"))); dt.Columns.Add(new DataColumn("Field", Type.GetType("System.String"))); dt.Columns.Add(new DataColumn("DataType", Type.GetType("System.String"))); dt.Columns.Add(new DataColumn("Format", Type.GetType("System.String"))); //配置文件的路径 string path = App.Get["ExcelInputConfig"].VirtualPath; string config = this.Server.MapPath(path + this.Config); if (!System.IO.File.Exists(config)) return dt; //填充表 XmlDocument resXml = new XmlDocument(); resXml.Load(config); XmlNodeList nodes = resXml.GetElementsByTagName("item"); foreach (XmlNode n in nodes) { XmlElement el = (XmlElement)n; DataRow dr = dt.NewRow(); dr["Column"] = el.Attributes["Column"].Value; dr["Field"] = el.Attributes["Field"].Value; dr["DataType"] = el.Attributes["DataType"] != null ? el.Attributes["DataType"].Value : null; dr["Format"] = el.Attributes["Format"] != null ? el.Attributes["Format"].Value : null; dt.Rows.Add(dr); } return dt; } /// /// 获取实际的列与字段的关系,Dictionary 前者为列名,后者为字段名 /// /// private Dictionary getColumnForField() { Dictionary dic = new Dictionary(); for (int i = 0; i < dlColumn.Items.Count; i++) { DataListItem dli = dlColumn.Items[i]; //列名、对应的字段 Label lb = (Label)dli.FindControl("lbColumn"); DropDownList ddl = (DropDownList)dli.FindControl("ddlColumnForField"); if (!dic.ContainsKey(lb.Text)) dic.Add(lb.Text, ddl.SelectedValue); } return dic; } /// /// 设置下拉选框中的哪个项,为选种状态 /// /// 字段名称(对应数据库说明) /// private void setDataList(string label, DropDownList ddl) { for (int i = 0; i < ddl.Items.Count; i++) { if (label == ddl.Items[i].Text) { ddl.Items[i].Selected = true; return; } } for (int i = 0; i < ddl.Items.Count; i++) { if (isExts(label, ddl.Items[i].Text)) { ddl.Items[i].Selected = true; break; } } } /// /// 判断前者字符,是否存在于后者 /// /// /// /// private bool isExts(string ea, string str) { bool isExt = false; if (ea.Trim() == str.Trim()) return true; if (str.IndexOf(ea) > -1) isExt = true; if (ea.Length > 2) { for (int i = 0; i <= (ea.Length - 2); i++) { string t = ea.Substring(i, 2); if (str.IndexOf(t) > -1) { isExt = true; break; } } } return isExt; } #endregion #region 导航按钮 protected void btnBack2_Click(object sender, EventArgs e) { fdPanel1.Visible = true; fdPanel2.Visible = false; } protected void btnBack_Click(object sender, EventArgs e) { fdPanel2.Visible = true; fdPanel3.Visible = false; } /// /// 继续导入其它的工作簿 /// /// /// protected void btnBack4_Click(object sender, EventArgs e) { fdPanel2.Visible = true; fdPanel4.Visible = false; lbError2.Text = ""; fdPanel5.Visible = false; } /// /// 继续导入Excel文档 /// /// /// protected void btnBack5_Click(object sender, EventArgs e) { fdPanel1.Visible = true; fdPanel4.Visible = false; lbState.Text = "等待上传……"; btnNext1.Visible = false; lbError1.Text = ""; fdPanel5.Visible = false; } protected void btnNext1_Click(object sender, EventArgs e) { fdPanel1.Visible = false; fdPanel2.Visible = true; } #endregion #region 导出错误数据 /// /// 导出错误数据 /// /// /// protected void btnOutpt_Click(object sender, EventArgs e) { //创建Excel对象 HSSFWorkbook hssfworkbook = new HSSFWorkbook(); //创建工作簿对象 ISheet sheet = hssfworkbook.CreateSheet(this.TemplateName); //sheet.DefaultColumnWidth = 30; //创建数据行对象 IRow rowHead = sheet.CreateRow(0); //生成表头 for (int i = 0; i < gvError.HeaderRow.Cells.Count; i++) { string txt = gvError.HeaderRow.Cells[i].Text; txt = txt.Replace(" ", ""); rowHead.CreateCell(i).SetCellValue(txt); } //生成数据行 ICellStyle style_size = hssfworkbook.CreateCellStyle(); style_size.WrapText = true; for (int i = 0; i < gvError.Rows.Count; i++) { IRow row = sheet.CreateRow(i + 1); GridViewRow gvr = gvError.Rows[i]; for (int j = 0; j < gvr.Cells.Count; j++) { string txt = gvr.Cells[j].Text; if (string.IsNullOrEmpty(txt)) continue; txt = txt.Replace(" ", ""); txt = txt.Replace("\n", ""); txt = txt.Replace("\r", ""); ICell cell = row.CreateCell(j); cell.SetCellValue(txt.Trim()); cell.CellStyle = style_size; if (txt.Length > 20) { cell.Sheet.SetColumnWidth(j, 100 * 256); } } } //创建文件 string filePath = Upload.Get["Temp"].Physics + WeiSha.Common.Server.LegalName(this.TemplateName + "-导入错误-" + DateTime.Now.ToLongDateString()) + ".xls"; FileStream file = new FileStream(filePath, FileMode.Create); hssfworkbook.Write(file); file.Close(); if (System.IO.File.Exists(filePath)) { FileInfo fileInfo = new FileInfo(filePath); Response.Clear(); Response.ClearContent(); Response.ClearHeaders(); Response.AddHeader("Content-Disposition", "attachment;filename=" + HttpUtility.UrlEncode(fileInfo.Name)); Response.AddHeader("Content-Length", fileInfo.Length.ToString()); Response.AddHeader("Content-Transfer-Encoding", "binary"); Response.ContentType = "application/-excel"; Response.ContentEncoding = System.Text.Encoding.Default; Response.WriteFile(fileInfo.FullName); Response.Flush(); Response.End(); } } #endregion } }