总体博文已迁移到博客园:http://www.cnblogs.com/csqb-511612371/p/4891492.html html
其实需求很明确,就是一大堆不同的excel,每张excel对应数据库的一张表,咱们须要提供用户上传excel,咱们解析数据入库的功能实现。node
那么,这就涉及到一个问题:咱们能够读出excel的表头,可是怎么知道每一个表头具体对应数据库里面的字段呢?数据库
博主通过一段时间的思考与构思,想到一法:如今的状况是咱们有excel表A,对应数据库表B,可是A与B具体属性字段的映射关系咱们不知。那咱们是否是能够有一个A到B的映射文件C呢?c#
我想,说到这,你们就很明了了...spa
第一步:为每张excel建立一个与数据库表对应的映射文件(xml配置文件),咱们称之为规则集,固然,咱们的需求是excel的列表头不变(顺序可换---缘由请继续往下看)设计
<?xml version="1.0" encoding="utf-8" ?> <module> <add firstHeaderRow="5" lastHeaderRow="7" sheetCount="1" Supplementary="0" /> <add headerText="年份" propertyName="Year" dataType="System.Int32"/> <add headerText="国内生产总值" propertyName="GDPValue" dataType="System.double"/> <add headerText="第一产业" propertyName="PrimaryIndustryAmount" dataType="System.double"/> <add headerText="第二产业" propertyName="SecondaryIndustry_TotalAmount" dataType="System.double"/> <add headerText="工业" propertyName="SecondaryIndustry_Industry" dataType="System.double"/> <add headerText="建筑业" propertyName="SecondaryIndustry_Construction" dataType="System.double"/> <add headerText="第三产业" propertyName="ThirdIndustryAmount" dataType="System.double"/> <add headerText="人均国内生产总值(元)" propertyName="GDPPerPerson" dataType="System.double"/> </module>
固然,这个xml文件因为是咱们本身定义的节点,因此每一个单词的意义就不详细解释了。excel
附:excel原表以下:code
其中【剔除行关键字】在后续详细代码中介绍,请继续关注微博。xml
表头含有层级结构,具体读取方法也在后续详细代码中介绍...今天之讲述设计思想与部分基础代码。htm
第二步:新建一个读取咱们本身定义的xml文件的类 RegularXMLReaderService.cs:
public class RegularXMLReaderService : IRegularXMLReaderService { public List<Regular> GetXMLInfo(string xmlpath) { //xmlpath为xml的路径名称 var reader = new XmlTextReader(xmlpath); var doc = new XmlDocument(); //从指定的XMLReader加载XML文档 doc.Load(reader); var headerList = new List<Regular>(); foreach (XmlNode node in doc.DocumentElement.ChildNodes) { var header = new Regular(); if (node.Attributes["firstHeaderRow"] != null) header.HeaderRegular.Add("firstHeaderRow", int.Parse(node.Attributes["firstHeaderRow"].Value)); if (node.Attributes["lastHeaderRow"] != null) header.HeaderRegular.Add("lastHeaderRow", int.Parse(node.Attributes["lastHeaderRow"].Value)); if (node.Attributes["sheetCount"] != null) header.HeaderRegular.Add("sheetCount", int.Parse(node.Attributes["sheetCount"].Value)); if (node.Attributes["ExcelType"] != null) header.HeaderRegular.Add("ExcelType", int.Parse(node.Attributes["ExcelType"].Value)); if (node.Attributes["Supplementary"] != null) header.HeaderRegular.Add("Supplementary", int.Parse(node.Attributes["Supplementary"].Value)); if (node.Attributes["headerText"] != null) header.HeaderText = node.Attributes["headerText"].Value; if (node.Attributes["propertyName"] != null) header.PropertyName = node.Attributes["propertyName"].Value; if (node.Attributes["dataType"] != null) header.DataType = node.Attributes["dataType"].Value; headerList.Add(header); } return headerList; } }
这段代码相信你们都能看懂,不作详细解释。其中设计到一个规则集类Regular.cs
/// <summary> /// 模板规则类 /// </summary> public class Regular { /// <summary> /// 表头文本 --对应excel表头名称 /// </summary> public string HeaderText { set; get; } /// <summary> /// 属性名称 --对应数据库字段名称 /// </summary> public string PropertyName { set; get; } /// <summary> /// 数据类型 ---对应数据库字段类型(用做判断excel数据是否合法用) /// </summary> public string DataType { set; get; } private Dictionary<string, int> _regular = new Dictionary<string, int>(); /// <summary> /// 表头规则 --咱们所定义的具体规则,如咱们文中例子的起始行、结束行、表单数等等 /// </summary> public Dictionary<string, int> HeaderRegular { get { return _regular; } set { _regular = value; } } }
这个类根据具体需求可能会有所不一样,具体随设计而改变。
第三步:建立一个解析excel数据的类(excel越多越复杂,实现就越困难),此处先假设已建好(详细代码请关注后续博客)
/// <summary> /// Excel表格检查与数据读取接口 /// </summary> public interface IExcelImportService { /// <summary> /// 初始化Excel数据及配置文件 /// </summary> /// <param name="filePath">Excel文件</param> /// <param name="xmlPath">配置文件</param> /// <param name="nullable">能够为空</param> void InitDataAndConfig(string filePath, string xmlPath, bool nullable); /// <summary> /// 综合验证Excel表格符合性 /// </summary> /// <param name="customValidate">某单元项自定义检验接口</param> /// <returns></returns> UploadExcelFileResult ValidateExcel(ISpecification<KeyValuePair<string, string>> customValidate); /// <summary> /// 导入EXCEL文件 /// </summary> /// <typeparam name="TableDTO">数据对象DTO</typeparam> /// <returns>EXCEL数据集合</returns> List<TableDTO> Import<TableDTO>(); /// <summary> /// 导入EXCEL 文件------矩阵类模板 /// 19.6-长江干线货物流量流向 /// 20.5-西江航运干线货物流量流向 /// </summary> /// <typeparam name="TableDTO"></typeparam> /// <returns></returns> List<TableDTO> ImportForMatrix<TableDTO>(); }
此处是已建好的解析excel接口。(具体实现请参考后续博客)
博主的设计理念是:用户上传一个excel后咱们后台分三步走:
一、初始化数据(excel文件流、对应配置文件--咱们的规则集xml文件、以及一些其余的配置参数)
二、验证excel里面的数据合格(经过验证表头能够断定用户是否错误上传excel文件,验证里面数据是否违规(格式错误等)等等须要验证的方面)。验证成功后返回基础表头、附加信息等数据让用户确认并提交;失败后提示具体失败缘由,准肯定位到失败数据行列数。
三、用户看到验证经过的返回结果,确认无误后点击提交,此时读取数据入库。
至此,咱们整个解析读取入库excel的流程就完成了,重在设计规则类这个设计思想,其中涉及到不少具体实现的代码,请参考后续博客专题。
总体博文已迁移到博客园:http://www.cnblogs.com/csqb-511612371/p/4891492.html