898 lines
35 KiB
C#
898 lines
35 KiB
C#
using Microsoft.VisualBasic;
|
||
using NPOI.HSSF.UserModel;
|
||
using NPOI.SS.UserModel;
|
||
using NPOI.XSSF.UserModel;
|
||
using OfficeOpenXml;
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.ComponentModel;
|
||
using System.Data;
|
||
using System.Linq;
|
||
using System.Reflection;
|
||
using System.Text;
|
||
using System.Threading.Tasks;
|
||
|
||
namespace DG.Tool
|
||
{
|
||
public static class ExcelHelper
|
||
{
|
||
public static void Export<T>(string fullName, List<T> data)
|
||
{
|
||
ExcelPackage.LicenseContext = OfficeOpenXml.LicenseContext.NonCommercial;
|
||
|
||
var ttype = typeof(T);
|
||
var typeName = ttype.Name;
|
||
var typeDescriptionAttr = ttype.GetCustomAttribute<DescriptionAttribute>();
|
||
if (typeDescriptionAttr != null)
|
||
{
|
||
typeName = typeDescriptionAttr.Description;
|
||
}
|
||
|
||
var tps = ttype.GetProperties().ToList();
|
||
for (var i = tps.Count - 1; i >= 0; i--)
|
||
{
|
||
var attr = tps[i].GetCustomAttribute<NotExportColumnAttribute>();
|
||
if (attr != null)
|
||
{
|
||
tps.RemoveAt(i);
|
||
}
|
||
}
|
||
|
||
using (var package = new ExcelPackage(new FileInfo(fullName)))
|
||
{
|
||
var worksheet = package.Workbook.Worksheets.Add(typeName);
|
||
for (var i = 0; i < tps.Count; i++)
|
||
{
|
||
var tp = tps[i];
|
||
var tpName = tp.Name;
|
||
var tpDescriptionAttr = tp.GetCustomAttribute<DescriptionAttribute>();
|
||
if (tpDescriptionAttr != null)
|
||
{
|
||
tpName = tpDescriptionAttr.Description;
|
||
}
|
||
|
||
worksheet.Cells[1, i + 1].Value = tpName;
|
||
}
|
||
for (var j = 0; j < data.Count; j++)
|
||
{
|
||
for (var k = 0; k < tps.Count; k++)
|
||
{
|
||
var val_display = "";
|
||
var val = tps[k].GetValue(data[j], null);
|
||
if (val != null)
|
||
{
|
||
val_display = Convert.ToString(val);
|
||
}
|
||
worksheet.Cells[j + 2, k + 1].Value = val_display;
|
||
}
|
||
}
|
||
package.Save();
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// excel导入
|
||
/// </summary>
|
||
/// <typeparam name="T"></typeparam>
|
||
/// <param name="bytes"></param>
|
||
/// <param name="dataRow">数据从第几行开始</param>
|
||
/// <param name="onlyFirstSheet">只导入第一个Sheet的数据</param>
|
||
/// <returns></returns>
|
||
public static List<T> Import<T>(byte[] bytes, int dataRow = 2, bool onlyFirstSheet = true) where T : class, new()
|
||
{
|
||
var ttype = typeof(T);
|
||
var tps = ttype.GetProperties();
|
||
|
||
var items = new List<T>();
|
||
using (var ms = new MemoryStream(bytes))
|
||
{
|
||
ExcelPackage.LicenseContext = OfficeOpenXml.LicenseContext.NonCommercial;
|
||
using (var package = new ExcelPackage(ms))
|
||
{
|
||
var sheets = package.Workbook.Worksheets.ToList();
|
||
if (onlyFirstSheet)
|
||
{
|
||
sheets = new List<ExcelWorksheet> { package.Workbook.Worksheets[0] };
|
||
}
|
||
|
||
foreach (var sheet in sheets)
|
||
{
|
||
for (var i = dataRow; i <= sheet.Dimension.Rows; i++)
|
||
{
|
||
var one = Activator.CreateInstance<T>();
|
||
for (var j = 0; j < tps.Length; j++)
|
||
{
|
||
var cell = sheet.Cells[i, j + 1];
|
||
if (cell == null)
|
||
{
|
||
continue;
|
||
}
|
||
|
||
var tp = tps[j];
|
||
var val = GetValue2(tp, cell.GetValue<string>());
|
||
tp.SetValue(one, val, null);
|
||
}
|
||
items.Add(one);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return items;
|
||
}
|
||
|
||
public static async Task ExportAsync<T>(string fullName, List<T> data)
|
||
{
|
||
ExcelPackage.LicenseContext = OfficeOpenXml.LicenseContext.NonCommercial;
|
||
|
||
var ttype = typeof(T);
|
||
var typeName = ttype.Name;
|
||
var typeDescriptionAttr = ttype.GetCustomAttribute<DescriptionAttribute>();
|
||
if (typeDescriptionAttr != null)
|
||
{
|
||
typeName = typeDescriptionAttr.Description;
|
||
}
|
||
|
||
var tps = ttype.GetProperties().ToList();
|
||
for (var i = tps.Count - 1; i >= 0; i--)
|
||
{
|
||
var attr = tps[i].GetCustomAttribute<NotExportColumnAttribute>();
|
||
if (attr != null)
|
||
{
|
||
tps.RemoveAt(i);
|
||
}
|
||
}
|
||
|
||
using (var package = new ExcelPackage(new FileInfo(fullName)))
|
||
{
|
||
var worksheet = package.Workbook.Worksheets.Add(typeName);
|
||
for (var i = 0; i < tps.Count; i++)
|
||
{
|
||
var tp = tps[i];
|
||
var tpName = tp.Name;
|
||
var tpDescriptionAttr = tp.GetCustomAttribute<DescriptionAttribute>();
|
||
if (tpDescriptionAttr != null)
|
||
{
|
||
tpName = tpDescriptionAttr.Description;
|
||
}
|
||
|
||
worksheet.Cells[1, i + 1].Value = tpName;
|
||
}
|
||
for (var j = 0; j < data.Count; j++)
|
||
{
|
||
for (var k = 0; k < tps.Count; k++)
|
||
{
|
||
var val_display = "";
|
||
var val = tps[k].GetValue(data[j], null);
|
||
if (val != null)
|
||
{
|
||
val_display = Convert.ToString(val);
|
||
}
|
||
worksheet.Cells[j + 2, k + 1].Value = val_display;
|
||
}
|
||
}
|
||
await package.SaveAsync();
|
||
}
|
||
}
|
||
|
||
private static object GetValue2(PropertyInfo tp, string val)
|
||
{
|
||
if (tp.PropertyType == typeof(int) || tp.PropertyType == typeof(int?))
|
||
{
|
||
if (int.TryParse(val, out int temp))
|
||
{
|
||
return temp;
|
||
}
|
||
|
||
return default(int?);
|
||
}
|
||
|
||
if (tp.PropertyType == typeof(long) || tp.PropertyType == typeof(long?))
|
||
{
|
||
if (long.TryParse(val, out long temp))
|
||
{
|
||
return temp;
|
||
}
|
||
|
||
return default(long?);
|
||
}
|
||
|
||
if (tp.PropertyType == typeof(decimal) || tp.PropertyType == typeof(decimal?))
|
||
{
|
||
if (decimal.TryParse(val, out decimal temp))
|
||
{
|
||
return temp;
|
||
}
|
||
|
||
return default(decimal?);
|
||
}
|
||
|
||
if (tp.PropertyType == typeof(DateTime) || tp.PropertyType == typeof(DateTime?))
|
||
{
|
||
if (DateTime.TryParse(val, out DateTime temp))
|
||
{
|
||
return temp;
|
||
}
|
||
|
||
return default(DateTime?);
|
||
}
|
||
|
||
if (tp.PropertyType == typeof(bool) || tp.PropertyType == typeof(bool?))
|
||
{
|
||
if (bool.TryParse(val, out bool temp))
|
||
{
|
||
return temp;
|
||
}
|
||
|
||
return default(bool?);
|
||
}
|
||
|
||
return val;
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 生成Excel文件(多行头部)
|
||
/// </summary>
|
||
/// <param name="dt">数据源</param>
|
||
/// <param name="strExcelFileName">文件名</param>
|
||
/// <param name="extHeaders"></param>
|
||
public static void GridToExcelByNPOIMultiHeader(DataTable dt, string strExcelFileName, List<List<string>> extHeaders)
|
||
{
|
||
HSSFWorkbook workbook = new HSSFWorkbook();
|
||
try
|
||
{
|
||
int sheetIndex = 0;
|
||
int dataIndex = 0;
|
||
ICellStyle HeadercellStyle = workbook.CreateCellStyle();
|
||
HeadercellStyle.BorderBottom = BorderStyle.Thin;
|
||
HeadercellStyle.BorderLeft = BorderStyle.Thin;
|
||
HeadercellStyle.BorderRight = BorderStyle.Thin;
|
||
HeadercellStyle.BorderTop = BorderStyle.Thin;
|
||
HeadercellStyle.Alignment = HorizontalAlignment.Center;
|
||
|
||
ICellStyle cellStyle = workbook.CreateCellStyle();
|
||
|
||
//为避免日期格式被Excel自动替换,所以设定 format 为 『@』 表示一率当成text來看
|
||
cellStyle.DataFormat = HSSFDataFormat.GetBuiltinFormat("@");
|
||
cellStyle.BorderBottom = BorderStyle.Thin;
|
||
cellStyle.BorderLeft = BorderStyle.Thin;
|
||
cellStyle.BorderRight = BorderStyle.Thin;
|
||
cellStyle.BorderTop = BorderStyle.Thin;
|
||
|
||
//字体
|
||
IFont headerfont = workbook.CreateFont();
|
||
headerfont.Boldweight = (short)FontBoldWeight.Bold;
|
||
HeadercellStyle.SetFont(headerfont);
|
||
|
||
IFont cellfont = workbook.CreateFont();
|
||
cellfont.Boldweight = (short)FontBoldWeight.Normal;
|
||
cellStyle.SetFont(cellfont);
|
||
var index = extHeaders.Count;
|
||
|
||
while (dataIndex < dt.Rows.Count)
|
||
{
|
||
sheetIndex++;
|
||
ISheet sheet = workbook.CreateSheet($"Sheet{sheetIndex}");
|
||
|
||
if (index > 0)
|
||
{
|
||
for (var i = 0; i < index; i++)
|
||
{
|
||
IRow extHeaderRow = sheet.CreateRow(i);
|
||
|
||
if (extHeaders[i].Count == 0)
|
||
{
|
||
ICell extCell = extHeaderRow.CreateCell(0);
|
||
extCell.SetCellValue("");
|
||
extCell.CellStyle = HeadercellStyle;
|
||
}
|
||
else
|
||
{
|
||
for (var j = 0; j < extHeaders[i].Count; j++)
|
||
{
|
||
ICell cell = extHeaderRow.CreateCell(j);
|
||
cell.SetCellValue(extHeaders[i][j]);
|
||
cell.CellStyle = HeadercellStyle;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
//用column name 作为列名
|
||
int icolIndex = 0;
|
||
IRow headerRow = sheet.CreateRow(index);
|
||
foreach (DataColumn item in dt.Columns)
|
||
{
|
||
ICell cell = headerRow.CreateCell(icolIndex);
|
||
cell.SetCellValue(item.ColumnName);
|
||
cell.CellStyle = HeadercellStyle;
|
||
icolIndex++;
|
||
}
|
||
|
||
//建立内容行
|
||
int iRowIndex = 1;
|
||
int iCellIndex = 0;
|
||
for (int count = 0; dataIndex < dt.Rows.Count; dataIndex++, count++)
|
||
{
|
||
if (count >= 65000)
|
||
break;
|
||
DataRow Rowitem = dt.Rows[dataIndex];
|
||
IRow DataRow = sheet.CreateRow(index + iRowIndex);
|
||
foreach (DataColumn Colitem in dt.Columns)
|
||
{
|
||
ICell cell = DataRow.CreateCell(iCellIndex);
|
||
cell.SetCellValue(Rowitem[Colitem].ToString());
|
||
cell.CellStyle = cellStyle;
|
||
iCellIndex++;
|
||
}
|
||
iCellIndex = 0;
|
||
iRowIndex++;
|
||
}
|
||
|
||
//自适应列宽度
|
||
for (int i = 0; i < icolIndex; i++)
|
||
{
|
||
sheet.AutoSizeColumn(i);
|
||
}
|
||
}
|
||
|
||
if (System.IO.File.Exists(strExcelFileName))
|
||
System.IO.File.Delete(strExcelFileName);
|
||
|
||
//写Excel
|
||
FileStream file = new FileStream(strExcelFileName, FileMode.Create);
|
||
workbook.Write(file);
|
||
file.Flush();
|
||
file.Close();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
throw;
|
||
}
|
||
finally { workbook = null; }
|
||
}
|
||
|
||
/// <summary>
|
||
/// 生成Excel文件
|
||
/// </summary>
|
||
/// <param name="dt">数据源</param>
|
||
/// <param name="strExcelFileName">文件名</param>
|
||
/// <param name="isWebDownload">如果是web下载,strExcelFileName则仅仅是文件名而非路径名</param>
|
||
public static void GridToExcelByNPOI(DataTable dt, string strExcelFileName)
|
||
{
|
||
HSSFWorkbook workbook = new HSSFWorkbook();
|
||
try
|
||
{
|
||
int sheetIndex = 0;
|
||
int dataIndex = 0;
|
||
ICellStyle HeadercellStyle = workbook.CreateCellStyle();
|
||
HeadercellStyle.BorderBottom = BorderStyle.Thin;
|
||
HeadercellStyle.BorderLeft = BorderStyle.Thin;
|
||
HeadercellStyle.BorderRight = BorderStyle.Thin;
|
||
HeadercellStyle.BorderTop = BorderStyle.Thin;
|
||
HeadercellStyle.Alignment = HorizontalAlignment.Center;
|
||
|
||
ICellStyle cellStyle = workbook.CreateCellStyle();
|
||
|
||
//为避免日期格式被Excel自动替换,所以设定 format 为 『@』 表示一率当成text來看
|
||
cellStyle.DataFormat = HSSFDataFormat.GetBuiltinFormat("@");
|
||
cellStyle.BorderBottom = BorderStyle.Thin;
|
||
cellStyle.BorderLeft = BorderStyle.Thin;
|
||
cellStyle.BorderRight = BorderStyle.Thin;
|
||
cellStyle.BorderTop = BorderStyle.Thin;
|
||
|
||
//字体
|
||
IFont headerfont = workbook.CreateFont();
|
||
headerfont.Boldweight = (short)FontBoldWeight.Bold;
|
||
HeadercellStyle.SetFont(headerfont);
|
||
|
||
IFont cellfont = workbook.CreateFont();
|
||
cellfont.Boldweight = (short)FontBoldWeight.Normal;
|
||
cellStyle.SetFont(cellfont);
|
||
while (dataIndex < dt.Rows.Count)
|
||
{
|
||
sheetIndex++;
|
||
ISheet sheet = workbook.CreateSheet($"Sheet{sheetIndex}");
|
||
|
||
//用column name 作为列名
|
||
int icolIndex = 0;
|
||
IRow headerRow = sheet.CreateRow(0);
|
||
foreach (DataColumn item in dt.Columns)
|
||
{
|
||
ICell cell = headerRow.CreateCell(icolIndex);
|
||
cell.SetCellValue(item.ColumnName);
|
||
cell.CellStyle = HeadercellStyle;
|
||
icolIndex++;
|
||
}
|
||
|
||
//建立内容行
|
||
int iRowIndex = 1;
|
||
int iCellIndex = 0;
|
||
for (int count = 0; dataIndex < dt.Rows.Count; dataIndex++, count++)
|
||
{
|
||
if (count >= 65000)
|
||
break;
|
||
DataRow Rowitem = dt.Rows[dataIndex];
|
||
IRow DataRow = sheet.CreateRow(iRowIndex);
|
||
foreach (DataColumn Colitem in dt.Columns)
|
||
{
|
||
ICell cell = DataRow.CreateCell(iCellIndex);
|
||
cell.SetCellValue(Rowitem[Colitem].ToString());
|
||
cell.CellStyle = cellStyle;
|
||
iCellIndex++;
|
||
}
|
||
iCellIndex = 0;
|
||
iRowIndex++;
|
||
}
|
||
|
||
//自适应列宽度
|
||
for (int i = 0; i < icolIndex; i++)
|
||
{
|
||
sheet.AutoSizeColumn(i);
|
||
}
|
||
}
|
||
|
||
//如果没有传路径,就生成用于web下载的流
|
||
//if (isWebDownload)
|
||
//{
|
||
// using (MemoryStream ms = new MemoryStream())
|
||
// {
|
||
// workbook.Write(ms);
|
||
// ms.Flush();
|
||
// ms.Position = 0;
|
||
|
||
// byte[] bytes = ms.GetBuffer();
|
||
// HttpContext.GetUserIp();
|
||
// string UserAgent = WebRequest.DefaultWebProxy.
|
||
|
||
// .g
|
||
|
||
// Request.UserAgent
|
||
|
||
// string UserAgent = HttpContext.Current.Request.ServerVariables["http_user_agent"].ToLower();
|
||
// string filename = strExcelFileName + ".xls";
|
||
// if (UserAgent.IndexOf("firefox") <= 0)//火狐,文件名不需要编码
|
||
// {
|
||
// filename = HttpUtility.UrlEncode(filename, Encoding.UTF8);
|
||
// }
|
||
// HttpContext.Current.Response.ContentType = "application/vnd.ms-excel";
|
||
|
||
// HttpContext.Current.Response.AppendHeader("Content-Disposition", "attachment;filename=" + filename);
|
||
// HttpContext.Current.Response.BinaryWrite(bytes);
|
||
// HttpContext.Current.Response.End();
|
||
// }
|
||
//}
|
||
//else
|
||
{
|
||
if (System.IO.File.Exists(strExcelFileName))
|
||
System.IO.File.Delete(strExcelFileName);
|
||
|
||
//写Excel
|
||
FileStream file = new FileStream(strExcelFileName, FileMode.Create);
|
||
workbook.Write(file);
|
||
file.Flush();
|
||
file.Close();
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
throw;
|
||
}
|
||
finally { workbook = null; }
|
||
}
|
||
|
||
/// <summary>
|
||
/// 将DataTable数据导入到excel中
|
||
/// </summary>
|
||
/// <param name="data">要导入的数据</param>
|
||
/// <param name="isColumnWritten">DataTable的列名是否要导入</param>
|
||
/// <param name="fileName">导出文件名全路径</param>
|
||
/// <param name="sheetName">要导入的excel的sheet的名称</param>
|
||
/// <returns>导入数据行数(包含列名那一行)</returns>
|
||
public static int DataTableToExcel(DataTable data, string fileName, bool isColumnWritten, string sheetName = "Sheet1")
|
||
{
|
||
int i = 0;
|
||
int j = 0;
|
||
int count = 0;
|
||
ISheet sheet = null;
|
||
IWorkbook workbook = null;
|
||
string myDir = Path.GetDirectoryName(fileName);
|
||
//判断文件夹是否存在
|
||
if (!Directory.Exists(myDir))
|
||
{
|
||
//文件夹不存在则创建该文件夹
|
||
if (myDir != null)
|
||
Directory.CreateDirectory(myDir);
|
||
}
|
||
using (var fs = new FileStream(fileName, FileMode.Create, FileAccess.ReadWrite))
|
||
{
|
||
if (fileName.IndexOf(".xlsx", StringComparison.Ordinal) > 0) // 2007版本
|
||
workbook = new XSSFWorkbook();
|
||
else if (fileName.IndexOf(".xls", StringComparison.Ordinal) > 0) // 2003版本
|
||
workbook = new HSSFWorkbook();
|
||
|
||
try
|
||
{
|
||
if (workbook != null)
|
||
{
|
||
sheet = workbook.CreateSheet(sheetName);
|
||
}
|
||
else
|
||
{
|
||
return -1;
|
||
}
|
||
|
||
if (isColumnWritten == true) //写入DataTable的列名
|
||
{
|
||
IRow row = sheet.CreateRow(0);
|
||
for (j = 0; j < data.Columns.Count; ++j)
|
||
{
|
||
row.CreateCell(j).SetCellValue(data.Columns[j].ColumnName);
|
||
}
|
||
count = 1;
|
||
}
|
||
else
|
||
{
|
||
count = 0;
|
||
}
|
||
|
||
for (i = 0; i < data.Rows.Count; ++i)
|
||
{
|
||
IRow row = sheet.CreateRow(count);
|
||
for (j = 0; j < data.Columns.Count; ++j)
|
||
{
|
||
row.CreateCell(j).SetCellValue(data.Rows[i][j].ToString());
|
||
}
|
||
++count;
|
||
}
|
||
workbook.Write(fs); //写入到excel
|
||
workbook.Close();
|
||
return count;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
workbook?.Close();
|
||
throw new Exception(ex.Message);
|
||
}
|
||
}
|
||
}
|
||
|
||
public static DataTable ExcelToDataTable(string fileName, string sheetName, bool isFirstRowColumn, Dictionary<string, string[]> columnTemplate = null, string[] requireColumns = null, int? maxRows = null)
|
||
{
|
||
ISheet sheet = null;
|
||
DataTable data = new DataTable();
|
||
IWorkbook workbook = null;
|
||
int startRow = 0;
|
||
try
|
||
{
|
||
using (var fs = new FileStream(fileName, FileMode.Open, FileAccess.Read))
|
||
{
|
||
try
|
||
{
|
||
workbook = new XSSFWorkbook(fs);
|
||
}
|
||
catch
|
||
{
|
||
workbook = new HSSFWorkbook(fs);
|
||
}
|
||
}
|
||
|
||
if (sheetName != null)
|
||
{
|
||
if (workbook != null)
|
||
{
|
||
sheet = workbook.GetSheet(sheetName);
|
||
if (sheet == null) //如果没有找到指定的sheetName对应的sheet,则尝试获取第一个sheet
|
||
{
|
||
sheet = workbook.GetSheetAt(0);
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (workbook != null) sheet = workbook.GetSheetAt(0);
|
||
}
|
||
if (sheet != null)
|
||
{
|
||
IRow firstRow = sheet.GetRow(0);
|
||
int cellCount = firstRow.LastCellNum; //一行最后一个cell的编号 即总的列数
|
||
|
||
if (isFirstRowColumn)
|
||
{
|
||
for (int i = firstRow.FirstCellNum; i < cellCount; ++i)
|
||
{
|
||
ICell cell = firstRow.GetCell(i);
|
||
string cellValue = cell?.StringCellValue?.Trim();
|
||
if (!string.IsNullOrWhiteSpace(cellValue))//列名正确性验证
|
||
{
|
||
if (columnTemplate != null && !columnTemplate.First().Value.Contains(cellValue))
|
||
throw new Exception($"{columnTemplate.First().Key}不存在列名:{cellValue}!正确列名为:{string.Join(",", columnTemplate.First().Value)}");
|
||
DataColumn column = new DataColumn(cellValue);
|
||
data.Columns.Add(column);
|
||
}
|
||
}
|
||
startRow = sheet.FirstRowNum + 1;
|
||
}
|
||
else
|
||
{
|
||
startRow = sheet.FirstRowNum;
|
||
}
|
||
|
||
//最后一列的标号
|
||
int rowCount = sheet.LastRowNum;
|
||
if (maxRows != null)
|
||
{
|
||
if (rowCount > maxRows)
|
||
throw new Exception($"请拆分文件,一次最多支持{maxRows}条数据");
|
||
}
|
||
for (int i = startRow; i <= rowCount; ++i)
|
||
{
|
||
IRow row = sheet.GetRow(i);
|
||
if (row == null || row.Cells.Count == 0 || row.FirstCellNum == -1 || row.Cells.All(d => d.CellType == CellType.Blank)) continue; //没有数据的行默认是null
|
||
|
||
DataRow dataRow = data.NewRow();
|
||
for (int j = row.FirstCellNum; j < cellCount; ++j)
|
||
{
|
||
var cellvalue = row.GetCell(j);
|
||
if (cellvalue == null || (cellvalue.ToString().Trim() == "0"))
|
||
{
|
||
if (requireColumns != null && requireColumns.Contains(data.Columns[j].ColumnName))
|
||
{
|
||
//throw new Exception($"第{i}行,第{j}列,【{data.Columns[j].ColumnName}】不能为空或0,必须填写!");
|
||
}
|
||
}
|
||
if (cellvalue != null) dataRow[j] = cellvalue.ToString().Trim();
|
||
else
|
||
{
|
||
dataRow[j] = ""; //string.Empty;
|
||
}
|
||
}
|
||
data.Rows.Add(dataRow);
|
||
}
|
||
}
|
||
workbook?.Close();
|
||
return data;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
workbook?.Close();
|
||
throw new Exception(ex.Message);
|
||
}
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 将excel中的数据导入到DataTable中
|
||
/// </summary>
|
||
/// <param name="sheetName">excel工作薄sheet的名称</param>
|
||
/// <param name="isFirstRowColumn">第一行是否是DataTable的列名</param>
|
||
/// <param name="fileName">第一行是否是DataTable的列名</param>
|
||
/// <param name="startRow">开始行数</param>
|
||
/// <param name="startData">开始收集数据行数</param>
|
||
/// <returns>返回的DataTable</returns>
|
||
public static DataTable ExcelToDataTable(string sheetName, bool isFirstRowColumn, string fileName, int startRow = 0, int startData = 1)
|
||
{
|
||
ISheet sheet = null;
|
||
DataTable data = new DataTable();
|
||
try
|
||
{
|
||
IWorkbook workbook = null;
|
||
FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
|
||
if (fileName.IndexOf(".xlsx") > 0 || fileName.IndexOf(".xlsm") > 0) // 2007版本
|
||
workbook = new XSSFWorkbook(fs);
|
||
else if (fileName.IndexOf(".xls") > 0) // 2003版本
|
||
workbook = new HSSFWorkbook(fs);
|
||
|
||
if (sheetName != null)
|
||
{
|
||
sheet = workbook.GetSheet(sheetName);
|
||
if (sheet == null) //如果没有找到指定的sheetName对应的sheet,则尝试获取第一个sheet
|
||
{
|
||
sheet = workbook.GetSheetAt(0);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
sheet = workbook.GetSheetAt(0);
|
||
}
|
||
if (sheet != null)
|
||
{
|
||
IRow firstRow = sheet.GetRow(startRow);
|
||
int cellCount = firstRow.LastCellNum; //一行最后一个cell的编号 即总的列数
|
||
|
||
if (isFirstRowColumn)
|
||
{
|
||
for (int i = firstRow.FirstCellNum; i < cellCount; ++i)
|
||
{
|
||
ICell cell = firstRow.GetCell(i);
|
||
if (cell != null)
|
||
{
|
||
string cellValue = cell.StringCellValue.Replace(" ", "").Replace("?", "");
|
||
if (cellValue != null)
|
||
{
|
||
if (data.Columns[cellValue] != null)
|
||
{
|
||
cellValue += i;
|
||
}
|
||
DataColumn column = new DataColumn(cellValue);
|
||
data.Columns.Add(column);
|
||
}
|
||
}
|
||
}
|
||
startRow += sheet.FirstRowNum + startData;
|
||
}
|
||
else
|
||
{
|
||
startRow = sheet.FirstRowNum;
|
||
}
|
||
|
||
//最后一列的标号
|
||
int rowCount = sheet.LastRowNum;
|
||
for (int i = startRow; i <= rowCount; ++i)
|
||
{
|
||
IRow row = sheet.GetRow(i);
|
||
if (row == null) continue; //没有数据的行默认是null
|
||
|
||
DataRow dataRow = data.NewRow();
|
||
for (int j = row.FirstCellNum; j < cellCount; ++j)
|
||
{
|
||
if (row.GetCell(j) != null) //同理,没有数据的单元格都默认是null
|
||
dataRow[j] = row.GetCell(j).ToString();
|
||
}
|
||
data.Rows.Add(dataRow);
|
||
}
|
||
}
|
||
|
||
return data;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine("Exception: " + ex.Message);
|
||
return null;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// DataTable转成List
|
||
/// </summary>
|
||
/// <typeparam name="T"></typeparam>
|
||
/// <param name="dt"></param>
|
||
/// <returns></returns>
|
||
public static List<T> ToDataList<T>(this DataTable dt)
|
||
{
|
||
var list = new List<T>();
|
||
var plist = new List<PropertyInfo>(typeof(T).GetProperties());
|
||
foreach (DataRow item in dt.Rows)
|
||
{
|
||
T s = Activator.CreateInstance<T>();
|
||
for (int i = 0; i < dt.Columns.Count; i++)
|
||
{
|
||
PropertyInfo info = plist.Find(p => p.Name == dt.Columns[i].ColumnName);
|
||
if (info != null)
|
||
{
|
||
try
|
||
{
|
||
if (!Convert.IsDBNull(item[i]))
|
||
{
|
||
object v = null;
|
||
if (info.PropertyType.ToString().Contains("System.Nullable"))
|
||
{
|
||
v = Convert.ChangeType(item[i], Nullable.GetUnderlyingType(info.PropertyType));
|
||
}
|
||
else
|
||
{
|
||
v = Convert.ChangeType(item[i], info.PropertyType);
|
||
}
|
||
info.SetValue(s, v, null);
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
throw new Exception("字段[" + info.Name + "]转换出错," + ex.Message);
|
||
}
|
||
}
|
||
}
|
||
list.Add(s);
|
||
}
|
||
return list;
|
||
}
|
||
|
||
/// <summary>
|
||
/// DataTable转成Dto
|
||
/// </summary>
|
||
/// <typeparam name="T"></typeparam>
|
||
/// <param name="dt"></param>
|
||
/// <returns></returns>
|
||
public static T ToDataDto<T>(this DataTable dt)
|
||
{
|
||
T s = Activator.CreateInstance<T>();
|
||
if (dt == null || dt.Rows.Count == 0)
|
||
{
|
||
return s;
|
||
}
|
||
var plist = new List<PropertyInfo>(typeof(T).GetProperties());
|
||
for (int i = 0; i < dt.Columns.Count; i++)
|
||
{
|
||
PropertyInfo info = plist.Find(p => p.Name == dt.Columns[i].ColumnName);
|
||
if (info != null)
|
||
{
|
||
try
|
||
{
|
||
if (!Convert.IsDBNull(dt.Rows[0][i]))
|
||
{
|
||
object v = null;
|
||
if (info.PropertyType.ToString().Contains("System.Nullable"))
|
||
{
|
||
v = Convert.ChangeType(dt.Rows[0][i], Nullable.GetUnderlyingType(info.PropertyType));
|
||
}
|
||
else
|
||
{
|
||
v = Convert.ChangeType(dt.Rows[0][i], info.PropertyType);
|
||
}
|
||
info.SetValue(s, v, null);
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
throw new Exception("字段[" + info.Name + "]转换出错," + ex.Message);
|
||
}
|
||
}
|
||
}
|
||
return s;
|
||
}
|
||
|
||
/// <summary>
|
||
/// list转化为table
|
||
/// </summary>
|
||
/// <typeparam name="T"></typeparam>
|
||
/// <param name="entitys"></param>
|
||
/// <returns></returns>
|
||
public static DataTable ListToDataTable<T>(List<T> entitys)
|
||
{
|
||
|
||
//检查实体集合不能为空
|
||
if (entitys == null || entitys.Count < 1)
|
||
{
|
||
return new DataTable();
|
||
}
|
||
|
||
//取出第一个实体的所有Propertie
|
||
Type entityType = entitys[0].GetType();
|
||
PropertyInfo[] entityProperties = entityType.GetProperties();
|
||
|
||
//生成DataTable的structure
|
||
//生产代码中,应将生成的DataTable结构Cache起来,此处略
|
||
DataTable dt = new DataTable("dt");
|
||
for (int i = 0; i < entityProperties.Length; i++)
|
||
{
|
||
//dt.Columns.Add(entityProperties[i].Name, entityProperties[i].PropertyType);
|
||
dt.Columns.Add(entityProperties[i].Name);
|
||
}
|
||
|
||
//将所有entity添加到DataTable中
|
||
foreach (object entity in entitys)
|
||
{
|
||
//检查所有的的实体都为同一类型
|
||
if (entity.GetType() != entityType)
|
||
{
|
||
throw new Exception("要转换的集合元素类型不一致");
|
||
}
|
||
DataRow dr = dt.NewRow();
|
||
dt.Rows.Add(dr);
|
||
int rowCount = dt.Rows.Count;
|
||
object[] entityValues = new object[entityProperties.Length];
|
||
for (int i = 0; i < entityProperties.Length; i++)
|
||
{
|
||
entityValues[i] = entityProperties[i].GetValue(entity, null);
|
||
//给当前行的每列加数据
|
||
dt.Rows[rowCount][i] = entityValues[i];
|
||
}
|
||
}
|
||
return dt;
|
||
}
|
||
|
||
|
||
}
|
||
}
|