1. 程式人生 > 其它 >.net core Excel匯入匯出

.net core Excel匯入匯出

只需要兩行程式碼,即可匯出資料。

只有一個約定:DisplayName 為列頭。 即可匯出

如下:

匯出後的資料:

資料匯入,可直接轉換對應model

注意:因為匯入會往伺服器儲存excel原本資料,ExcelHelper沒有自動清理的本領

只需要一行程式碼即可。

也是隻有一個約定,匯入資料Excel的列頭 和,和匯入Model 屬性上的DisplayName 值一致。

如下:

效果:

ExcelHelper原始碼:

/// <summary>
/// 和 model displayName 一起使用
/// 匯入時只需要核對 列頭與displayName值是否一致
/// </summary>
public class ExcelHelper
{
/// <summary>
/// 第一步
/// 上傳Excel 並返回上傳路徑
/// </summary>
/// <param name="files"></param>
/// <param name="directoryName">資料夾名稱</param>
/// <returns>
/// 返回路徑
/// </returns>
private static string DepositExcel(IFormFile file, string directoryName)
{
//建立需要存放的位置 返回一個準確的路徑
var path = CreateDirectory("Upload/Excels/" + directoryName);
//檔名
string fileName = DateTime.Now.Ticks.ToString() + "." + file.FileName.Split('.').Last();
path = path + "/" + fileName;
if (File.Exists(path))
{
File.Delete(path);
}

using (var stream = new FileStream(path, FileMode.CreateNew))
{
file.CopyTo(stream);
}
return path;
}

/// <summary>
/// 第二步
/// 得到Excel 內容
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
private static ISheet GetSheet(string path)
{
ISheet sheet;
using (var file = new FileStream(path, FileMode.Open, FileAccess.Read))
{
MemoryStream ms = new MemoryStream();
if (Path.GetExtension(path) == ".xls")
{
HSSFWorkbook workbook = new HSSFWorkbook(file);
//獲取一個sheetName
sheet = workbook.GetSheetAt(0);
}
else
{
XSSFWorkbook workbook = new XSSFWorkbook(file);
//獲取一個sheetName
sheet = workbook.GetSheetAt(0);
}
}
return sheet;
}

/// <summary>
/// 第三步
/// 根據Excel 內容得到想要的List
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="sheet"></param>
/// <param name="headNum"></param>
/// <returns></returns>
private static List<T> GetList<T>(ISheet sheet, int headNum)
{
List<T> list = new List<T>();
Dictionary<int, string> dict = new Dictionary<int, string>();
//獲得列名所對應的欄位名
var propertys = GetPropertyByType<T>(false);
//得到每個欄位對應的序號
IRow head = sheet.GetRow(headNum);

for (int i = 0; i < head.LastCellNum; i++)
{
ICell cell = head.GetCell(i);
if (propertys.ContainsKey(cell.StringCellValue.Trim()))
{
dict.Add(i, propertys[cell.StringCellValue.Trim()]);
}
}
if (dict.Count != head.LastCellNum)
{
throw new Exception("Import tables head and requirements inconsistency");
}
var type = typeof(T).GetProperties();
int c = 0;
try
{
for (int i = headNum + 1; i <= sheet.LastRowNum; i++)
{
c = i;
IRow row = sheet.GetRow(i);
if (row != null)
{
bool isAddList = true;
T t = Activator.CreateInstance<T>();
for (int j = 0; j < row.LastCellNum; j++)
{
ICell cell = row.GetCell(j);
string name = "";
dict.TryGetValue(j, out name);
if (cell != null)
{
if (cell.CellType == CellType.Blank)//空值
{
isAddList = IsAdd(name, true);
}
else
{
var item = type.FirstOrDefault(m => m.Name == name);
if (item != null)
{
if (item.PropertyType == typeof(DateTime))
{
try
{
if (cell.CellType == CellType.String)
{
var value = Convert.ToDateTime(cell.ToString());
item.SetValue(t, value);
}
else
{
item.SetValue(t, cell.DateCellValue);
}
}
catch
{
throw new Exception($"DateTime{cell.ToString()}格式不正確!");
}
}
else if (item.PropertyType == typeof(int))
{
try
{
item.SetValue(t, Convert.ToInt32(cell.ToString()));
}
catch
{
throw new Exception($"int{cell.ToString()}格式不正確!");
}
}
else if (item.PropertyType == typeof(string))
{
if (cell.CellType == CellType.String)
{
item.SetValue(t, cell.ToString());
isAddList = IsAdd(name, string.IsNullOrEmpty(cell.ToString()));
}
else
{
item.SetValue(t, cell.NumericCellValue.ToString());
}

}
else if (item.PropertyType == typeof(decimal?) || item.PropertyType == typeof(decimal))
{
if (cell != null)
{
try
{
var value = 0m;
if (cell.CellType == CellType.String)
{
value = Convert.ToDecimal(cell.ToString());
}
else
{
value = Convert.ToDecimal(cell.NumericCellValue);
}
item.SetValue(t, value);
isAddList = IsAdd(name, value == 0);
}
catch
{
throw new Exception($"decimal{cell.ToString()}格式不正確!");
}
}
}
}
}
if (isAddList == false)
{
break;
}
}
}
if (isAddList)
{
list.Add(t);
}
}

}
}
catch (Exception e)
{
throw e;
}
return list;
}

private static bool IsAdd(string name, bool isOk)
{
bool result = true;
string[] isNotStrs = { };
if (isNotStrs.Contains(name) && isOk)
{
result = false;
}
return result;
}

#region 輔助方法
/// <summary>
/// 建立目錄
/// </summary>
/// <param name="directoryPath">目錄路徑</param>
private static string CreateDirectory(string directoryPath = "")
{
var path = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Content");
if (!string.IsNullOrEmpty(directoryPath))
{
if (directoryPath.Substring(0, 1) != "/")
{
directoryPath = "/" + directoryPath;
}
path += directoryPath;
}
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
return path;
}

/// <summary>
/// 獲得Excel列名
/// </summary>
private static Dictionary<string, string> GetPropertyByType<In>(bool isToExcel)
{
Dictionary<string, string> dict = new Dictionary<string, string>();
var type = typeof(In);
try
{
foreach (var item in type.GetProperties())
{
var displayName = item.GetCustomAttribute<DisplayNameAttribute>();
if (displayName != null)
{
if (isToExcel)
{
dict.Add(item.Name, displayName.DisplayName);
}
else
{
dict.Add(displayName.DisplayName, item.Name);
}
}

}
}
catch (Exception e)
{
throw e;
}
return dict;
}
#endregion

/// <summary>
/// 功能,
/// 匯入Excel
/// 列頭名和實體的DispName 要一致。
/// </summary>
/// <typeparam name="T">要轉換的實體</typeparam>
/// <param name="files">上傳的Excel檔案</param>
/// <param name="headNum">Excel頭部行數</param>
/// <returns>
/// 獲得轉換後的List 集合
/// </returns>
public static List<T> GetList<T>(IFormFile files, int headNum)
{
List<T> list = new List<T>();
string path = DepositExcel(files, typeof(T).Name);
//得到上傳檔案內容
ISheet sheet = GetSheet(path);
//轉換成List
var t = GetList<T>(sheet, headNum);
if (t != null && t.Count > 0)
{
list.AddRange(t);
}
return list;
}

/// <summary>
/// 生成Excel流資料,
/// return File(memoryStream.ToArray(), "application/vnd.ms-excel", fileName); //vnd.ms 此模式有些不相容
/// 或者
/// return File(memoryStream.ToArray(), "application/ms-excel", "紅包列表.xls")
/// </summary>
/// <typeparam name="T">資料模型</typeparam>
/// <param name="excelType">excel副檔名型別</typeparam>
/// <param name="data">資料集</param>
/// <param name="sheetSize">Excel的單個Sheet的行數,不能超過65535,否則會丟擲異常</param>
/// <returns></returns>
public static MemoryStream ToExcel<T>(List<T> data, string excelType = "xls", int sheetSize = 50000)
{
IWorkbook wk;
if (excelType == "xlsx")
{
wk = new XSSFWorkbook();
}
else
{
wk = new HSSFWorkbook();
}
var itemType = Activator.CreateInstance<T>().GetType();

int baseNum = 65535;//單個Sheet最大行數65535
int cNum = data.Count / baseNum;
int myForCount = data.Count % baseNum == 0 ? cNum : cNum + 1;
for (int i = 0; i < myForCount; i++)
{
var list = data.Skip(i * baseNum).Take(baseNum).ToList();
string sheetName = "sheet" + i;
CreateSheet(wk, list, itemType, sheetName);
}
MemoryStream m = new MemoryStream();
wk.Write(m);
return m;
}

/// <summary>
/// 建立並得到一個 sheet
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="IN"></typeparam>
/// <param name="wk"></param>
/// <param name="data"></param>
/// <param name="itemType"></param>
/// <param name="sheetName"></param>
/// <param name="sheetSize"></param>
/// <param name="valueHandlerDict"></param>
private static void CreateSheet<T>(IWorkbook wk, List<T> data, Type itemType, string sheetName, int sheetSize = 50000)
{
try
{
ISheet sheet = null;
var headers = GetPropertyByType<T>(true);
sheet = CreateHeaders(wk, headers, sheetName);
if (data.Count > 0)
{
for (var i = 0; i < data.Count; i++)
{
//建立內容
IRow row = sheet.CreateRow(i % sheetSize + 1);

//遍歷填充每條資料
int j = 0;
foreach (var item in headers)
{
var p = itemType.GetProperty(item.Key);//獲取對應列名
if (p != null)
{
var value = p.GetValue(data[i]);
value = value == null ? string.Empty : value;
ICell cell = row.CreateCell(j);
cell.SetCellValue(value.ToString());
}
j++;
}
}
}
}
catch (Exception ex)
{

throw ex;
}
}

/// <summary>
/// 建立sheet 表頭
/// </summary>
/// <param name="wk">workbook</param>
/// <param name="headers">表頭</param>
/// <param name="sheetName"></param>
/// <returns>
/// 返回一個sheet
/// </returns>
private static ISheet CreateHeaders(IWorkbook wk, Dictionary<string, string> headers, string sheetName)
{
var sheet = wk.CreateSheet(sheetName);
IRow rowHead = sheet.CreateRow(0);
ICellStyle style = wk.CreateCellStyle();
IFont font = wk.CreateFont();//建立字型樣式
font.Boldweight = (short)FontBoldWeight.Bold;
style.SetFont(font);

int i = 0;
foreach (var item in headers)
{
ICell cellHead = rowHead.CreateCell(i);
cellHead.SetCellValue(item.Value);
cellHead.CellStyle = style;
i++;
}
return sheet;
}
}

轉自https://blog.csdn.net/u012900128/article/details/118804273