博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
NPOI操作EXCEL(二)——大量不同模板时设计方式
阅读量:5128 次
发布时间:2019-06-13

本文共 9496 字,大约阅读时间需要 31 分钟。

上一篇文章介绍了一些NPOI的基础接口,我们现在就来看看具体怎么用NPOI来解析一个EXCEL。

博主现在有这么一堆excel需要解析数据入库:

当然这只是员工的简要模板,还有很多其他的模板。我们可以要求线下人员把表头都做成像这样的表头,但是数据的列数与各列内容是不受我们所控制的。那么我们需要的就是一个公用的方法,能够解析这一类表头的excel数据。

既然每种表对应着一张数据库表,字段不一样,那么我们的方法就考虑到使用反射机制来给泛型DTO属性赋值。具体每个excel表的各列与DTO属性字段的对应以及表本身信息我们用XML文件来做配置。OK,我们得到下面的一个基本流程:

1.用户上传excel文件,调用uploadExcelFile()接口

2.uploadExcelFile()接口保存文件到指定路径,调用excel解析工具类ImportExcel()方法,传入泛型参数ExcelDataDTO与excel配置文件xml路径

3.ImportExcel()服务首先验证excel数据(表头与xml是否匹配,各单元格数据格式,空格等等)

4.验证通过后调用获取数据方法,失败值直接返回具体失败数据(定位到每一行的某一列,并附带具体错误原因)

 

OK,那我们先来看看excel的配置xml文件具体怎么配置:

1 
2
3
4
5
6
7
8
9
10

再写一个读取excel配置xml文件的方法:

1         // 读取XML配置信息集 2         public List
GetXMLInfo(string xmlpath) 3 { 4 var reader = new XmlTextReader(xmlpath); 5 var doc = new XmlDocument(); 6 doc.Load(reader); 7 8 var headerList = new List
(); 9 foreach (XmlNode node in doc.DocumentElement.ChildNodes)10 {11 var header = new Regular();12 13 if (node.Attributes["firstHeaderRow"] != null)14 header.HeaderRegular.Add("firstHeaderRow", int.Parse(node.Attributes["firstHeaderRow"].Value));15 if (node.Attributes["lastHeaderRow"] != null)16 header.HeaderRegular.Add("lastHeaderRow", int.Parse(node.Attributes["lastHeaderRow"].Value));17 if (node.Attributes["sheetCount"] != null)18 header.HeaderRegular.Add("sheetCount", int.Parse(node.Attributes["sheetCount"].Value));19 20 if (node.Attributes["headerText"] != null)21 header.HeaderText = node.Attributes["headerText"].Value;22 if (node.Attributes["propertyName"] != null)23 header.PropertyName = node.Attributes["propertyName"].Value;24 if (node.Attributes["dataType"] != null)25 header.DataType = node.Attributes["dataType"].Value;26 27 headerList.Add(header);28 }29 return headerList;30 }

其中涉及到一个我们自己创建的规则类,Regular

1     ///  2     /// 模板规则类 3     ///  4     public class Regular 5     { 6         ///  7         /// 表头文本 8         ///  9         public string HeaderText { set; get; }10 11         /// 12         /// 属性名称13         /// 14         public string PropertyName { set; get; }15 16         /// 17         /// 数据类型18         /// 19         public string DataType { set; get; }20 21         private Dictionary
_regular = new Dictionary
();22 23 ///
24 /// 表头规则25 /// 26 public Dictionary
HeaderRegular27 {28 get { return _regular; }29 set { _regular = value; }30 }31 }

这样,我们就能将一个excel的配置信息读取出来备用。

 

具体上传文件的接口就不在这儿粘贴了,以前有一篇文章介绍过wenAPI做文件上传,地址:

http://www.cnblogs.com/csqb-511612371/p/4871574.html

我们在文件上传成功后的逻辑是调用服务ImportExcel,解析出excel数据到DTO,然后再将DTO映射到实体入库。

那么就会有这样一段代码:

