using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using NPOI.SS.Util;
using NPOI.XSSF.UserModel;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Data.OleDb;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace SysBaseLibs
{
public class ExcelHelper
{
///
/// 将数据导出至Excel文件
///
/// DataTable对象
/// Excel文件路径
public static bool OutputToExcel(DataTable Table, string ExcelFilePath)
{
if (File.Exists(ExcelFilePath))
{
throw new Exception("该文件已经存在!");
}
if ((Table.TableName.Trim().Length == 0) || (Table.TableName.ToLower() == "table"))
{
Table.TableName = "Sheet1";
}
//数据表的列数
int ColCount = Table.Columns.Count;
//用于记数,实例化参数时的序号
int i = 0;
//创建参数
OleDbParameter[] para = new OleDbParameter[ColCount];
//创建表结构的SQL语句
string TableStructStr = @"Create Table " + Table.TableName + "(";
//连接字符串
string connString = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + ExcelFilePath + ";Extended Properties=Excel 8.0;";
OleDbConnection objConn = new OleDbConnection(connString);
//创建表结构
OleDbCommand objCmd = new OleDbCommand();
//数据类型集合
ArrayList DataTypeList = new ArrayList();
DataTypeList.Add("System.Decimal");
DataTypeList.Add("System.Double");
DataTypeList.Add("System.Int16");
DataTypeList.Add("System.Int32");
DataTypeList.Add("System.Int64");
DataTypeList.Add("System.Single");
//遍历数据表的所有列,用于创建表结构
foreach (DataColumn col in Table.Columns)
{
//如果列属于数字列,则设置该列的数据类型为double
if (DataTypeList.IndexOf(col.DataType.ToString()) >= 0)
{
para[i] = new OleDbParameter("@" + col.ColumnName, OleDbType.Double);
objCmd.Parameters.Add(para[i]);
//如果是最后一列
if (i + 1 == ColCount)
{
TableStructStr += col.ColumnName + " double)";
}
else
{
TableStructStr += col.ColumnName + " double,";
}
}
else
{
para[i] = new OleDbParameter("@" + col.ColumnName, OleDbType.VarChar);
objCmd.Parameters.Add(para[i]);
//如果是最后一列
if (i + 1 == ColCount)
{
TableStructStr += col.ColumnName + " varchar)";
}
else
{
TableStructStr += col.ColumnName + " varchar,";
}
}
i++;
}
//创建Excel文件及文件结构
try
{
objCmd.Connection = objConn;
objCmd.CommandText = TableStructStr;
if (objConn.State == ConnectionState.Closed)
{
objConn.Open();
}
objCmd.ExecuteNonQuery();
}
catch (Exception exp)
{
throw exp;
}
//插入记录的SQL语句
string InsertSql_1 = "Insert into " + Table.TableName + " (";
string InsertSql_2 = " Values (";
string InsertSql = "";
//遍历所有列,用于插入记录,在此创建插入记录的SQL语句
for (int colID = 0; colID < ColCount; colID++)
{
if (colID + 1 == ColCount) //最后一列
{
InsertSql_1 += Table.Columns[colID].ColumnName + ")";
InsertSql_2 += "@" + Table.Columns[colID].ColumnName + ")";
}
else
{
InsertSql_1 += Table.Columns[colID].ColumnName + ",";
InsertSql_2 += "@" + Table.Columns[colID].ColumnName + ",";
}
}
InsertSql = InsertSql_1 + InsertSql_2;
//遍历数据表的所有数据行
for (int rowID = 0; rowID < Table.Rows.Count; rowID++)
{
for (int colID = 0; colID < ColCount; colID++)
{
if (para[colID].DbType == DbType.Double && Table.Rows[rowID][colID].ToString().Trim() == "")
{
para[colID].Value = 0;
}
else
{
para[colID].Value = Table.Rows[rowID][colID].ToString().Trim();
}
}
try
{
objCmd.CommandText = InsertSql;
objCmd.ExecuteNonQuery();
}
catch (Exception exp)
{
string str = exp.Message;
}
}
try
{
if (objConn.State == ConnectionState.Open)
{
objConn.Close();
}
}
catch (Exception exp)
{
throw exp;
}
return true;
}
///
/// 将数据导出至Excel文件
///
/// DataTable对象
/// 要导出的数据列集合
/// Excel文件路径
public static bool OutputToExcel(DataTable Table, ArrayList Columns, string ExcelFilePath)
{
if (File.Exists(ExcelFilePath))
{
throw new Exception("该文件已经存在!");
}
//如果数据列数大于表的列数,取数据表的所有列
if (Columns.Count > Table.Columns.Count)
{
for (int s = Table.Columns.Count + 1; s <= Columns.Count; s++)
{
Columns.RemoveAt(s); //移除数据表列数后的所有列
}
}
//遍历所有的数据列,如果有数据列的数据类型不是 DataColumn,则将它移除
DataColumn column = new DataColumn();
for (int j = 0; j < Columns.Count; j++)
{
try
{
column = (DataColumn)Columns[j];
}
catch (Exception)
{
Columns.RemoveAt(j);
}
}
if ((Table.TableName.Trim().Length == 0) || (Table.TableName.ToLower() == "table"))
{
Table.TableName = "Sheet1";
}
//数据表的列数
int ColCount = Columns.Count;
//创建参数
OleDbParameter[] para = new OleDbParameter[ColCount];
//创建表结构的SQL语句
string TableStructStr = @"Create Table " + Table.TableName + "(";
//连接字符串
string connString = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + ExcelFilePath + ";Extended Properties=Excel 8.0;";
OleDbConnection objConn = new OleDbConnection(connString);
//创建表结构
OleDbCommand objCmd = new OleDbCommand();
//数据类型集合
ArrayList DataTypeList = new ArrayList();
DataTypeList.Add("System.Decimal");
DataTypeList.Add("System.Double");
DataTypeList.Add("System.Int16");
DataTypeList.Add("System.Int32");
DataTypeList.Add("System.Int64");
DataTypeList.Add("System.Single");
DataColumn col = new DataColumn();
//遍历数据表的所有列,用于创建表结构
for (int k = 0; k < ColCount; k++)
{
col = (DataColumn)Columns[k];
//列的数据类型是数字型
if (DataTypeList.IndexOf(col.DataType.ToString().Trim()) >= 0)
{
para[k] = new OleDbParameter("@" + col.Caption.Trim(), OleDbType.Double);
objCmd.Parameters.Add(para[k]);
//如果是最后一列
if (k + 1 == ColCount)
{
TableStructStr += col.Caption.Trim() + " Double)";
}
else
{
TableStructStr += col.Caption.Trim() + " Double,";
}
}
else
{
para[k] = new OleDbParameter("@" + col.Caption.Trim(), OleDbType.VarChar);
objCmd.Parameters.Add(para[k]);
//如果是最后一列
if (k + 1 == ColCount)
{
TableStructStr += col.Caption.Trim() + " VarChar)";
}
else
{
TableStructStr += col.Caption.Trim() + " VarChar,";
}
}
}
//创建Excel文件及文件结构
try
{
objCmd.Connection = objConn;
objCmd.CommandText = TableStructStr;
if (objConn.State == ConnectionState.Closed)
{
objConn.Open();
}
objCmd.ExecuteNonQuery();
}
catch (Exception exp)
{
throw exp;
}
//插入记录的SQL语句
string InsertSql_1 = "Insert into " + Table.TableName + " (";
string InsertSql_2 = " Values (";
string InsertSql = "";
//遍历所有列,用于插入记录,在此创建插入记录的SQL语句
for (int colID = 0; colID < ColCount; colID++)
{
if (colID + 1 == ColCount) //最后一列
{
InsertSql_1 += Columns[colID].ToString().Trim() + ")";
InsertSql_2 += "@" + Columns[colID].ToString().Trim() + ")";
}
else
{
InsertSql_1 += Columns[colID].ToString().Trim() + ",";
InsertSql_2 += "@" + Columns[colID].ToString().Trim() + ",";
}
}
InsertSql = InsertSql_1 + InsertSql_2;
//遍历数据表的所有数据行
DataColumn DataCol = new DataColumn();
for (int rowID = 0; rowID < Table.Rows.Count; rowID++)
{
for (int colID = 0; colID < ColCount; colID++)
{
//因为列不连续,所以在取得单元格时不能用行列编号,列需得用列的名称
DataCol = (DataColumn)Columns[colID];
if (para[colID].DbType == DbType.Double && Table.Rows[rowID][DataCol.Caption].ToString().Trim() == "")
{
para[colID].Value = 0;
}
else
{
para[colID].Value = Table.Rows[rowID][DataCol.Caption].ToString().Trim();
}
}
try
{
objCmd.CommandText = InsertSql;
objCmd.ExecuteNonQuery();
}
catch (Exception exp)
{
string str = exp.Message;
}
}
try
{
if (objConn.State == ConnectionState.Open)
{
objConn.Close();
}
}
catch (Exception exp)
{
throw exp;
}
return true;
}
///
/// 获取Excel文件数据表列表
///
public static ArrayList GetExcelTables(string ExcelFileName)
{
DataTable dt = new DataTable();
ArrayList TablesList = new ArrayList();
if (File.Exists(ExcelFileName))
{
using (OleDbConnection conn = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Extended Properties=Excel 8.0;Data Source=" + ExcelFileName))
{
try
{
conn.Open();
dt = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[] { null, null, null, "TABLE" });
}
catch (Exception exp)
{
throw exp;
}
//获取数据表个数
int tablecount = dt.Rows.Count;
for (int i = 0; i < tablecount; i++)
{
string tablename = dt.Rows[i][2].ToString().Trim().TrimEnd('$');
if (TablesList.IndexOf(tablename) < 0)
{
TablesList.Add(tablename);
}
}
}
}
return TablesList;
}
///
/// 将Excel文件导出至DataTable(第一行作为表头)
///
/// Excel文件路径
/// 数据表名,如果数据表名错误,默认为第一个数据表名
public static DataTable InputFromExcel(string ExcelFilePath, string TableName)
{
if (!File.Exists(ExcelFilePath))
{
throw new Exception("Excel文件不存在!");
}
//如果数据表名不存在,则数据表名为Excel文件的第一个数据表
ArrayList TableList = new ArrayList();
TableList = GetExcelTables(ExcelFilePath);
if (TableName.IndexOf(TableName) < 0)
{
TableName = TableList[0].ToString().Trim();
}
DataTable table = new DataTable();
OleDbConnection dbcon = new OleDbConnection(@"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + ExcelFilePath + ";Extended Properties=Excel 8.0");
OleDbCommand cmd = new OleDbCommand("select * from [" + TableName + "$]", dbcon);
OleDbDataAdapter adapter = new OleDbDataAdapter(cmd);
try
{
if (dbcon.State == ConnectionState.Closed)
{
dbcon.Open();
}
adapter.Fill(table);
}
catch (Exception exp)
{
throw exp;
}
finally
{
if (dbcon.State == ConnectionState.Open)
{
dbcon.Close();
}
}
return table;
}
///
/// 获取Excel文件指定数据表的数据列表
///
/// Excel文件名
/// 数据表名
public static ArrayList GetExcelTableColumns(string ExcelFileName, string TableName)
{
DataTable dt = new DataTable();
ArrayList ColsList = new ArrayList();
if (File.Exists(ExcelFileName))
{
using (OleDbConnection conn = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Extended Properties=Excel 8.0;Data Source=" + ExcelFileName))
{
conn.Open();
dt = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Columns, new object[] { null, null, TableName, null });
//获取列个数
int colcount = dt.Rows.Count;
for (int i = 0; i < colcount; i++)
{
string colname = dt.Rows[i]["Column_Name"].ToString().Trim();
ColsList.Add(colname);
}
}
}
return ColsList;
}
public static bool dataTableToCsv(DataTable table, string file)
{
bool lcRetval = false;
if (File.Exists(file))
{
throw new Exception("该文件已经存在!");
}
try
{
string title = "";
FileStream fs = new FileStream(file, FileMode.OpenOrCreate);
//FileStream fs1 = File.Open(file, FileMode.Open, FileAccess.Read);
StreamWriter sw = new StreamWriter(new BufferedStream(fs), System.Text.Encoding.Default);
for (int i = 0; i < table.Columns.Count; i++)
{
title += table.Columns[i].ColumnName + "\t"; //栏位:自动跳到下一单元格
}
title = title.Substring(0, title.Length - 1) + "\n";
sw.Write(title);
foreach (DataRow row in table.Rows)
{
string line = "";
for (int i = 0; i < table.Columns.Count; i++)
{
line += row[i].ToString().Trim() + "\t"; //内容:自动跳到下一单元格
}
line = line.Substring(0, line.Length - 1) + "\n";
sw.Write(line);
}
sw.Close();
fs.Close();
lcRetval = true;
}catch(Exception err)
{
ThreadLog.LogException(err);
}
return lcRetval;
}
}
public static class ExcelHelper2
{
#region Excel导入
///
/// 从Excel取数据并记录到List集合里
///
/// 单元头的值和名称:{ { "UserName", "姓名" }, { "Age", "年龄" } };
/// 保存文件绝对路径
/// 错误信息
/// 数据行开始序列,默认为1(即第二列,从0开始)
/// 转换后的List对象集合
public static List ExcelToEntityList(this Dictionary cellHeader, string filePath, out string errMsg, int startIndex = 1) where T : new()
{
List enlist = new List();
var errorMsg = new StringBuilder();
try
{
if (Regex.IsMatch(filePath, ".xls$")) // 2003
{
enlist = Excel2003ToEntityList(cellHeader, filePath, out errorMsg, startIndex);
}
else if (Regex.IsMatch(filePath, ".xlsx$")) // 2007
{
enlist = Excel2007ToEntityList(cellHeader, filePath, out errorMsg, startIndex);
}
}
catch (Exception ex)
{
errMsg = ex.Message;
//typeof(ExcelHelper).LogError(ex);
return default(List);
}
errMsg = errorMsg.ToString();
return enlist;
}
///
/// 从Excel2003取数据并记录到List集合里
///
/// 单元头的Key和Value:{ { "UserName", "姓名" }, { "Age", "年龄" } };
/// 保存文件绝对路径
/// 错误信息
///
/// 转换好的List对象集合
private static List Excel2003ToEntityList(this Dictionary cellHeader, string filePath, out StringBuilder errorMsg, int startIndex = 1) where T : new()
{
errorMsg = new StringBuilder(); // 错误信息,Excel转换到实体对象时,会有格式的错误信息
List enlist = new List(); // 转换后的集合
try
{
using (FileStream fs = File.OpenRead(filePath))
{
HSSFWorkbook workbook = new HSSFWorkbook(fs);
HSSFSheet sheet = (HSSFSheet)workbook.GetSheetAt(0); // 获取此文件第一个Sheet页
for (int rowIndex = startIndex; rowIndex <= sheet.LastRowNum; rowIndex++)
{
// 1.判断当前行是否空行,若空行就不在进行读取下一行操作,结束Excel读取操作
IRow row = sheet.GetRow(rowIndex);
if (row == null)
{
break;
}
// 2.每一个Excel row转换为一个实体对象
T en = new T();
ExcelRowToEntity(cellHeader, row, rowIndex, en, ref errorMsg);
enlist.Add(en);
}
}
return enlist;
}
catch (Exception ex)
{
//typeof(ExcelHelper).LogError(ex);
return default(List);
}
}
///
/// 从Excel2007取数据并记录到List集合里
///
/// 单元头的Key和Value:{ { "UserName", "姓名" }, { "Age", "年龄" } };
/// 保存文件绝对路径
/// 错误信息
/// 数据行开始序列,默认为1(即第二列,从0开始)
/// 转换好的List对象集合
private static List Excel2007ToEntityList(this Dictionary cellHeader, string filePath, out StringBuilder errorMsg, int startIndex = 1)
where T : new()
{
errorMsg = new StringBuilder(); // 错误信息,Excel转换到实体对象时,会有格式的错误信息
List enlist = new List(); // 转换后的集合
try
{
using (FileStream fs = File.OpenRead(filePath))
{
XSSFWorkbook workbook = new XSSFWorkbook(fs);
XSSFSheet sheet = (XSSFSheet)workbook.GetSheetAt(0); // 获取此文件第一个Sheet页
for (int rowIndex = startIndex; rowIndex <= sheet.LastRowNum; rowIndex++)
{
// 1.判断当前行是否空行,若空行就不在进行读取下一行操作,结束Excel读取操作
IRow row = sheet.GetRow(rowIndex);
if (row == null)
{
break;
}
// 2.每一个Excel row转换为一个实体对象
T en = new T();
ExcelRowToEntity(cellHeader, row, rowIndex, en, ref errorMsg);
enlist.Add(en);
}
}
return enlist;
}
catch (Exception ex)
{
//typeof(ExcelHelper).LogError(ex);
return default(List);
}
}
#endregion Excel导入
#region Excel导出
///
/// 实体类集合导出到EXCEL2003
///
/// 单元头的Key和Value:{ { "UserName", "姓名" }, { "Age", "年龄" } };
/// 数据源
/// 工作表名称
/// 文件的下载地址
///
public static string EntityListToExcel2003(this Dictionary cellHeader, IList enList, string sheetName, string filePath)
{
var lcRetVal = "error@";
try
{
string fileName = $"D-{sheetName}-{DateTime.Now:yyyyMMddHHmmssfff}.xls"; // 文件名称
filePath = filePath.StartsWith("/") ? filePath : ("/" + filePath);
filePath = filePath.EndsWith("/") ? filePath : (filePath + "/");
string path = $"{AppDomain.CurrentDomain.BaseDirectory}{filePath}";
if (!Directory.Exists(path))
Directory.CreateDirectory(path);
// 2.解析单元格头部,设置单元头的中文名称
HSSFWorkbook workbook = new HSSFWorkbook(); // 工作簿
ISheet sheet = workbook.CreateSheet(sheetName); // 工作表
IRow row = sheet.CreateRow(0);
List keys = cellHeader.Keys.ToList();
for (int i = 0; i < keys.Count; i++)
{
row.CreateCell(i).SetCellValue(cellHeader[keys[i]]); // 列名为Key的值
}
// 3.List对象的值赋值到Excel的单元格里
int rowIndex = 1; // 从第二行开始赋值(第一行已设置为单元头)
object propertyValue = null;
foreach (var en in enList)
{
IRow rowTmp = sheet.CreateRow(rowIndex);
for (int i = 0; i < keys.Count; i++) // 根据指定的属性名称,获取对象指定属性的值
{
string cellValue = "";
PropertyInfo propertyInfo = null; // 属性的信息
// 3.1 若属性头的名称包含'.',就表示是子类里的属性,那么就要遍历子类,eg:UserEn.UserName
string[] propertyArray = keys[i].Split(new[] { "." }, StringSplitOptions.RemoveEmptyEntries);
if (keys[i].IndexOf(".", StringComparison.Ordinal) >= 0)
{
// 3.1.1 解析子类属性(这里只解析1层子类,多层子类未处理)
string subClassName = propertyArray[0]; // '.'前面的为子类的名称
string subClassPropertyName = propertyArray[1]; // '.'后面的为子类的属性名称
PropertyInfo subClassInfo = en.GetType().GetProperty(subClassName); // 获取子类的类型
if (subClassInfo != null)
{
// 3.1.2 获取子类的实例
var subClassEn = en.GetType().GetProperty(subClassName)?.GetValue(en, null);
// 3.1.3 根据属性名称获取子类里的属性类型
propertyInfo = subClassInfo.PropertyType.GetProperty(subClassPropertyName);
if (propertyInfo != null)
{
propertyValue = propertyInfo.GetValue(subClassEn, null); // 获取子类属性的值
}
}
}
else
{
// 3.2 若不是子类的属性,直接根据属性名称获取对象对应的属性
propertyInfo = en.GetType().GetProperty(keys[i]);
if (propertyInfo != null)
{
propertyValue = propertyInfo.GetValue(en, null);
}
}
// 3.3 属性值经过转换赋值给单元格值
if (propertyValue != null)
{
if (propertyInfo?.PropertyType.Name == "int" || propertyInfo?.PropertyType.Name == "float" || propertyInfo?.PropertyType.Name == "double" || propertyInfo?.PropertyType.Name == "decimal")
{
var value = Convert.ToDouble(propertyValue);
rowTmp.CreateCell(i).SetCellValue(value);
}
else if (propertyInfo?.PropertyType.Name == "bool")
{
var value = Convert.ToBoolean(propertyValue);
rowTmp.CreateCell(i).SetCellValue(value);
}
else
{
cellValue = propertyValue.ToString();
// 3.3.1 对时间初始值赋值为空
if (cellValue.Trim() == "0001/1/1 0:00:00" || cellValue.Trim() == "0001/1/1 23:59:59")
{
cellValue = "";
}
// 3.4 填充到Excel的单元格里
rowTmp.CreateCell(i).SetCellValue(cellValue);
}
}
else
{
// 3.4 填充到Excel的单元格里
rowTmp.CreateCell(i).SetCellValue(cellValue);
}
}
rowIndex++;
}
// 4.生成文件
FileStream file = new FileStream($"{path}{fileName}", FileMode.Create);
workbook.Write(file);
file.Close();
lcRetVal = $"{filePath}{fileName}";
}
catch (Exception ex)
{
lcRetVal += ex.Message;
//typeof(ExcelHelper).LogError(ex);
}
return lcRetVal;
}
public static string EntityListToExcel2003(this HSSFWorkbook workbook,
string sheetName, string filePath)
{
var lcRetVal = "error@";
try
{
string fileName = $"D-{sheetName}-{DateTime.Now:yyyyMMddHHmmssfff}.xls"; // 文件名称
filePath = filePath.StartsWith("/") ? filePath : ("/" + filePath);
filePath = filePath.EndsWith("/") ? filePath : (filePath + "/");
string path = $"{AppDomain.CurrentDomain.BaseDirectory}{filePath}";
if (!Directory.Exists(path))
Directory.CreateDirectory(path);
FileStream file = new FileStream($"{path}{fileName}", FileMode.Create);
workbook.Write(file);
file.Close();
lcRetVal = $"{filePath}{fileName}";
}
catch (Exception ex)
{
lcRetVal += ex.Message;
//typeof(ExcelHelper).LogError(ex);
}
return lcRetVal;
}
public static HSSFWorkbook EntityListToExcel2003Book(this Dictionary cellHeader, IList enList,
string sheetName)
{
HSSFWorkbook workbook = new HSSFWorkbook(); // 工作簿
ISheet sheet = workbook.CreateSheet(sheetName); // 工作表
IRow row = sheet.CreateRow(0);
List keys = cellHeader.Keys.ToList();
for (int i = 0; i < keys.Count; i++)
{
row.CreateCell(i).SetCellValue(cellHeader[keys[i]]); // 列名为Key的值
}
// 3.List对象的值赋值到Excel的单元格里
int rowIndex = 1; // 从第二行开始赋值(第一行已设置为单元头)
foreach (var en in enList)
{
IRow rowTmp = sheet.CreateRow(rowIndex);
for (int i = 0; i < keys.Count; i++) // 根据指定的属性名称,获取对象指定属性的值
{
string cellValue = ""; // 单元格的值
object propertyValue = null; // 属性的值
PropertyInfo propertyInfo; // 属性的信息
// 3.1 若属性头的名称包含'.',就表示是子类里的属性,那么就要遍历子类,eg:UserEn.UserName
if (keys[i].IndexOf(".", StringComparison.Ordinal) >= 0)
{
// 3.1.1 解析子类属性(这里只解析1层子类,多层子类未处理)
string[] propertyArray = keys[i].Split(new[] { "." }, StringSplitOptions.RemoveEmptyEntries);
string subClassName = propertyArray[0]; // '.'前面的为子类的名称
string subClassPropertyName = propertyArray[1]; // '.'后面的为子类的属性名称
PropertyInfo subClassInfo = en.GetType().GetProperty(subClassName); // 获取子类的类型
if (subClassInfo != null)
{
// 3.1.2 获取子类的实例
var subClassEn = en.GetType().GetProperty(subClassName)?.GetValue(en, null);
// 3.1.3 根据属性名称获取子类里的属性类型
propertyInfo = subClassInfo.PropertyType.GetProperty(subClassPropertyName);
if (propertyInfo != null)
{
propertyValue = propertyInfo.GetValue(subClassEn, null); // 获取子类属性的值
}
}
}
else
{
// 3.2 若不是子类的属性,直接根据属性名称获取对象对应的属性
propertyInfo = en.GetType().GetProperty(keys[i]);
if (propertyInfo != null)
{
propertyValue = propertyInfo.GetValue(en, null);
}
}
// 3.3 属性值经过转换赋值给单元格值
if (propertyValue != null)
{
cellValue = propertyValue.ToString();
// 3.3.1 对时间初始值赋值为空
if (cellValue.Trim() == "0001/1/1 0:00:00" || cellValue.Trim() == "0001/1/1 23:59:59")
{
cellValue = "";
}
}
// 3.4 填充到Excel的单元格里
rowTmp.CreateCell(i).SetCellValue(cellValue);
}
rowIndex++;
}
return workbook;
}
///
/// 实体类集合导出到EXCEL2007
///
/// 单元头的Key和Value:{ { "UserName", "姓名" }, { "Age", "年龄" } };
/// 数据源
/// 工作表名称
/// 文件的下载地址
///
public static string EntityListToExcel2007(this Dictionary cellHeader, IList enList, string sheetName, string filePath)
{
var lcRetVal = "error@";
try
{
string fileName = $"D-{sheetName}-{DateTime.Now:yyyyMMddHHmmssfff}.xlsx"; // 文件名称
filePath = filePath.StartsWith("/") ? filePath : ("/" + filePath);
filePath = filePath.EndsWith("/") ? filePath : (filePath + "/");
string path = $"{AppDomain.CurrentDomain.BaseDirectory}{filePath}";
if (!Directory.Exists(path))
Directory.CreateDirectory(path);
// 2.解析单元格头部,设置单元头的中文名称
XSSFWorkbook workbook = new XSSFWorkbook(); // 工作簿
ISheet sheet = workbook.CreateSheet(sheetName); // 工作表
IRow row = sheet.CreateRow(0);
List keys = cellHeader.Keys.ToList();
for (int i = 0; i < keys.Count; i++)
{
row.CreateCell(i).SetCellValue(cellHeader[keys[i]]); // 列名为Key的值
}
// 3.List对象的值赋值到Excel的单元格里
int rowIndex = 1; // 从第二行开始赋值(第一行已设置为单元头)
foreach (var en in enList)
{
IRow rowTmp = sheet.CreateRow(rowIndex);
for (int i = 0; i < keys.Count; i++) // 根据指定的属性名称,获取对象指定属性的值
{
string cellValue = ""; // 单元格的值
object propertyValue = null; // 属性的值
PropertyInfo propertyInfo = null; // 属性的信息
// 3.1 若属性头的名称包含'.',就表示是子类里的属性,那么就要遍历子类,eg:UserEn.UserName
if (keys[i].IndexOf(".", StringComparison.Ordinal) >= 0)
{
// 3.1.1 解析子类属性(这里只解析1层子类,多层子类未处理)
string[] propertyArray = keys[i].Split(new[] { "." }, StringSplitOptions.RemoveEmptyEntries);
string subClassName = propertyArray[0]; // '.'前面的为子类的名称
var subClassPropertyName = propertyArray[1]; // '.'后面的为子类的属性名称
PropertyInfo subClassInfo = en.GetType().GetProperty(subClassName); // 获取子类的类型
if (subClassInfo != null)
{
// 3.1.2 获取子类的实例
var subClassEn = en.GetType().GetProperty(subClassName)?.GetValue(en, null);
// 3.1.3 根据属性名称获取子类里的属性类型
propertyInfo = subClassInfo.PropertyType.GetProperty(subClassPropertyName);
if (propertyInfo != null)
{
propertyValue = propertyInfo.GetValue(subClassEn, null); // 获取子类属性的值
}
}
}
else
{
// 3.2 若不是子类的属性,直接根据属性名称获取对象对应的属性
propertyInfo = en.GetType().GetProperty(keys[i]);
if (propertyInfo != null)
{
propertyValue = propertyInfo.GetValue(en, null);
}
}
// 3.3 属性值经过转换赋值给单元格值
if (propertyValue != null)
{
if (propertyInfo.PropertyType.Name.ToLower() == "int" || propertyInfo.PropertyType.Name.ToLower() == "int16" || propertyInfo.PropertyType.Name.ToLower() == "int32" || propertyInfo.PropertyType.Name.ToLower() == "int64" || propertyInfo.PropertyType.Name.ToLower() == "double" || propertyInfo.PropertyType.Name.ToLower() == "decimal")
{
var value = Convert.ToDouble(propertyValue);
rowTmp.CreateCell(i).SetCellValue(value);
}
else if (propertyInfo.PropertyType.Name.ToLower() == "bool")
{
var value = Convert.ToBoolean(propertyValue);
rowTmp.CreateCell(i).SetCellValue(value);
}
else if (propertyInfo.PropertyType.Name.ToLower() == "nullable`1")
{
if (propertyInfo.PropertyType.FullName == null)
{
}
else if (propertyInfo.PropertyType.FullName.ToLower().Contains("datetime"))
{
cellValue = propertyValue.ToString();
// 3.3.1 对时间初始值赋值为空
if (cellValue.Trim() == "0001/1/1 0:00:00" || cellValue.Trim() == "0001/1/1 23:59:59")
{
cellValue = "";
}
rowTmp.CreateCell(i).SetCellValue(cellValue);
}
else if (propertyInfo.PropertyType.FullName.ToLower().Contains("int"))
{
var value = (int)Convert.ChangeType(propertyValue, typeof(int));
rowTmp.CreateCell(i).SetCellValue(value);
}
else if (propertyInfo.PropertyType.FullName.ToLower().Contains("float") || propertyInfo.PropertyType.FullName.ToLower().Contains("double") || propertyInfo.PropertyType.FullName.ToLower().Contains("decimal") || propertyInfo.PropertyType.FullName.ToLower().Contains("single"))
{
var value = (float)Convert.ChangeType(propertyValue, typeof(float));
rowTmp.CreateCell(i).SetCellValue(value);
}
else if (propertyInfo.PropertyType.FullName.ToLower().Contains("bool"))
{
var value = (bool)Convert.ChangeType(propertyValue, typeof(bool));
rowTmp.CreateCell(i).SetCellValue(value);
}
}
else
{
cellValue = propertyValue.ToString();
// 3.3.1 对时间初始值赋值为空
if (cellValue.Trim() == "0001/1/1 0:00:00" || cellValue.Trim() == "0001/1/1 23:59:59")
{
cellValue = "";
}
// 3.4 填充到Excel的单元格里
rowTmp.CreateCell(i).SetCellValue(cellValue);
}
}
else
{
// 3.4 填充到Excel的单元格里
rowTmp.CreateCell(i).SetCellValue(cellValue);
}
}
rowIndex++;
}
// 4.生成文件
FileStream file = new FileStream($"{path}{fileName}", FileMode.Create);
workbook.Write(file);
file.Close();
lcRetVal = $"{filePath}{fileName}";
}
catch (Exception ex)
{
lcRetVal += ex.Message;
//typeof(ExcelHelper).LogError(ex);
}
return lcRetVal;
}
#endregion Excel导出
#region Common
///
/// Excel row转换为实体对象
///
///
/// 单元头的Key和Value:{ { "UserName", "姓名" }, { "Age", "年龄" } };
/// Excel row
/// row index
/// 实体
/// 错误信息
private static void ExcelRowToEntity(Dictionary cellHeader, IRow row, int rowIndex, T en, ref StringBuilder errorMsg)
{
List keys = cellHeader.Keys.ToList(); // 要赋值的实体对象属性名称
string errStr = ""; // 当前行转换时,是否有错误信息,格式为:第1行数据转换异常:XXX列;
for (int i = 0; i < keys.Count; i++)
{
// 1.若属性头的名称包含'.',就表示是子类里的属性,那么就要遍历子类,eg:UserEn.TrueName
if (keys[i].IndexOf(".", StringComparison.Ordinal) >= 0)
{
// 1)解析子类属性
string[] propertyArray = keys[i].Split(new[] { "." }, StringSplitOptions.RemoveEmptyEntries);
string subClassName = propertyArray[0]; // '.'前面的为子类的名称
string classPropertyName = propertyArray[1]; // '.'后面的为子类的属性名称
PropertyInfo subClassInfo = en.GetType().GetProperty(subClassName); // 获取子类的类型
if (subClassInfo != null)
{
// 2)获取子类的实例
var subClassEn = en.GetType().GetProperty(subClassName)?.GetValue(en, null);
// 3)根据属性名称获取子类里的属性信息
PropertyInfo propertyInfo = subClassInfo.PropertyType.GetProperty(classPropertyName);
if (propertyInfo != null)
{
try
{
// Excel单元格的值转换为对象属性的值,若类型不对,记录出错信息
propertyInfo.SetValue(subClassEn, GetExcelCellToProperty(propertyInfo.PropertyType, row.GetCell(i)), null);
}
catch (Exception e)
{
//typeof(ExcelHelper).LogError(e);
if (errStr.Length == 0)
{
errStr = "第" + rowIndex + "行数据转换异常:";
}
errStr += cellHeader[keys[i]] + "列;";
}
}
}
}
else
{
// 2.给指定的属性赋值
PropertyInfo propertyInfo = en.GetType().GetProperty(keys[i]);
if (propertyInfo != null)
{
try
{
// Excel单元格的值转换为对象属性的值,若类型不对,记录出错信息
propertyInfo.SetValue(en, GetExcelCellToProperty(propertyInfo.PropertyType, row.GetCell(i)), null);
}
catch (Exception e)
{
//typeof(ExcelHelper).LogError(e);
if (errStr.Length == 0)
{
errStr = "第" + rowIndex + "行数据转换异常:";
}
errStr += cellHeader[keys[i]] + "列;";
}
}
}
}
// 若有错误信息,就添加到错误信息里
if (errStr.Length > 0)
{
errorMsg.AppendLine(errStr);
}
}
///
/// Excel Cell转换为实体的属性值
///
/// 目标对象类型
/// 对象属性的值
private static object GetExcelCellToProperty(Type distanceType, ICell sourceCell)
{
object rs = distanceType.IsValueType ? Activator.CreateInstance(distanceType) : null;
// 1.判断传递的单元格是否为空
if (sourceCell == null || string.IsNullOrEmpty(sourceCell.ToString()))
{
return rs;
}
// 2.Excel文本和数字单元格转换,在Excel里文本和数字是不能进行转换,所以这里预先存值
object sourceValue = null;
switch (sourceCell.CellType)
{
case CellType.Blank:
break;
case CellType.Boolean:
sourceValue = sourceCell.BooleanCellValue;
break;
case CellType.Error:
break;
case CellType.Formula:
break;
case CellType.Numeric:
sourceValue = sourceCell.NumericCellValue;
break;
case CellType.String:
sourceValue = sourceCell.StringCellValue;
break;
case CellType.Unknown:
break;
default:
sourceValue = sourceCell.StringCellValue;
break;
}
string valueDataType = distanceType.Name;
// 在这里进行特定类型的处理
switch (valueDataType.ToLower()) // 以防出错,全部小写
{
case "string":
rs = sourceValue?.ToString();
break;
case "int":
case "int32":
rs = (int)Convert.ChangeType(sourceValue?.ToString() ?? "", distanceType);
break;
case "int16":
rs = (short)Convert.ChangeType(sourceValue?.ToString() ?? "", distanceType);
break;
case "int64":
rs = (long)Convert.ChangeType(sourceValue?.ToString() ?? "", distanceType);
break;
case "float":
case "single":
rs = (float)Convert.ChangeType(sourceValue?.ToString() ?? "", distanceType);
break;
case "double":
rs = (double)Convert.ChangeType(sourceValue?.ToString() ?? "", distanceType);
break;
case "decimal":
rs = (decimal)Convert.ChangeType(sourceValue?.ToString() ?? "", distanceType);
break;
case "datetime":
rs = (DateTime)Convert.ChangeType(sourceValue?.ToString() ?? "", distanceType);
break;
case "guid":
rs = (Guid)Convert.ChangeType(sourceValue?.ToString() ?? "", distanceType);
break;
case "nullable`1":
if (distanceType.FullName == null)
{
rs = "";
}
else if (distanceType.FullName.ToLower().Contains("datetime"))
{
rs = (DateTime)Convert.ChangeType(sourceValue?.ToString() ?? "", typeof(DateTime));
}
else if ((bool)distanceType.FullName?.ToLower().Contains("int"))
{
rs = (int)Convert.ChangeType(sourceValue?.ToString() ?? "", typeof(int));
}
else if ((bool)distanceType.FullName?.ToLower().Contains("float") || (bool)distanceType.FullName?.ToLower().Contains("double") || (bool)distanceType.FullName?.ToLower().Contains("decimal") || (bool)distanceType.FullName?.ToLower().Contains("single"))
{
rs = (float)Convert.ChangeType(sourceValue?.ToString() ?? "", typeof(float));
}
else if ((bool)distanceType.FullName?.ToLower().Contains("bool"))
{
rs = (bool)Convert.ChangeType(sourceValue?.ToString() ?? "", typeof(bool));
}
break;
}
return rs;
}
#endregion
public static HSSFWorkbook CreateWorkBook03(string filePath = null)
{
if (string.IsNullOrEmpty(filePath))
{
return new HSSFWorkbook();
}
FileStream file = new FileStream(filePath, FileMode.Open);
return new HSSFWorkbook(file);
}
public static XSSFWorkbook CreateWorkBook07(string filePath = null)
{
if (string.IsNullOrEmpty(filePath))
{
return new XSSFWorkbook();
}
return new XSSFWorkbook(filePath);
}
///
/// 创建Sheet
///
///
///
///
///
///
///
public static ISheet GenerateSheet(this string sheetName, int defaultWidth = 20, int defaultHeight = 20, bool is07 = true, IWorkbook workbook = null)
{
workbook = is07 ? workbook ?? CreateWorkBook07() : workbook ?? CreateWorkBook03();
var sheet = workbook.CreateSheet(sheetName);
sheet.DefaultColumnWidth = defaultWidth;
sheet.DefaultRowHeight = (short)(defaultHeight * 20);
return sheet;
}
///
/// 创建行
///
/// 表
/// 第几行(从1开始计数)
///
public static IRow GenerateRow(this ISheet sheet, int rowIndex)
{
rowIndex = rowIndex <= 0 ? 1 : rowIndex;
var row = sheet.GetRow(rowIndex - 1) ?? sheet.CreateRow(rowIndex - 1);
return row;
}
///
/// 创建单元格
///
/// 表
/// 第几行(从1开始计数)
/// 第几列(从1开始计数)
/// 值
/// 单元格类型
///
public static ICell GenerateCell(this ISheet sheet, int rowIndex, int columnIndex, string val = null, CellType cellType = CellType.String)
{
var row = sheet.GenerateRow(rowIndex);
var cell = GenerateCell(row, columnIndex, val, cellType);
return cell;
}
///
/// 创建单元格
///
/// 行
/// 第几列(从1开始计数)
/// 值
/// 单元格类型
///
public static ICell GenerateCell(this IRow row, int columnIndex, string val = null, CellType cellType = CellType.String)
{
columnIndex = columnIndex <= 0 ? 1 : columnIndex;
var cell = row.GetCell(columnIndex - 1) ?? row.CreateCell(columnIndex - 1);
if (!string.IsNullOrEmpty(val))
{
cell.SetCellValue(val);
cell.SetCellType(cellType);
}
return cell;
}
///
/// 设置列宽度
///
/// 表
/// 第几列(从1开始计数)
/// 宽度
///
public static ISheet SetCellWidth(this ISheet sheet, int columnIndex, int width)
{
sheet.SetColumnWidth(columnIndex - 1, width * 256);
return sheet;
}
///
/// 设置列宽度
///
/// 行
/// 第几列(从1开始计数)
/// 宽度
///
public static IRow SetCellWidth(this IRow row, int columnIndex, int width)
{
row.Sheet.SetColumnWidth(columnIndex - 1, width * 256);
return row;
}
///
/// 设置列宽度
///
/// 单元格
/// 第几列(从1开始计数)
/// 宽度
///
public static ICell SetCellWidth(this ICell cell, int columnIndex, int width)
{
cell.Sheet.SetColumnWidth(columnIndex - 1, width * 256);
return cell;
}
///
/// 设置行高度
///
/// 表
/// 第几行(从1开始计数)
/// 宽度
///
public static ISheet SetRowHeight(this ISheet sheet, int rowIndex, int height)
{
sheet.GetRow(rowIndex - 1).SetRowHeight(height);
return sheet;
}
///
/// 设置行高度
///
/// 行
/// 宽度
///
public static IRow SetRowHeight(this IRow row, int height)
{
row.Height = (short)(height * 20);
return row;
}
///
/// 设置行高度
///
/// 单元格
/// 宽度
///
public static ICell SetRowHeight(this ICell cell, int height)
{
cell.Row.SetRowHeight(height);
return cell;
}
///
/// 设置单元格的值
///
///
///
///
public static ICell SetValue(this ICell cell, string obj)
{
return SetValue(cell, obj);
}
///
/// 设置单元格的值
///
/// 值类型(sting,bool,double,DateTime)
///
///
///
public static ICell SetValue(this ICell cell, object obj)
{
Type type = typeof(T);
bool bValue;
double iValue;
DateTime dValue;
if (type == typeof(string))
{
cell.SetCellValue(obj.ToString());
}
else if (type == typeof(bool) && bool.TryParse(obj.ToString(), out bValue))
{
cell.SetCellValue(bValue);
}
else if ((type == typeof(int) || type == typeof(double) || type == typeof(decimal)) && double.TryParse(obj.ToString(), out iValue))
{
cell.SetCellValue(iValue);
}
else if (type == typeof(DateTime) && DateTime.TryParse(obj.ToString(), out dValue))
{
cell.SetCellValue(dValue);
}
return cell;
}
#region DATA-FORMAT
public static ICellStyle SetCellDateTime(this ICell cell, DateTime value, string formatStr = "yyyy-MM-dd HH:mm:ss")
{
cell.SetCellValue(value);
cell.SetDataFormat(formatStr);
return cell.CellStyle;
}
public static ICellStyle SetCellString(this ICell cell, double value, string formatStr = "@")
{
cell.SetCellValue(value);
cell.SetDataFormat(formatStr);
return cell.CellStyle;
}
public static ICellStyle SetCellDouble(this ICell cell, double value, string formatStr = "0.00")
{
cell.SetCellValue(value);
cell.SetDataFormat(formatStr);
return cell.CellStyle;
}
public static ICellStyle SetCellCurrency(this ICell cell, double value, string formatStr = "¥#,###.##")
{
cell.SetCellValue(value);
cell.SetDataFormat(formatStr);
return cell.CellStyle;
}
public static ICellStyle SetCellPercent(this ICell cell, double value, string formatStr = "0.00%")
{
cell.SetCellValue(value);
cell.SetDataFormat(formatStr);
return cell.CellStyle;
}
public static void SetDataFormat(this ICell cell, string formatStr = "¥#,##0.00")
{
var cellStyle = cell.CellStyle ?? GetCellStyle(cell);
var format = cell.Sheet.Workbook.CreateDataFormat();
cellStyle.DataFormat = format.GetFormat(formatStr);
cell.SetCellStyle(cellStyle);
}
#endregion
#region 合并单元格
///
/// 合并单元格
///
///
/// 开始行数(从1开始计数)
/// 结束行数(从1开始计数)
/// 开始列数(从1开始计数)
/// 结束列数(从1开始计数)
///
public static ISheet MergedRegion(this ISheet sheet, int firstRow, int lastRow, int firstColumn, int lastColumn)
{
var region = GetCellRegion(firstRow, lastRow, firstColumn, lastColumn);
sheet.MergedRegion(region);
return sheet;
}
public static ISheet MergedRegion(this ISheet sheet, CellRangeAddress region)
{
sheet.AddMergedRegion(region);
//SetRegionBorder(sheet, region, borderTypeStr, borderColorStr);
return sheet;
}
public static CellRangeAddress GetCellRegion(this int firstRow, int lastRow, int firstColumn, int lastColumn)
{
firstRow = firstRow <= 0 ? 1 : firstRow;
firstColumn = firstColumn <= 0 ? 1 : firstColumn;
lastRow = lastRow <= 0 ? 1 : lastRow;
lastColumn = lastColumn <= 0 ? 1 : lastColumn;
return new CellRangeAddress(firstRow - 1, lastRow - 1, firstColumn - 1, lastColumn - 1);
}
#endregion
public static ICellStyle GetCellStyle(this ICell cell)
{
return cell.CellStyle ?? cell.Sheet.Workbook.CreateCellStyle();
}
public static void SetCellStyle(this ICell cell, ICellStyle cellStyle)
{
cell.CellStyle = cellStyle;
}
///
/// 保存工作簿
///
///
///
///
///
public static string SaveWorkBook(this ISheet sheet, string filePath, string fileName)
{
try
{
if (!Directory.Exists(filePath))
{
Directory.CreateDirectory(filePath);
}
filePath = filePath.EndsWith("\\") ? filePath : filePath + "\\";
FileStream file = new FileStream(filePath + fileName, FileMode.Create);
sheet.Workbook.Write(file);
file.Close();
return "";
}
catch (Exception e)
{
return e.Message;
}
}
///
/// 保存工作簿
///
///
///
///
///
public static string SaveWorkBook(this IWorkbook workbook, string filePath, string fileName)
{
try
{
if (!Directory.Exists(filePath))
{
Directory.CreateDirectory(filePath);
}
filePath = filePath.EndsWith("\\") ? filePath : filePath + "\\";
var path = filePath + fileName;
if (File.Exists(path))
{
File.Delete(path);
}
FileStream file = new FileStream(path, FileMode.Create);
workbook.Write(file);
file.Close();
return "";
}
catch (Exception e)
{
return e.Message;
}
}
}
}