学海无涯

导航

使用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

posted on 2022-11-21 22:18  宁静致远.  阅读(44)  评论(0编辑  收藏  举报