之前做过的项目中有个需要读取Excel文件内容的需求,因此使用NPOI实现,写下以下代码,这个只是一个代码段,还有很多地方需要优化,希望能对大家有所帮助

        public static IList<T> ReadListFromStream<T>(string fileName, Stream stream, bool ignoreFirstLine)
where T : new()
{
string extendsion = Path.GetExtension(fileName).TrimStart('.'); IWorkbook workBook = null;
switch (extendsion)
{
case "xls":
workBook = new HSSFWorkbook(stream);
break;
case "xlsx":
workBook = new XSSFWorkbook(stream);
break;
} if (workBook == null || workBook.Count <= 0) { throw new NPOIException("Excel表格工作簿为空"); } IList<T> list = new List<T>();
for (int i = 0; i < workBook.Count; i++)
{
ISheet sheet = workBook.GetSheetAt(i); if (sheet.PhysicalNumberOfRows > 0)
{
if (!ignoreFirstLine)
{
//检查列是否与ExcelAttribute定义的一致
ValidTableHeader<T>(sheet);
} for (int j = ignoreFirstLine ? 0 : 1; j < sheet.PhysicalNumberOfRows; j++)
{
var row = sheet.GetRow(j); T entity = new T(); var propertys = typeof(T).GetProperties(); foreach (var p in propertys)
{
var excel = Attribute.GetCustomAttribute(p, typeof(ExcelAttribute)) as ExcelAttribute; if (excel != null)
{
var cellValue = row.GetCell(excel.ColumnIndex); if (cellValue == null || string.IsNullOrEmpty(cellValue.ToString()))
throw new NPOIException(string.Format("第{0}行“{1}”不能为空", j + 1, excel.ColumnName)); string cellValueStr = cellValue.ToString();
if (p.PropertyType == typeof(int))
{
int temp;
if (!int.TryParse(cellValueStr, out temp))
throw new NPOIException(string.Format("第{0}行“{1}”应为{2}类型", j + 1, excel.ColumnName, "整数"));
p.SetValue(entity, temp, null);
}
else if (p.PropertyType == typeof(DateTime))
{
DateTime temp;
if (!DateTime.TryParse(cellValueStr, out temp))
throw new NPOIException(string.Format("第{0}行“{1}”应为{2}类型", j + 1, excel.ColumnName, "时间"));
p.SetValue(entity, temp, null);
}
else if (p.PropertyType == typeof(bool))
{
bool temp;
if (!bool.TryParse(cellValueStr, out temp))
throw new NPOIException(string.Format("第{0}行“{1}”应为{2}类型", j + 1, excel.ColumnName, "布尔"));
p.SetValue(entity, cellValueStr, null);
}
else if (p.PropertyType == typeof(string))
{
p.SetValue(entity, cellValueStr, null);
}
else
{
throw new NPOIException(string.Format("第{0}行“{1}”类型未知,请联系开发人员", j + 1, excel.ColumnName));
}
}
}
list.Add(entity);
}
}
}
return list;
} /// <summary>
/// 检查表头与定义是否匹配
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="firstRow"></param>
/// <returns></returns>
private static void ValidTableHeader<T>(ISheet sheet) where T : new()
{
var firstRow = sheet.GetRow(0); var propertys = typeof(T).GetProperties(); foreach (var p in propertys)
{
var excel = Attribute.GetCustomAttribute(p, typeof(ExcelAttribute)) as ExcelAttribute; if (excel != null)
{
if (!firstRow.GetCell(excel.ColumnIndex).StringCellValue.Trim().Equals(excel.ColumnName))
{
throw new NPOIException(string.Format("Excel表格第{0}列标题应为{1}", excel.ColumnIndex + 1, excel.ColumnName));
}
}
}
}

ExcelAttribute是自定义的一个特性类,主要在实体属性上标记,以确定该属性对应于Excel中的列名,列的索引

[AttributeUsage(AttributeTargets.Property)]
public class ExcelAttribute : Attribute
{
private string _columnName; public string ColumnName
{
get { return _columnName; }
set { _columnName = value; }
}
private int _columnIndex; public int ColumnIndex
{
get { return _columnIndex; }
set { _columnIndex = value; }
} public ExcelAttribute(string columnName)
{
this._columnName = columnName;
} public ExcelAttribute(string columnName, int columnIndex)
{
this._columnName = columnName;
this._columnIndex = columnIndex;
}
}

最新文章

  1. Mybatis 总结
  2. centos6.3(64位) 安装apr
  3. HDU 2609 最小表示法
  4. 重启Apache报错apache2: Could not reliably determine the server&#39;s fully qualified domain name, using 127.0.1.1 for ServerName ... waiting的解决方法
  5. RAC配置、安装
  6. [转]Linux(centOS6.5)下SVN的安装、配置及开机启动
  7. 微软vs2015先行,Visual Studio 2015正式版离线iso及在线下载(附key)附带百度云盘地址
  8. 软件工程个人第二小项目——wc
  9. 使用line-height来垂直居中在安卓设备并不居中,利用ji调整
  10. asp.net网站管理工具 遇到错误。请返回上一页并重试。
  11. 事务的ACID特性(转)
  12. [Postman]请求(6)
  13. auto 和 decltype
  14. [PHP] 算法-复制复杂链表的PHP实现
  15. 编辑你的数学公式——markdown中latex的使用
  16. Flask页面模板化代码片段
  17. 004 @PathVariable映射URL绑定的占位符
  18. Extjs js 产生Guid或者UUID
  19. 函数及while实例
  20. 做Global Admin

热门文章

  1. C/C++——存储
  2. 发送邮件 html格式
  3. kendo ui - grid 数据表格系列
  4. SDOI2018 一轮培训划水祭
  5. Gradle Goodness: Display Available Tasks
  6. Vscode 格式化vue Template代码段
  7. 用JavaScript编写简单斗地主效果Es6
  8. iOS之限制TextField的输入长度
  9. 项目中常用的MySQL优化方法--壹拾玖条
  10. PHP代码优化—getter 和 setter