NPOI解析多行表头Excel

NPOI解析Excel的例子很多,一般是针对单行表头,输出DataTable的,如果遇到多行表头,输出泛型对象的,要稍微复杂一些,参考了一篇博文,理解后进行了简化,支持了第五篇的合并单元格读取(参考地址:https://www.cnblogs.com/csqb-511612371/p/4891492.html 与 https://www.cnblogs.com/csqb-511612371/p/4895548.html)原文一共6篇,写得很详细。

定义:

public class ExcelHelper
{
	public List<T> ExcelToCollection<T>(string excelPath, Dictionary<string, string> headerPropDict, string sheetName, int indexHeaderStart, int indexHeaderEnd)
	{
		var result = new List<T>();

		if (string.IsNullOrEmpty(excelPath) || !File.Exists(excelPath))
		{
			throw new FileNotFoundException();
		}
		if (indexHeaderStart < 0 || indexHeaderEnd < 0 || indexHeaderStart > indexHeaderEnd)
		{
			throw new ArgumentException();
		}
		try
		{
			using (Stream fileStream = new FileStream(excelPath, FileMode.Open))
			{
				IWorkbook workbook;
				if (excelPath.EndsWith(".xls"))
				{
					workbook = new HSSFWorkbook(fileStream);
				}
				else if (excelPath.EndsWith(".xlsx"))
				{
					workbook = new XSSFWorkbook(fileStream);
				}
				else
				{
					throw new Exception("格式不支持");
				}

				ISheet sheet;
				if (!string.IsNullOrEmpty(sheetName))
				{
					sheet = workbook.GetSheet(sheetName);
					if (sheet == null)
					{
						throw new Exception("sheet name Error");
					}
				}
				else
				{
					sheet = workbook.GetSheetAt(0);
				}

				var headerDict = GetHeaderIndexDict(sheet, indexHeaderStart, indexHeaderEnd);
				if (headerDict.Count == 0)
				{
					throw new Exception("未读取到表头,请检查Excel模板与调用入参");
				}

				for (int i = indexHeaderEnd; i <= sheet.LastRowNum; i++)
				{
					// 产生一个新的泛型对象
					var model = Activator.CreateInstance<T>();

					// 是否为空行
					bool isEmptyRow = true;

					IRow dataRow = sheet.GetRow(i);
					int cellCount = headerDict.Count;

					if (dataRow != null)
					{
						// 循环列数据
						for (int j = dataRow.FirstCellNum; j < cellCount; j++)
						{
							var propertyName = headerPropDict[headerDict[j]];
							PropertyInfo prop = model.GetType().GetProperty(propertyName);

							ICell cell = dataRow.GetCell(j);
							var value = GetCellValue<T>(sheet, cell, j, i, indexHeaderEnd, result, prop.Name);

							if (!string.IsNullOrEmpty(value))
							{
								// 赋值
								switch (prop.PropertyType.FullName)
								{
									case "System.Double":
										if (double.TryParse(value, out double valueDecimal))
										{
											prop.SetValue(model, valueDecimal, null);
										}
										break;
									case "System.Int16":
					
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值