1                             var xmlName = getXml();// 自己定义的获取配置文件名称方法 2                             var excelDataDtos = new List
(); 3 var result = attachmentFileService.ImportExcel(excelFilePath, xmlName, ref excelDataDtos); 4 if (result.Success) 5 {
9 foreach (var excelDataDto in excelDataDtos)10 {
// 数据入库19 employeeInfoService.HR_Add_EmployeeInfo(excelDataDto);20 } }
ExcelDataDTO是我们对应这个excel文件的DTO,此处简要的直接new了,也应该是单独服务产生(因为我们这个方法是实现多模板上传)。
第3行ImportExcel方法中将执行逻辑:获取基础配置信息->验证excel数据->读取excel数据
1        public UploadExcelFileResult ImportExcel(string filePath, string xmlPath, ref List
excelDTO) 2 { 3 // XML配置文件绝对路径 4 var xmlFilePath = ExcelTemplateBasePath + xmlPath; 5 6 var excelImportService = new ExcelImportService(filePath, xmlFilePath); 7 var result = excelImportService.ValidateExcel(); 8 if (result.Success) 9 {10 excelDTO = excelImportService.Import
();11 }12 return result;13 }

注:

1.第6行初始化excel导入服务(初始化基本配置信息)

2.第7行验证excel数据,失败则返回具体错误信息

3.验证通过则读取excel数据到DTO

这儿的excelImportService就涉及到整个excel解析工具了,我们先看看整个excel解析的接口与实现文件:

其中Regular前面已经讲过了,是规则集。UploadExcelFileResult则是解析返回结果,内含成功与否,总Message,文件信息,具体错误信息等数据:

///     /// EXCEL文件上传检查返回数据    ///     public class UploadExcelFileResult    {        ///         /// 是否成功        ///         public bool Success { get; set; }        ///         /// 附带消息        ///         public string Message { get; set; }        ///         /// 文件基本信息        ///         public FileMessage FileMessage { get; set; }        ///         /// 解析失败后错误位置定位信息        ///         public List
ExcelFileErrorPositions { get; set; } } public class FileMessage { ///
/// 上传文件名称 /// public string FileName { get; set; } ///
/// 文件大小 /// public int Length { get; set; } ///
/// 文件类型 /// public string Type { get; set; } } public class ExcelFileErrorPosition { ///
/// 错误行 /// public int RowIndex { get; set; } ///
/// 错误列集 /// public List
CellIndex { get; set; } ///
/// 错误列具体错误信息 /// public List
ErrorMessage { get; set; } ///
/// 错误行数据 /// public List
RowContent { get; set; } }

然后我们来看具体的三个接口:

1.IExcelParseBaseService接口是最基础服务接口,里面包含所有需要用到的抽象方法:

1     ///  2     /// EXCEL解析基本服务接口 3     ///  4     public interface IExcelParseBaseService 5     { 6         ///  7         /// 检查单元格数据类型 8         ///  9         /// 类型10         /// 单元格值11         /// 
类型是否出错
12 bool CheckDataType(string cellType, string cellValue);13 14 /// 15 /// 检查单元格数据是否为空16 /// 17 /// 单元格值18 /// 行空值计数器19 ///
数据是否为空
20 bool CheckNull(string cellValue, ref int nullcount);21 22 /// 23 /// 去除数据空格24 /// 25 /// 单元格值26 void ReplaceSpace(ref string cellValue);27 28 /// 29 /// 判断当前单元格是否为合并单元格30 /// 31 /// 单元格所在列序号32 /// 单元格所在行序号33 /// EXCEL工作表34 ///
合并单元格为true
35 bool IsMergedRegionCell(int cellIndex, int rowIndex, ISheet sheet, ref int firstRegionRow);36 37 /// 38 /// 读取EXCEL XML配置信息集39 /// 40 /// xml文件路径41 ///
42 List
GetXMLInfo(string xmlpath);43 }

它的实现类是抽象类ExcelParseBaseService

 

