使用DocumentFormat.OpenXml 从Excel 导入数据
public List<DailyStock> ReadExcelFile(string fileName)
{
List<DailyStock> list = new List<DailyStock>();
DataTable dt = ReadExcelFileToDataTable(fileName);
if (dt != null && dt.Rows.Count > 0)
{
foreach (DataRow row in dt.Rows)
{
var model = UtilityHelper.ConvertToModel<DailyStock>(row, new DailyStock());
list.Add(model);
}
}
return list;
}
public DataTable ReadExcelFileToDataTable(string fileName)
{
System.Data.DataTable dt = UtilityHelper.GenerateDailyStockDataTable();
try
{
//Lets open the existing excel file and read through its content . Open the excel using openxml sdk
using (SpreadsheetDocument doc = SpreadsheetDocument.Open(fileName, false))
{
//create the object for workbook part
WorkbookPart workbookPart = doc.WorkbookPart;
Sheets thesheetcollection = workbookPart.Workbook.GetFirstChild<Sheets>();
//using for each loop to get the sheet from the sheetcollection
foreach (Sheet thesheet in thesheetcollection)
{
//statement to get the worksheet object by using the sheet id
Worksheet theWorksheet = ((WorksheetPart)workbookPart.GetPartById(thesheet.Id)).Worksheet;
ExcelDailyStockColumnMapping columnMapping = new ExcelDailyStockColumnMapping();
SheetData thesheetdata = (SheetData)theWorksheet.GetFirstChild<SheetData>();
foreach (Row thecurrentrow in thesheetdata)
{
if (thecurrentrow.RowIndex == 1) { continue; }//忽略第一行
DataRow row = dt.NewRow();
foreach (Cell thecurrentcell in thecurrentrow)
{
string value = thecurrentcell.CellValue.InnerText;
if (thecurrentcell.DataType != null)
{
int id;
if (Int32.TryParse(thecurrentcell.InnerText, out id))
{
SharedStringItem item = workbookPart.SharedStringTablePart.SharedStringTable.Elements<SharedStringItem>().ElementAt(id);
value = item.InnerText;
}
}
SetVaule(thecurrentcell.CellReference.ToString(), value, row, columnMapping);
}
dt.Rows.Add(row);
}
}
}
}
catch (Exception ex)
{
logger.LogError(ex, "读取Excel失败");
throw ex;
}
return dt;
}
private void SetVaule(string cellReference, string value, DataRow row, ExcelDailyStockColumnMapping columnMapping)
{
string columnName = UtilityHelper.GetABC(cellReference);
if (columnMapping.ColumnNames.ContainsKey(columnName))
{
var keyValue = columnMapping.ColumnNames[columnName];
if (keyValue.Value == CellValues.Number)
{
row[keyValue.Key] = UtilityHelper.ToDouble(value.Trim());
}
else
{
row[keyValue.Key] = value.Trim();
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Ardalis.Result;
using DocumentFormat.OpenXml.Drawing.Charts;
using Humanizer;
using Stock.Core.Aggregate.DailyStockAggregate;
using System.Data;
using System.Reflection;
using System.Text.RegularExpressions;
namespace Stock.Infrastructure;
public class UtilityHelper
{
public const string THOUSAND = "万";
public const string MILLION = "亿";
public static double ToDouble(string value)
{
CurrencyUnits unit = GetUnit(value);
string numberStr = GetNumber(value, unit);
double result = 0;
if (double.TryParse(numberStr, out result))
{
result = ConvertToNumbersByUnit(result, unit);
}
return result;
}
private static double ConvertToNumbersByUnit(double value, CurrencyUnits unit)
{
double result = value;
switch (unit)
{
case CurrencyUnits.Thousand:
result = value * 10000;
break;
case CurrencyUnits.Million:
result = value * 10000 * 10000;
break;
}
return result;
}
private static CurrencyUnits GetUnit(string value)
{
CurrencyUnits unit = CurrencyUnits.None;
if (value.Contains(THOUSAND))
{
unit = CurrencyUnits.Thousand;
}
else if (value.Contains(MILLION))
{
unit = CurrencyUnits.Million;
}
return unit;
}
private static string GetNumber(string value, CurrencyUnits unit)
{
string result = value.Trim();
switch (unit)
{
case CurrencyUnits.Thousand:
result = result.Replace(THOUSAND, string.Empty);
break;
case CurrencyUnits.Million:
result = result.Replace(MILLION, string.Empty);
break;
}
return result;
}
private static System.Data.DataTable dailyStockDataTable = null;
public static System.Data.DataTable GenerateDailyStockDataTable()
{
if (dailyStockDataTable == null)
{
DailyStock dailyStock = new DailyStock();
dailyStockDataTable = ToDataTable(dailyStock);
return dailyStockDataTable;
}
else
{
dailyStockDataTable.Clear();
return dailyStockDataTable;
}
}
/// <summary>
/// 将实体转换成具有相同结构的DataTable
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="model">要转换的实体</param>
/// <returns></returns>
public static System.Data.DataTable ToDataTable<T>(T model)
{
//检查实体集合不能为空
if (model == null)
{
throw new Exception("需转换的集合为空");
}
//取出第一个实体的所有Propertie
Type entityType = model.GetType();
PropertyInfo[] entityProperties = entityType.GetProperties();
//生成DataTable的structure
//生产代码中,应将生成的DataTable结构Cache起来,此处略
System.Data.DataTable dt = new();
for (int i = 0; i < entityProperties.Length; i++)
{
dt.Columns.Add(entityProperties[i].Name, entityProperties[i].PropertyType);
}
return dt;
}
/// <summary>
/// DataRow转化为实体
/// </summary>
/// <typeparam name="T">实体</typeparam>
/// <param name="pDataRow">DataRow</param>
/// <param name="model"></param>
/// <returns></returns>
public static T ConvertToModel<T>(DataRow pDataRow, T model)
{
object proValue = null;
PropertyInfo propertyInfo = null;
try
{
if (pDataRow != null)
{
foreach (DataColumn dc in pDataRow.Table.Columns)
{
//忽略绑定时的大小写
propertyInfo = model.GetType().GetProperty(dc.ColumnName, BindingFlags.Public | BindingFlags.Instance | BindingFlags.IgnoreCase);
proValue = pDataRow[dc];
//当值不为空时
if (proValue != DBNull.Value)
{
try
{ //给属性赋值
propertyInfo.SetValue(model, Convert.ChangeType(proValue, dc.DataType), null);
}
catch //如果有错误,继续下一个属性的赋值
{
continue;
}
}
}
}
}
catch
{
model = default(T);
}
return model;
}
/// <summary>
/// DataTable转化为泛型
/// </summary>
/// <typeparam name="T">实体</typeparam>
/// <param name="dt">DataTable</param>
/// <param name="model"></param>
/// <returns></returns>
public static List<T> ConvertToList<T>(System.Data.DataTable dt, T model)
{
List<T> _list = new List<T>();
foreach (DataRow dr in dt.Rows)
{
_list.Add(ConvertToModel<T>(dr, model));
}
return _list;
}
/// <summary>
/// 得到字符串中的字母
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public static string GetABC(string value)
{
return Regex.Replace(value, "[0-9]", "", RegexOptions.IgnoreCase);
}
}
参考:https://www.thecodebuzz.com/read-excel-file-in-dotnet-core-2-1/#aioseo-export-create-write-data-to-excel-using-openxml
浙公网安备 33010602011771号