#region using System; using System.Collections.Generic; using System.Data; using System.Data.Common; using System.Data.OleDb; using CSFrameworkV5.Common; using CSFrameworkV5.Core; using CSFrameworkV5.Library.CommonForms; #endregion namespace CSFrameworkV5.Library.CommonClass { /// /// 导入数据通用接口 /// public interface IImporterSource { /// /// 是否连接 /// bool IsConnected { get; } /// /// 创建连接 /// /// DbConnection CreateConnection(); /// /// 获取用于预览的数据 /// /// DataTable GetData(string tableName); /// /// 取数据库清单 /// /// List GetDatabaseList(); /// /// 取表结构 /// /// List GetFields(string tableName); /// /// 取数据 /// /// /// DataTable GetTable(string tableName, string orderBy); /// /// 取数据库中所有资料表 /// /// List GetTableNameList(); /// /// 测试连接 /// /// bool TestConnection(out string msg); } /// /// 导入数据到目标表的接口 /// public abstract class IImporterTarget { protected DataTable _DataSource; protected DataTable _DataTarget; private List _ReportList = new List(); protected string _ReportTitle = "导入数据"; public IImporterTarget() { } public IImporterTarget(DataTable dataTarget) { _DataTarget = dataTarget; } /// /// 本次导入错误信息 /// public string ErrorInfo { get; set; } /// /// 返回导入的记录数 /// public int LastImportCounter { get; set; } /// /// 导入失败的记录数 /// public int LastImportFailed { get; set; } protected void AddReport(bool isError, string stepText, string content, string refID) { if (_ReportList != null) _ReportList.Add(new OperateReportItem(isError, stepText, refID, content)); } protected virtual void BeginImport(DataTable dataSource) { } /// /// 清空目标表的数据 /// public abstract void ClearData(); protected virtual void EndImport(int success, int failed) { } /// /// 获取目标表的字段清单 /// /// /// public List GetFieldList() { var fieldListTarget = new List(); foreach (DataColumn col in _DataTarget.Columns) fieldListTarget.Add(new FieldEntity(col.ColumnName, col.ColumnName)); return fieldListTarget; } protected virtual object GetFieldValue(DataRow sourceRow, DataRow targetRow, FieldMapping mapping) { var T = targetRow.Table.Columns[mapping.TargetField].DataType; var o = sourceRow[mapping.SourceField]; //日期类型兼容 if (T == typeof(DateTime)) { if (o == null || o.ToStringEx().Trim() == string.Empty) return DBNull.Value; return ConvertEx.ToDateTime(o); } if (T == typeof(int) || T == typeof(int) || T == typeof(long)) return ConvertEx.ToInt(o); if (T == typeof(double) || T == typeof(float) || T == typeof(decimal)) return ConvertEx.ToDecimal(o); return sourceRow[mapping.SourceField]; } /// /// 获取字段映射关系 /// /// public abstract List GetMapping(); /// /// 开始导入数据 /// /// 数据源 /// 字段映射 /// 进度条控件 /// 返回操作报告 public virtual List Import( DataTable source, List fieldMapping, IProgressBar progress) { _DataSource = source; _ReportList.Clear(); LastImportCounter = 0; LastImportFailed = 0; progress.Position = 1; progress.MinValue = 0; progress.MaxValue = source.Rows.Count; progress.Reset(); DataRow targetRow; var isImport = false; //需要导入当前记录 var index = 0; //开始导入 BeginImport(_DataSource); foreach (DataRow R in source.Rows) { if (IsEmptyRow(R)) continue; //不导入空记录 index = source.Rows.IndexOf(R); targetRow = _DataTarget.NewRow(); foreach (var mp in fieldMapping) if (mp.SourceField != "" && mp.TargetField != "") { isImport = true; //有匹配成功的字段 targetRow[mp.TargetField] = GetFieldValue(R, targetRow, mp); } //没有映射关系的字段不导入数据 if (isImport) //当前记录需要导入 { targetRow.EndEdit(); var errMsg = ""; //提交数据 if (PostImportedData(targetRow, out errMsg)) { _ReportList.Add(new OperateReportItem(false, _ReportTitle, "行号:" + index.ToStringEx(), "导入成功.")); LastImportCounter++; } else { _ReportList.Add(new OperateReportItem(true, _ReportTitle, "<错误行:" + index.ToStringEx() + ">", errMsg)); LastImportFailed++; } } progress.Position++; } AddReport(false, _ReportTitle, "导入结束。", ""); AddReport(false, _ReportTitle, string.Format("成功{0},失败{1}", LastImportCounter, LastImportFailed), ""); EndImport(LastImportCounter, LastImportFailed); return _ReportList; } protected bool IsEmptyRow(DataRow R) { var str = ""; for (var i = 0; i <= R.Table.Columns.Count - 1; i++) { str = ConvertEx.ToString(R[i]).Trim(); str = str.Replace("0", "").Replace(".", ""); if (str != "") return false; } return true; } /// /// 匹配字段名 /// /// /// /// public string MatchField(string fieldName) { foreach (DataColumn col in _DataTarget.Columns) if (col.ColumnName.Trim() == fieldName.Trim()) return fieldName.Trim(); return ""; } /// /// 提交数据 /// /// 当前记录 /// protected abstract bool PostImportedData(DataRow drTarge, out string errMsg); } /// /// 数据导入接口基类 /// public class ImporterDataSourceBase : IImporterSource { #region IImporterDataSource Members public virtual DbConnection CreateConnection() { throw new Exception("CreateConnection方法没有实现!"); } public virtual bool TestConnection(out string msg) { msg = ""; try { using (var conn = CreateConnection()) { conn.Open(); conn.Close(); return true; } } catch (Exception ex) { msg = "连接数据库失败!" + ex.Message; return false; } } /// /// 是否连接 /// public bool IsConnected { get { string msg; return TestConnection(out msg); } } public virtual DataTable GetTable(string tableName, string orderBy) { throw new Exception("GetTable方法没有实现!"); } /// /// 取所有表名 /// /// public virtual List GetTableNameList() { var list = new List(); using (var conn = CreateConnection()) { var dt = conn.GetSchema("Tables"); foreach (DataRow row in dt.Rows) if (row[3].ToStringEx() == "TABLE" || row[3].ToStringEx() == "BASE TABLE") list.Add(row[2].ToStringEx()); } return list; } /// /// 取指定表所有字段名称 /// /// public virtual List GetFields(string tableName) { var list = new List(); DbConnection conn = null; OleDbCommand cmd = null; OleDbDataReader dr = null; try { using (conn = CreateConnection()) { using (cmd = new OleDbCommand()) { var sql = "SELECT TOP 1 * FROM " + tableName; cmd.CommandText = CodeSafeHelper.GetSafeSQL(sql); cmd.Connection = conn as OleDbConnection; using (dr = cmd.ExecuteReader()) { for (var i = 0; i < dr.FieldCount; i++) list.Add(dr.GetName(i)); } } } } finally { if (conn != null) conn.Dispose(); if (cmd != null) cmd.Dispose(); if (dr != null) dr.Dispose(); } return list; } public virtual List GetDatabaseList() { throw new Exception("GetDatabaseList方法没有实现!"); } /// /// 获取用于预览的数据 /// /// public virtual DataTable GetData(string tableName) { return GetTable(tableName, ""); } #endregion } /// /// 从Excel文件导入数据 /// public class ImportDataFromExcel : ImporterDataSourceBase { private string _FileName = ""; public ImportDataFromExcel(string fileName) { _FileName = fileName; } public override DbConnection CreateConnection() { // IMEX=1 可把混合型作为文本型读取,避免null值 var conn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + _FileName + ";Extended Properties='Excel 8.0;HDR=False;IMEX=1'"; return new OleDbConnection(conn); } public override DataTable GetTable(string tableName, string orderBy) { DataTable dt = null; var sql = "SELECT * FROM " + tableName + (!string.IsNullOrWhiteSpace(orderBy) ? " ORDER BY " + orderBy : ""); using (var conn = CreateConnection()) { var cmd = conn.CreateCommand() as OleDbCommand; cmd.CommandText = CodeSafeHelper.GetSafeSQL(sql); dt = new DataTable(); DbDataAdapter adp = new OleDbDataAdapter(cmd); adp.Fill(dt); } return dt; } } /// /// 字段实体类定义 /// public class FieldEntity { private string _FieldName; private string _TitleName; public FieldEntity(string fieldName, string titleName) { _FieldName = fieldName; _TitleName = titleName; } public string FieldName { get => _FieldName; set => _FieldName = value; } public string TitleName { get => _TitleName; set => _TitleName = value; } } /// /// 字段名称映射 /// public class FieldMapping { private string _SourceField; private string _TargetField; public FieldMapping(string sourceField, string targetField) { _SourceField = sourceField; _TargetField = targetField; } /// /// 映射关系是否有效 /// public bool IsValid => !string.IsNullOrEmpty(_SourceField) && !string.IsNullOrEmpty(_TargetField); /// /// 来源字段 /// public string SourceField { get => _SourceField; set => _SourceField = value; } /// /// 目标表字段 /// public string TargetField { get => _TargetField; set => _TargetField = value; } } /// /// 进度条 /// public interface IProgressBar { int MaxValue { get; set; } int MinValue { get; set; } int Position { get; set; } void Reset(); } }