455 lines
16 KiB
C#
455 lines
16 KiB
C#
|
||
using OfficeOpenXml;
|
||
using OfficeOpenXml.Style;
|
||
|
||
using System;
|
||
using System.Data;
|
||
|
||
using System.Linq;
|
||
using System.Reflection;
|
||
|
||
using Szmedi.Toolkit.Assists;
|
||
|
||
namespace Szmedi.RvKits.Assists;
|
||
|
||
public static class EPPlusHelpers //公式计算最后需要调用Calculate()
|
||
{
|
||
private static PropertyInfo GetPropValue<T>(this T obj, string propName)
|
||
{
|
||
return obj.GetType().GetProperty(propName);
|
||
}
|
||
|
||
private static object Cast(object value, PropertyConfiguration propertyConfiguration)
|
||
{
|
||
return value == null
|
||
? null
|
||
: propertyConfiguration.WriteFormatFunc != null ? propertyConfiguration.WriteFormatFunc(value) : (object)value.ToString().Trim();
|
||
}
|
||
/// <summary>
|
||
/// DataTable导出为Excel
|
||
/// </summary>
|
||
/// <param name="destFileName"></param>
|
||
/// <param name="dt"></param>
|
||
public static void DataTableToExcel(DataTable dt, string destFileName)
|
||
{
|
||
FileInfo fi = new(destFileName);
|
||
using ExcelPackage package = new(fi);
|
||
try
|
||
{
|
||
ExcelWorksheet workSheet = package.Workbook.Worksheets.Add(dt.TableName);
|
||
workSheet.Cells["A1"].LoadFromDataTable(dt, true);
|
||
}
|
||
catch (Exception)
|
||
{
|
||
// ignored
|
||
}
|
||
finally
|
||
{
|
||
package.Save();
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 给第一个表中的单元格赋值
|
||
/// </summary>
|
||
/// <param name="fileName"></param>
|
||
/// <param name="rowNum"></param>
|
||
/// <param name="columnNum"></param>
|
||
/// <param name="value"></param>
|
||
public static void EditCellValue(string fileName, int rowNum, int columnNum, string value)
|
||
{
|
||
FileInfo fi = new(fileName);
|
||
using ExcelPackage package = new(fi);
|
||
//ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
|
||
ExcelWorksheet sheet = package.Workbook.Worksheets[0];
|
||
//string filename = System.IO.Path.GetFileNameWithoutExtension(fileName);
|
||
sheet.Cells[rowNum, columnNum].Value = value;
|
||
package.Save();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 工作表转换为DataTable,首行为表头
|
||
/// </summary>
|
||
/// <param name="worksheet">行列索引从1开始</param>
|
||
/// <returns></returns>
|
||
public static DataTable ExcelSheetToDataTable(ExcelWorksheet worksheet)
|
||
{
|
||
if (worksheet == null)
|
||
{
|
||
return null;
|
||
}
|
||
|
||
//获取worksheet的行数
|
||
int rows = worksheet.Dimension.End.Row;
|
||
//获取worksheet的列数
|
||
int cols = worksheet.Dimension.End.Column;
|
||
|
||
DataTable dt = new(worksheet.Name);
|
||
DataRow dr = null;
|
||
for (int i = 1; i <= rows; i++)
|
||
{
|
||
if (i > 1)
|
||
{
|
||
dr = dt.Rows.Add();
|
||
}
|
||
|
||
for (int j = 1; j <= cols; j++)
|
||
{
|
||
//默认将第一行设置为datatable的标题
|
||
var value = worksheet.Cells[i, j].Value;
|
||
if (i == 1)
|
||
{
|
||
dt.Columns.Add(value == null ? $"标题{i}" : value.ToString());
|
||
}
|
||
//剩下的写入datatable
|
||
else
|
||
{
|
||
dr[j - 1] = value == null ? string.Empty : value.ToString();
|
||
}
|
||
}
|
||
}
|
||
|
||
return dt;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 工作表转换为DataTable
|
||
/// </summary>
|
||
/// <param name="fileName"></param>
|
||
/// <param name="sheetName"></param>
|
||
/// <returns></returns>
|
||
public static DataTable ExcelSheetToDataTable(string fileName, string sheetName)
|
||
{
|
||
FileInfo fi = new(fileName);
|
||
ExcelPackage p = new(fi);
|
||
ExcelWorkbook workbook = p.Workbook;
|
||
ExcelWorksheet worksheet = workbook.Worksheets[sheetName];
|
||
return ExcelSheetToDataTable(worksheet);
|
||
}
|
||
/// <summary>
|
||
/// 从 ExcelPackage 中提取数据集。
|
||
/// </summary>
|
||
/// <param name="package">The Excel package.</param>
|
||
/// <param name="firstRowContainsHeader">if set to <c>true</c> [first row contains header].</param>
|
||
/// <returns></returns>
|
||
public static DataSet ToDataSet(this ExcelPackage package, bool firstRowContainsHeader = false)
|
||
{
|
||
var headerRow = firstRowContainsHeader ? 1 : 0;
|
||
return ToDataSet(package, headerRow);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 从 ExcelPackage 中提取数据集。
|
||
/// </summary>
|
||
/// <param name="package">The Excel package.</param>
|
||
/// <param name="headerRow">标题行。如果没有标题行,则使用 0。值必须为 0 或更大。</param>
|
||
/// <returns></returns>
|
||
/// <exception cref="ArgumentException">headerRow 必须为 0 或更大。</exception>
|
||
public static DataSet ToDataSet(this ExcelPackage package, int headerRow = 0)
|
||
{
|
||
if (headerRow < 0)
|
||
{
|
||
throw new ArgumentOutOfRangeException(nameof(headerRow), headerRow, "必须为 0 或更大。");
|
||
}
|
||
|
||
var result = new DataSet();
|
||
|
||
foreach (var sheet in package.Workbook.Worksheets)
|
||
{
|
||
var table = new DataTable { TableName = sheet.Name };
|
||
|
||
int sheetStartRow = 1;
|
||
if (headerRow > 0)
|
||
{
|
||
sheetStartRow = headerRow;
|
||
}
|
||
var columns = from firstRowCell in sheet.Cells[sheetStartRow, 1, sheetStartRow, sheet.Dimension.End.Column]
|
||
select new DataColumn(headerRow > 0 ? firstRowCell.Value.ToString() : $"Column {firstRowCell.Start.Column}");
|
||
|
||
table.Columns.AddRange(columns.ToArray());
|
||
|
||
var startRow = headerRow > 0 ? sheetStartRow + 1 : sheetStartRow;
|
||
|
||
for (var rowIndex = startRow; rowIndex <= sheet.Dimension.End.Row; rowIndex++)
|
||
{
|
||
var inputRow = sheet.Cells[rowIndex, 1, rowIndex, sheet.Dimension.End.Column];
|
||
var row = table.Rows.Add();
|
||
foreach (var cell in inputRow)
|
||
{
|
||
row[cell.Start.Column - 1] = cell.Value;
|
||
}
|
||
}
|
||
|
||
result.Tables.Add(table);
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
public static void TrimLastEmptyRows(this ExcelWorksheet worksheet)
|
||
{
|
||
while (worksheet.IsLastRowEmpty())
|
||
{
|
||
worksheet.DeleteRow(worksheet.Dimension.End.Row, 1);
|
||
}
|
||
}
|
||
|
||
public static bool IsLastRowEmpty(this ExcelWorksheet worksheet)
|
||
{
|
||
var empties = new List<bool>();
|
||
|
||
for (var index = 1; index <= worksheet.Dimension.End.Column; index++)
|
||
{
|
||
var value = worksheet.Cells[worksheet.Dimension.End.Row, index].Value;
|
||
empties.Add(value == null || string.IsNullOrWhiteSpace(value.ToString()));
|
||
}
|
||
|
||
return empties.All(e => e);
|
||
}
|
||
/// <summary>
|
||
/// 获取工作表
|
||
/// </summary>
|
||
/// <param name="excelFilePath"></param>
|
||
/// <param name="sheetName"></param>
|
||
/// <returns></returns>
|
||
/// <exception cref="Exception"></exception>
|
||
public static ExcelWorksheet GetExcelWorksheet(string excelFilePath, string sheetName)
|
||
{
|
||
var excelworkbook = new FileInfo(excelFilePath);
|
||
using var p = new ExcelPackage(excelworkbook);
|
||
var ws = p.Workbook.Worksheets[sheetName];
|
||
return ws ?? throw new Exception("工作表不存在。");
|
||
}
|
||
|
||
/// <summary>
|
||
/// 读取Excel所有表
|
||
/// </summary>
|
||
/// <param name="filePath"></param>
|
||
public static void ReadSheets(string filePath)
|
||
{
|
||
using ExcelPackage package = new(new FileStream(filePath, FileMode.Open));
|
||
for (int i = 1; i <= package.Workbook.Worksheets.Count; ++i)
|
||
{
|
||
ExcelWorksheet sheet = package.Workbook.Worksheets[i];
|
||
for (int j = sheet.Dimension.Start.Column, k = sheet.Dimension.End.Column; j <= k; j++)
|
||
{
|
||
for (int m = sheet.Dimension.Start.Row, n = sheet.Dimension.End.Row; m <= n; m++)
|
||
{
|
||
//string str = GetValue(sheet, m, j);
|
||
//if (str != null)
|
||
//{
|
||
// // do something
|
||
//}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
/// <summary>
|
||
/// 读取Excel所有表
|
||
/// </summary>
|
||
/// <param name="filePath"></param>
|
||
public static ExcelPackage ReadExcel(string filePath)
|
||
{
|
||
return new(new FileStream(filePath, FileMode.Open));
|
||
|
||
}
|
||
/// <summary>
|
||
/// 设置单元格的值
|
||
/// </summary>
|
||
/// <param name="sheet"></param>
|
||
/// <param name="rowNum">1开始</param>
|
||
/// <param name="columnNum">1开始</param>
|
||
/// <param name="value"></param>
|
||
public static void SetCellValue(ExcelWorksheet sheet, int rowNum, int columnNum, string value)
|
||
{
|
||
//sheet.Cells[rowNum, ColumnNum].Value = value;
|
||
sheet.SetValue(rowNum, columnNum, value);
|
||
}
|
||
/// <summary>
|
||
/// 通过单元格名设置值
|
||
/// </summary>
|
||
/// <param name="sheet"></param>
|
||
/// <param name="cellName"></param>
|
||
/// <param name="value"></param>
|
||
public static void SetCellValue(ExcelWorksheet sheet, string cellName, string value)
|
||
{
|
||
sheet.Cells[cellName].Value = value;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 给工作表中的单元格赋值
|
||
/// </summary>
|
||
/// <param name="fileName"></param>
|
||
/// <param name="sheetname"></param>
|
||
/// <param name="rowNum"></param>
|
||
/// <param name="columnNum"></param>
|
||
/// <param name="value"></param>
|
||
public static void SetCellValue(string fileName, string sheetname, int rowNum, int columnNum, string value)
|
||
{
|
||
FileInfo fi = new(fileName);
|
||
using ExcelPackage package = new(fi);
|
||
//ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
|
||
ExcelWorksheet sheet = package.Workbook.Worksheets[sheetname];
|
||
//string filename = System.IO.Path.GetFileNameWithoutExtension(fileName);
|
||
sheet.SetValue(rowNum, columnNum, value);
|
||
package.Save();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 给工作表中的单元格赋值
|
||
/// </summary>
|
||
/// <param name="fileName"></param>
|
||
/// <param name="sheetname"></param>
|
||
/// <param name="cellName">单元格名称,比如A1</param>
|
||
/// <param name="value"></param>
|
||
public static void SetCellValue(string fileName, string sheetname, string cellName, string value)
|
||
{
|
||
FileInfo fi = new(fileName);
|
||
using ExcelPackage package = new(fi);
|
||
//ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
|
||
ExcelWorksheet sheet = package.Workbook.Worksheets[sheetname];
|
||
//string filename = System.IO.Path.GetFileNameWithoutExtension(fileName);
|
||
sheet.Cells[cellName].Value = value;
|
||
package.Save();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 给工作表中的单元格赋值
|
||
/// </summary>
|
||
/// <param name="fileName"></param>
|
||
/// <param name="index">表索引,0开始</param>
|
||
/// <param name="cellName">单元格名称,如A1</param>
|
||
/// <param name="value"></param>
|
||
public static void SetCellValue(string fileName, int index, string cellName, string value)
|
||
{
|
||
FileInfo fi = new(fileName);
|
||
using ExcelPackage package = new(fi);
|
||
//ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
|
||
ExcelWorksheet sheet = package.Workbook.Worksheets[index];
|
||
//string filename = System.IO.Path.GetFileNameWithoutExtension(fileName);
|
||
sheet.Cells[cellName].Value = value;
|
||
package.Save();
|
||
}
|
||
/// <summary>
|
||
/// 设置样式
|
||
/// </summary>
|
||
/// <param name="sheet"></param>
|
||
/// <param name="fromRow"></param>
|
||
/// <param name="fromCol"></param>
|
||
/// <param name="toRow"></param>
|
||
/// <param name="toCol"></param>
|
||
public static void SetStyle(ExcelWorksheet sheet, int fromRow, int fromCol, int toRow, int toCol)
|
||
{
|
||
using var range = sheet.Cells[fromRow, fromCol, toRow, toCol];
|
||
//range.Style.Font.Name = "微软雅黑";
|
||
range.Style.HorizontalAlignment = ExcelHorizontalAlignment.Center;
|
||
range.Style.Font.Size = 12;
|
||
range.Style.Border.Top.Style = ExcelBorderStyle.Thin;
|
||
range.Style.Border.Bottom.Style = ExcelBorderStyle.Thin;
|
||
range.Style.Border.Left.Style = ExcelBorderStyle.Thin;
|
||
range.Style.Border.Right.Style = ExcelBorderStyle.Thin;
|
||
//range.Style.SetBackgroundColor(System.Drawing.Color.FromArgb(142, 169, 219));
|
||
}
|
||
/// <summary>
|
||
/// 设置表头样式
|
||
/// </summary>
|
||
/// <param name="sheet"></param>
|
||
/// <param name="fromRow"></param>
|
||
/// <param name="fromCol"></param>
|
||
/// <param name="toRow"></param>
|
||
/// <param name="toCol"></param>
|
||
public static void SetTitle(ExcelWorksheet sheet, int fromRow, int fromCol, int toRow, int toCol)
|
||
{
|
||
using var range = sheet.Cells[fromRow, fromCol, toRow, toCol];
|
||
range.Style.Font.Name = "微软雅黑";
|
||
range.Style.HorizontalAlignment = ExcelHorizontalAlignment.Center;
|
||
range.Style.Font.Size = 14;
|
||
range.Style.Font.Bold = true;
|
||
range.Style.Border.Top.Style = ExcelBorderStyle.Thin;
|
||
range.Style.Border.Bottom.Style = ExcelBorderStyle.Thin;
|
||
range.Style.Border.Left.Style = ExcelBorderStyle.Thin;
|
||
range.Style.Border.Right.Style = ExcelBorderStyle.Thin;
|
||
//range.SetBackgroundColor(System.Drawing.Color.FromArgb(142, 169, 219));
|
||
}
|
||
/// <summary>
|
||
/// 创建Excel文件添加Excel表格
|
||
/// </summary>
|
||
/// <param name="filePath"></param>
|
||
/// <param name="sheetName"></param>
|
||
/// <param name="action"></param>
|
||
public static void WriteExcel(string filePath, string sheetName, Action<ExcelPackage> action)
|
||
{
|
||
using ExcelPackage package = new();
|
||
ExcelWorksheet sheet = package.Workbook.Worksheets.Add(sheetName);
|
||
|
||
using Stream stream = new FileStream(filePath, FileMode.Create);
|
||
action(package);
|
||
package.SaveAs(stream);
|
||
}
|
||
/// <summary>
|
||
/// 写入Excel
|
||
/// </summary>
|
||
/// <param name="filePath"></param>
|
||
/// <param name="action"></param>
|
||
public static void WriteExcel(string filePath, Action<ExcelPackage> action)
|
||
{
|
||
var fileInfo = new FileInfo(filePath);
|
||
if (fileInfo.Exists)
|
||
{
|
||
fileInfo.Delete();
|
||
}
|
||
using ExcelPackage package = new(fileInfo);
|
||
action(package);
|
||
package.Save();
|
||
}
|
||
public static IEnumerable<T> ReadRecords<T>(string path, int headerIndex = 1, string sheet = null, Type type = null)
|
||
where T : new()
|
||
{
|
||
using var package = new ExcelPackage(new FileInfo(path));
|
||
|
||
var worksheet = string.IsNullOrWhiteSpace(sheet)
|
||
? package.Workbook.Worksheets.FirstOrDefault()
|
||
: package.Workbook.Worksheets.FirstOrDefault(i => i.Name == sheet);
|
||
|
||
var results = worksheet.Read<T>(headerIndex, type);
|
||
|
||
return results;
|
||
}
|
||
public static byte[] ToBytes<T>(IEnumerable<T> items, string sheetName, Type type = null)
|
||
{
|
||
var mapClass = type ?? AppDomain.CurrentDomain
|
||
.GetAssemblies()
|
||
.Where(a => a.FullName.StartsWith("Namespace"))
|
||
.SelectMany(i => i.GetTypes().Where(t => t.IsClass && typeof(BaseTypeConfiguration<T>).IsAssignableFrom(t)))
|
||
.FirstOrDefault();
|
||
|
||
var instance = (BaseTypeConfiguration<T>)Activator.CreateInstance(mapClass);
|
||
var mappings = instance.GetMappings().OrderBy(x => x.Order).ToList();
|
||
|
||
var cols = new List<(int index, string name, int order, PropertyConfiguration propertyConfiguration)>();
|
||
var results = new List<object>();
|
||
|
||
using var package = new ExcelPackage();
|
||
var worksheet = package.Workbook.Worksheets.Add(sheetName);
|
||
|
||
var row = 1;
|
||
|
||
mappings.ForEach(map => worksheet.Cells[row, map.Order].Value = map.Name);
|
||
|
||
foreach (var item in items)
|
||
{
|
||
row++;
|
||
|
||
mappings.ForEach(map =>
|
||
{
|
||
var propertyInfo = item.GetPropValue(map.Member.Name);
|
||
var value = Cast(propertyInfo.GetValue(item, null), map);
|
||
|
||
worksheet.Cells[row, map.Order].Value = value;
|
||
});
|
||
}
|
||
|
||
return package.GetAsByteArray();
|
||
|
||
}
|
||
} |