首先,根据.xlsx文件的表头建立一个实体类
public class Student
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
public DateTime EnrollmentDate { get; set; }
}
建立一个Excel读取文件帮助类,
安装第三方包 NPOI
public class ExcelReader
{
public static List<T> ReadExcelToList<T>(string filePath, bool hasHeader = true) where T : new()
{
List<T> resultList = new List<T>();
var properties = typeof(T).GetProperties();
using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
IWorkbook workbook = new XSSFWorkbook(fs); //.xlsx文件
ISheet sheet = workbook.GetSheetAt(0); //第一个工作表
//获取表头列索引与属性的映射
Dictionary<int, string> columnMap = new Dictionary<int, string>();
IRow headerRow = sheet.GetRow(0); //假设表头在第一行
if (hasHeader && headerRow != null)
{
foreach (var cell in headerRow.Cells)
{
string columName = cell.StringCellValue.Trim();
var property = Array.Find(properties
, p => p.Name.Equals(columName, StringComparison.OrdinalIgnoreCase));
if (property != null)
{
columnMap[cell.ColumnIndex] = property.Name;
}
}
}
else
{
//无表头,按列顺序映射属性
for (int i = 0; i < properties.Length; i++)
{
columnMap[i] = properties[i].Name;
}
}
//遍历数据行
int startRow = hasHeader ? 1 : 0;
for (int rowIndex = startRow; rowIndex <= sheet.LastRowNum; rowIndex++)
{
IRow row = sheet.GetRow(rowIndex);
if (row == null)
{
continue;
}
T item = new T();
foreach (var pair in columnMap)
{
int colIndex = pair.Key;
string propName = pair.Value;
ICell cell = row.GetCell(colIndex);
var property = typeof(T).GetProperty(propName);
if (property != null && cell != null)
{
object value = GetCellValue(cell, property.PropertyType);
property.SetValue(item, value);
//SetValue方法的参数第一个是要设置属性的 对象实例(若属性是静态的,传 null),第二个是要赋给属性的 值
}
}
resultList.Add(item);
}
}
return resultList;
}
/// <summary>
/// 处理单元格数据类型
/// </summary>
/// <param name="cell"></param>
/// <param name="propertyType"></param>
/// <returns></returns>
private static object GetCellValue(ICell cell, Type targetType)
{
if (cell == null) return null;
switch (cell.CellType)
{
case CellType.Numeric:
if (DateUtil.IsCellDateFormatted(cell))
{
return cell.DateCellValue; //日期类型
}
else
{
double numValue = cell.NumericCellValue;
return Convert.ChangeType(numValue, targetType); //数值类型
}
case CellType.String:
var r=cell.StringCellValue.Trim();
return Convert.ChangeType(cell.StringCellValue.Trim(), targetType);
case CellType.Boolean:
return cell.BooleanCellValue;
default:
return null;
}
}
}
在Main函数里测试一下
static void Main(string[] args)
{
try
{
string filePath = "Students.xlsx";
List<Student> students=ExcelReader.ReadExcelToList<Student>(filePath);
foreach (var student in students)
{
Console.WriteLine($"ID: {student.Id}" +
$", 姓名: {student.Name}" +
$", 年龄: {student.Age}" +
$", 入学时间: {student.EnrollmentDate:yyyy-MM-dd}");
}
}
catch (FileNotFoundException)
{
Console.WriteLine("Excel 文件不存在!");
}
catch(Exception ex)
{
Console.WriteLine($"读取失败:{ex.Message}");
}
}
当然,也可以将读取到的数据存储到Dictionary中
public class StudentRepository
{
private List<Student> _students=new List<Student>();
private Dictionary<int, Student> _idIndex = new Dictionary<int, Student>();
private Dictionary<string, Student> _nameIndex = new Dictionary<string, Student>();
//初始化是构建索引
public StudentRepository(List<Student> student)
{
_students = student;
foreach (Student stu in _students)
{
_idIndex[stu.Id] = stu;
_nameIndex[stu.Name] = stu;
}
}
}
浙公网安备 33010602011771号