2.IExcelAnalyzeService接口是excel解析的核心服务,实现对excel的操作

1     ///  2     /// EXCEL 解析基础服务 3     ///  4     public interface IExcelAnalyzeService 5     { 6         ///  7         /// 获取指定excel文件版本 8         ///  9         /// EXCEL文件名称10         /// 
11 int GetExcelEdition(string fileName);12 13 /// 14 /// 根据EXCEL版本创建WorkBook15 /// 16 /// EXCEL版本17 /// EXCEL文件18 ///
excel文件对应workbook
19 IWorkbook CreateWorkBook(int edition, Stream excelFileStream);20 21 /// 22 /// 解析并检查EXCEL表头数据23 /// 24 /// 25 /// 26 /// 27 ///
28 Dictionary
GetExcelHeaders(ISheet sheet, ref UploadExcelFileResult uploadExcelFileResult,29 List
list);30 31 ///
32 /// 读取EXCEL数据33 /// 34 ///
数据对象
35 ///
工作簿对应工作表36 ///
excel工作表名称37 ///
该excel规则集38 ///
表头字典39 ///
总数据行数40 ///
解析后的Excel数据集
41 List
GetExcelDatas
(ISheet sheet, string sheetName, List
list,42 Dictionary
dict, int rowCount);43 44 ///
45 /// 检查excel数据46 /// 47 ///
excel工作表48 ///
规则集49 ///
表头50 ///
总数据行数51 ///
检查结果
52 UploadExcelFileResult CheckExcelDatasEnableNull(ISheet sheet, List
list, Dictionary
dict,int rowCount);53 }

它的实现类是ExcelAnalyzeService,也是抽象类并继承于Base服务ExcelParseBaseService

 

3.IExcelImportService接口就是对外暴漏的excel解析工具类的接口,只含两个方法:验证和读取;

1     ///  2     /// Excel 导入基础服务接口 3     ///  4     public interface IExcelImportService 5     { 6         ///  7         /// 综合验证Excel表格符合性 8         ///  9         /// 
10 UploadExcelFileResult ValidateExcel();11 12 /// 13 /// 导入EXCEL文件14 /// 15 ///
数据对象DTO
16 ///
EXCEL数据集合
17 List
Import
();18 }

它的实现是ExcelImportService,继承于抽象类ExcelAnalyzeService。是我们外部调用excel工具的入口

 

具体各个类方法的实现,下一篇文章再继续贴代码。

本篇文章主要讲述了通过配置xml文件解析多模板excel表格数据的设计流程与主要框架,附带部分规则代码。具体工具内接口方法实现,请关注下一篇文章。

 

原创文章,代码都是从自己项目里贴出来的。转载请注明出处哦,亲~~~

 

转载于:https://www.cnblogs.com/csqb-511612371/p/4885930.html

你可能感兴趣的文章
jquery自定义对话框alert、confirm和prompt
查看>>
intellijj idea正则替换下划线为驼峰
查看>>
《漫画线性代数》读书笔记 用矩阵解方程组
查看>>
关于flume的几道题
查看>>
Java Spring学习笔记 01.@Autowired与@Resource区别?
查看>>
python 小试牛刀之信息管理
查看>>
PHPStorm配置自己喜欢的主题
查看>>
小程序爬坑记录-wxml
查看>>
windows服务与控制台应用程序之HttpWebResponse的使用
查看>>
Windows Phone开发(36):动画之DoubleAnimation 转:http://blog.csdn.net/tcjiaan/article/details/7521388...
查看>>
入驻一点资讯
查看>>
在过滤器中设置一个应用范围内的路径
查看>>
C# OOP程序设计目录
查看>>
表变量类型的创建及使用
查看>>
理解JS里的偏函数与柯里化
查看>>
总结get和post区别---面试用
查看>>
js判断当前浏览器
查看>>
玩转HTTP
查看>>
继承 多态 java相关基础知识
查看>>
iter创建一个可以被迭代的对象
查看>>