using Admin.NET.Core.Helper.ExcelHelper;
using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using System.Drawing.Imaging;
using ICell = NPOI.SS.UserModel.ICell;
namespace PandaWork.Infrastructure;
///
/// ExcelHelper导入
///
public class ExcelOperation
{
///
/// 以时间命名
///
///
///
public static string GetFileName(string name)
{
string FileName = $"{name}{DateTime.Now.ToString("yyyyMMddhhmmss")}.xls";
return FileName;
}
///
/// 以时间命名不带后缀名
///
///
///
public static string GetFileNameEmpty(string name)
{
string FileName = $"{name}{DateTime.Now.ToString("yyyyMMddhhmmss")}";
return FileName;
}
///
/// 导出 返回具体的路径文件
///
/// 支持多个sheet导入
/// xxx.xlsx
/// 路径可为null
/// 默认 "DownloadExcel\\"
///
public static string ExportExcel(Dictionary dtDictionary, string FileName, string ProjectPath = "", string ExportPath = "")
{
if (dtDictionary is null || dtDictionary.Count == 0) return null;
if (string.IsNullOrWhiteSpace(FileName)) FileName = Guid.NewGuid().ToString() + ".xlsx";
if (string.IsNullOrWhiteSpace(ProjectPath)) ProjectPath = ExcelOperation.ProjectPath();
if (string.IsNullOrWhiteSpace(ExportPath)) ExportPath = "DownloadExcel\\";
Excel excel = new Excel();
foreach (var dt in dtDictionary)
{
if (dt.Value != null && dt.Value.Rows.Count > 0)
{
excel.CreateSheet(dt.Value.Columns, dt.Key);
foreach (DataRow row in dt.Value.Rows)
{
excel.SetRowValue(row);
}
}
}
string filePath = ProjectPath + ExportPath;
if (!System.IO.Directory.Exists(filePath)) Directory.CreateDirectory(filePath);
filePath = filePath + FileName;
excel.SaveAs(filePath);
// return "\\" + ExportPath + FileName;
return filePath;
}
///
/// 导出 返回个steam流
///
/// 支持多个sheet导入
/// xxx.xlsx
/// 路径可为null
/// 默认 "DownloadExcel\\"
///
public static Stream ExportExcel(Dictionary dtDictionary)
{
if (dtDictionary is null || dtDictionary.Count == 0) return null;
// if (string.IsNullOrWhiteSpace(FileName)) FileName = Guid.NewGuid().ToString() + ".xlsx";
//if (string.IsNullOrWhiteSpace(ProjectPath)) ProjectPath = ExcelOperation.ProjectPath();
//if (string.IsNullOrWhiteSpace(ExportPath)) ExportPath = "DownloadExcel\\";
Excel excel = new Excel();
foreach (var dt in dtDictionary)
{
if (dt.Value != null && dt.Value.Rows.Count > 0)
{
excel.CreateSheet(dt.Value.Columns, dt.Key);
foreach (DataRow row in dt.Value.Rows)
{
excel.SetRowValue(row);
}
}
}
MemoryStream memoryStream = excel.SaveAsMemoryStream();
return memoryStream;
}
///
/// 获取当前项目的目录
///
///
public static string ProjectPath()
{
string Paths = System.AppDomain.CurrentDomain.BaseDirectory;
return Paths;
}
///
/// 去除空行
///
///
///
private static DataTable RemoveEmpty(DataTable dt)
{
List removelist = new List();
for (int i = 0; i < dt.Rows.Count; i++)
{
bool rowdataisnull = true;
for (int j = 0; j < dt.Columns.Count; j++)
{
if (!string.IsNullOrEmpty(dt.Rows[i][j].ToString().Trim()))
{
rowdataisnull = false;
}
}
if (rowdataisnull)
{
removelist.Add(dt.Rows[i]);
}
}
for (int i = 0; i < removelist.Count; i++)
{
dt.Rows.Remove(removelist[i]);
}
return dt;
}
///
/// 将excel导入到datatable
///
/// excel路径
/// 第一行是否是列名
/// 返回datatable
public static System.Data.DataTable ExcelToDataTable(string filePath, bool isColumnName)
{
System.Data.DataTable dataTable = null;
FileStream fs = null;
DataColumn column = null;
DataRow dataRow = null;
IWorkbook workbook = null;
ISheet sheet = null;
IRow row = null;
ICell cell = null;
int startRow = 0;
try
{
using (fs = File.OpenRead(filePath))
{
if (fs == null)
{
throw Oops.Oh("请上传事件文件");
}
long length = fs.Length;
if (length > 1024 * 1024 * 100) //200M
{
throw Oops.Oh("上传文件不能超过100M");
}
fs.Position = 0;
// 2007版本
if (filePath.ToLower().IndexOf(".xlsx") > 0)
workbook = new XSSFWorkbook(fs);
// 2003版本
else if (filePath.ToLower().IndexOf(".xls") > 0)
// workbook = new HSSFWorkbook(fs);
workbook = new XSSFWorkbook(fs);
else
{
throw Oops.Oh("请上传事件文件");
}
if (workbook != null)
{
sheet = workbook.GetSheetAt(0);//读取第一个sheet,当然也可以循环读取每个sheet
dataTable = new System.Data.DataTable();
if (sheet != null)
{
int rowCount = sheet.LastRowNum;//总行数
if (rowCount > 0)
{
IRow firstRow = sheet.GetRow(0);//第一行
int cellCount = firstRow.LastCellNum;//列数
//构建datatable的列
if (isColumnName)
{
startRow = 1;//如果第一行是列名,则从第二行开始读取
for (int i = firstRow.FirstCellNum; i < cellCount; ++i)
{
cell = firstRow.GetCell(i);
if (cell != null)
{
if (cell.StringCellValue != null)
{
column = new DataColumn(cell.StringCellValue);
dataTable.Columns.Add(column);
}
}
}
}
else
{
for (int i = firstRow.FirstCellNum; i < cellCount; ++i)
{
column = new DataColumn("column" + (i + 1));
dataTable.Columns.Add(column);
}
}
//填充行
for (int i = startRow; i <= rowCount; ++i)
{
row = sheet.GetRow(i);
if (row == null) continue;
dataRow = dataTable.NewRow();
for (int j = row.FirstCellNum; j < cellCount; ++j)
{
cell = row.GetCell(j);
if (cell == null)
{
dataRow[j] = "";
}
else
{
//CellType(Unknown = -1,Numeric = 0,String = 1,Formula = 2,Blank = 3,Boolean = 4,Error = 5,)
switch (cell.CellType)
{
case CellType.Blank:
dataRow[j] = "";
break;
case CellType.Numeric:
short format = cell.CellStyle.DataFormat;
//对时间格式(2015.12.5、2015/12/5、2015-12-5等)的处理
if (format == 14 || format == 31 || format == 57 || format == 58)
{
if (DateUtil.IsCellDateFormatted(cell))
{
dataRow[j] = Convert.ToDateTime(cell.DateCellValue).Date.ToString();
}
}
else
{
dataRow[j] = cell.NumericCellValue;
}
break;
case CellType.String:
dataRow[j] = cell.StringCellValue;
break;
}
}
//为创建人赋值
// dataRow[cellCount] = userad;
}
//去除空白行数据
bool rowdataisnull = true;
for (int k = row.FirstCellNum; k < cellCount - 1; ++k)
{
if (!string.IsNullOrEmpty(dataRow[k] as string))
{
rowdataisnull = false;
}
}
if (!rowdataisnull)
{
dataTable.Rows.Add(dataRow);
}
}
}
}
}
}
return dataTable;
}
catch (Exception ex)
{
if (fs != null)
{
fs.Close();
}
throw Oops.Oh("错误:" + ex.Message);
}
}
///
/// 以文件流IFormFile方式导入到DataTable
///
///
///
public static DataTable TaskFileImport(IFormFile file)
{
string[] fileExcels = ".xls,.xlsx".Split(',');
string fileType = "";
if (file == null)
{
throw Oops.Oh("请上传事件文件");
}
var fileExtension = Path.GetExtension(file.FileName);
if (fileExtension == null)
{
throw Oops.Oh("文件无后缀信息");
}
long length = file.Length;
if (length > 1024 * 1024 * 100) //200M
{
throw Oops.Oh("上传文件不能超过100M");
}
if (!fileExcels.Contains(fileExtension))
{
throw Oops.Oh("上传文件只支持.xls,.xlsx");
}
string filePath = ExcelOperation.ProjectPath() + "DownloadExcel\\";
if (!System.IO.Directory.Exists(filePath)) Directory.CreateDirectory(filePath);
var saveName = filePath + $"{DateTime.Now.ToString("yyyyMMddhhmmss")}" + (file.FileName);
using (FileStream fs = File.Create(saveName))
{
file.CopyTo(fs);
}
var datatel = ExcelToDataTable(saveName, true);
return datatel;
}
///
/// 将excel导入到datatable,指定sheetname
///
/// excel路径
/// 第一行是否是列名
/// Excel的sheet名
/// 返回datatable
public static List ExcelToDataTableList(string filePath, bool isColumnName, string[] sheetName)
{
List dataTableList = null;
FileStream fs = null;
DataColumn column = null;
DataRow dataRow = null;
IWorkbook workbook = null;
ISheet sheet = null;
IRow row = null;
ICell cell = null;
int startRow = 0;
try
{
using (fs = File.OpenRead(filePath))
{
// 2007版本
if (filePath.IndexOf(".xlsx") > 0)
workbook = new XSSFWorkbook(fs);
// 2003版本
else if (filePath.IndexOf(".xls") > 0)
workbook = new HSSFWorkbook(fs);
if (workbook != null && sheetName != null && sheetName.Length > 0)
{
dataTableList = new List();
//string[] sheetName = { "工单", "工单材料", "杆件", "杆件工时", "配料单", "配料单详情", "物料主数据", "工艺", "工序", "工艺工序", "检验项" };
for (int w = 0; w < sheetName.Length; w++)
//for (int w = 0; w < workbook.NumberOfSheets; w++)
{
//sheet = workbook.GetSheetAt(w);//循环读取每个sheet(根据下标获取)
sheet = workbook.GetSheet(sheetName[w]);//循环读取每个sheet(根据名称获取)
DataTable dataTable = new DataTable();
if (sheet != null)
{
int rowCount = sheet.LastRowNum;//总行数
if (rowCount > 0)
{
IRow firstRow = sheet.GetRow(0);//第一行
int cellCount = firstRow.LastCellNum;//列数
#region 构建datatable的列
if (isColumnName)
{
startRow = 1;//如果第一行是列名,则从第二行开始读取
for (int i = firstRow.FirstCellNum; i < cellCount; ++i)
{
cell = firstRow.GetCell(i);
if (cell != null)
{
if (cell.StringCellValue != null)
{
column = new DataColumn(cell.StringCellValue);
dataTable.Columns.Add(column);
}
}
}
}
else
{
for (int i = firstRow.FirstCellNum; i < cellCount; ++i)
{
column = new DataColumn("column" + (i + 1));
dataTable.Columns.Add(column);
}
}
#endregion
#region 填充行
for (int i = startRow; i <= rowCount; ++i)
{
row = sheet.GetRow(i);
if (row == null) continue;
bool IsNull = true;//是否是空行
dataRow = dataTable.NewRow();
for (int j = row.FirstCellNum; j < cellCount; ++j)
{
cell = row.GetCell(j);
if (cell == null)
{
dataRow[j] = "";
}
else
{
object value = null;
//CellType(Unknown = -1,Numeric = 0,String = 1,Formula = 2,Blank = 3,Boolean = 4,Error = 5,)
switch (cell.CellType)
{
case CellType.Blank:
value = "";
break;
case CellType.Numeric:
short format = cell.CellStyle.DataFormat;
//对时间格式(2015.12.5、2015/12/5、2015-12-5等)的处理
if (format == 14 || format == 31 || format == 57 || format == 58 || format == 176)
value = cell.DateCellValue;
else
value = Math.Round(cell.NumericCellValue, 2);//2位小数
break;
case CellType.String:
value = cell.StringCellValue;
break;
case CellType.Formula://公式
row.GetCell(j).SetCellType(CellType.String);//先改变公式为字符
value = cell.StringCellValue;
break;
default:
value = cell.StringCellValue;
break;
}
if (!string.IsNullOrWhiteSpace(value.ToString()))
{
IsNull = false;
dataRow[j] = value;
}
}
}
if (!IsNull)
dataTable.Rows.Add(dataRow);
}
#endregion
}
dataTableList.Add(dataTable);
}
}
}
}
return dataTableList;
}
catch (Exception ex)
{
if (fs != null)
{
fs.Close();
}
return null;
}
}
///
/// 格式化关键字集合
///
/// 泛型对象
/// 关键字集对象
///
public static Dictionary getProperties(T t)
{
Dictionary keywords = new Dictionary();
if (t == null)
{
return keywords;
}
System.Reflection.PropertyInfo[] properties = t.GetType().GetProperties(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);
if (properties.Length <= 0)
{
return keywords;
}
foreach (System.Reflection.PropertyInfo item in properties)
{
string name = "{$" + item.Name + "}";
object value = item.GetValue(t, null);
if (item.PropertyType.IsValueType || item.PropertyType.Name.StartsWith("String"))
{
keywords.Add(name, value.ToString());
}
else
{
getProperties(value);
}
}
return keywords;
}
///
/// NPOI使用ShiftRows向excel插入行,并复制原有样式
///
/// 模板文件,包含物理路径
/// 数据集合
/// 开始插入行索引
/// 循环赋值的方法
public static void ShiftRows(string SavePath, List list, int startRow, Func func)//开始插入行索引
{
//创建Excel文件的对象
FileStream fs = new FileStream(SavePath, FileMode.Open, FileAccess.ReadWrite);
XSSFWorkbook workbook = new XSSFWorkbook(fs);
fs.Close();
ISheet sheet = workbook.GetSheetAt(0);
if (list != null && list.Count > 1)
{
//插入行
sheet.ShiftRows(startRow, sheet.LastRowNum, list.Count - 1, true, false);
var rowSource = sheet.GetRow(startRow - 1);
var rowStyle = rowSource.RowStyle;//获取当前行样式
for (int i = startRow; i < startRow + list.Count - 1; i++)
{
var rowInsert = sheet.CreateRow(i);
if (rowStyle != null) rowInsert.RowStyle = rowStyle;
rowInsert.Height = rowSource.Height;
for (int col = 0; col < rowSource.LastCellNum; col++)
{
var cellsource = rowSource.GetCell(col);
var cellInsert = rowInsert.CreateCell(col);
var cellStyle = cellsource.CellStyle;
//设置单元格样式
if (cellStyle != null)
cellInsert.CellStyle = cellsource.CellStyle;
}
}
}
//绑定数据
for (int j = startRow; j < startRow + list.Count; j++)
{
//单元格赋值等其他代码
IRow r = sheet.GetRow(j);
bool ls = func(r, j);
// 标准写法 r.Cells[0].SetCellValue(j + 1);
}
FileStream success = new FileStream(SavePath, FileMode.Create);
workbook.Write(success);
success.Close();
workbook.Close();
}
///
/// 数据替换
///
/// 实体 替换默认为 {Name}
///
///
///
///
public static string ExcelReplace(T entity, string FromSourcePath, string ToSourcePath)
{
FileStream fs = new FileStream(FromSourcePath, FileMode.Open, FileAccess.Read);
IWorkbook workbook = WorkbookFactory.Create(fs);
ISheet sheet = workbook.GetSheetAt(0);
IRow firstRow = sheet.GetRow(0);
int cellCount = firstRow.LastCellNum;
int rowCount = sheet.LastRowNum;
for (int i = 0; i < rowCount; i++)
{
IRow row = sheet.GetRow(i);
for (int j = 0; j < cellCount; j++)
{
NPOI.SS.UserModel.ICell cell = row.GetCell(j);
ReplaceExcelKey(entity, cell);
}
}
byte[] buffer = new byte[1024 * 5];
if (File.Exists(ToSourcePath)) File.Delete(ToSourcePath);
var file = new FileStream(ToSourcePath, FileMode.Create);
workbook.Write(file);
file.Close();
return ToSourcePath;
}
private static void ReplaceExcelKey(T etity, NPOI.SS.UserModel.ICell cell)
{
Type entityType = typeof(T);
PropertyInfo[] properties = entityType.GetProperties();
if (cell != null)
{
var text = "";
if (cell.CellType == CellType.String)//这⾥根据不同的类型进⾏不同的处理
{
text = cell.ToString();
}
if (text != "")
{
foreach (var p in properties)
{
string propteryName = "{" + p.Name + "}";
object value = p.GetValue(etity);
if (value == null)
{
value = "";
}
if (text.Contains(propteryName))
{
var v = value.ToString();
text = text.Replace(propteryName, v);
}
cell.SetCellValue(text);
}
}
}
}
/////
///// excel转image
/////
/////
/////
//public static string ChangeExcel2Image(string filename, string imagepath)
//{
// string filePath = ExcelOperation.ProjectPath() + "DownloadExcel\\";
// if (!System.IO.Directory.Exists(filePath)) Directory.CreateDirectory(filePath);
// var saveName = filePath + $"{DateTime.Now.ToString("yyyyMMddhhmmss")}" + imagepath;
// Workbook workbook = new Workbook();
// workbook.LoadFromFile(filename);
// Worksheet sheet = workbook.Worksheets[0];
// //sheet.SaveToImage(imagepath); //图片后缀.bmp ,imagepath自己设置
// // //加载生成图表后的Excel文档
// //workbook.LoadFromFile("ColumnChart.xlsx");
// sheet.ToImage(0, 0, 0, 0).Save(saveName, ImageFormat.Jpeg);
// return saveName;
//}
public static string ExcelRepleImages(string TagetPath, string imgpath)
{
string fileExtensionName = Path.GetExtension(TagetPath);
if (fileExtensionName.ToLower() == ".xlsx")
{
return InsertImageToXLSXExcel(TagetPath, imgpath);
}
if (fileExtensionName.ToLower() == ".xls")
{
return InsertImageToXLSExcel(TagetPath, imgpath);
}
return "";
}
///
/// .xlsx后缀的Excel文件添加图片
///
///
///
private static string InsertImageToXLSXExcel(string excelPath, string imgPath)
{
try
{
using (FileStream fs = new FileStream(excelPath, FileMode.Open))//获取指定Excel文件流
{
//创建工作簿
XSSFWorkbook xssfworkbook = new XSSFWorkbook(fs);
//获取第一个工作表(下标从0起)
XSSFSheet sheet = (XSSFSheet)xssfworkbook.GetSheet(xssfworkbook.GetSheetName(0));
//获取指定图片的字节流
byte[] bytes = System.IO.File.ReadAllBytes(imgPath);
//将图片添加到工作簿中,返回值为该图片在工作表中的索引(从0开始)
//图片所在工作簿索引理解:如果原Excel中没有图片,那执行下面的语句后,该图片为Excel中的第1张图片,其索引为0;
//同理,如果原Excel中已经有1张图片,执行下面的语句后,该图片为Excel中的第2张图片,其索引为1;
int pictureIdx = xssfworkbook.AddPicture(bytes, PictureType.PNG);
//创建画布
XSSFDrawing patriarch = (XSSFDrawing)sheet.CreateDrawingPatriarch();
//设置图片坐标与大小
//函数原型:XSSFClientAnchor(int dx1, int dy1, int dx2, int dy2, int col1, int row1, int col2, int row2);
//坐标(col1,row1)表示图片左上角所在单元格的位置,均从0开始,比如(5,2)表示(第六列,第三行),即F3;注意:图片左上角坐标与(col1,row1)单元格左上角坐标重合
//坐标(col2,row2)表示图片右下角所在单元格的位置,均从0开始,比如(10,3)表示(第十一列,第四行),即K4;注意:图片右下角坐标与(col2,row2)单元格左上角坐标重合
//坐标(dx1,dy1)表示图片左上角在单元格(col1,row1)基础上的偏移量(往右下方偏移);(dx1,dy1)的最大值为(1023, 255),为一个单元格的大小
//坐标(dx2,dy2)表示图片右下角在单元格(col2,row2)基础上的偏移量(往右下方偏移);(dx2,dy2)的最大值为(1023, 255),为一个单元格的大小
//注意:目前测试发现,对于.xlsx后缀的Excel文件,偏移量设置(dx1,dy1)(dx2,dy2)无效;只会对.xls生效
XSSFClientAnchor anchor = new XSSFClientAnchor(0, 0, 20, 15, 0, 2, 2, 6);
//正式在指定位置插入图片
XSSFPicture pict = (XSSFPicture)patriarch.CreatePicture(anchor, pictureIdx);
//创建一个新的Excel文件流,可以和原文件名不一样,
//如果不一样,则会创建一个新的Excel文件;如果一样,则会覆盖原文件
FileStream file = new FileStream("E:/图片3333333333.xlsx", FileMode.Create);
//将已插入图片的Excel流写入新创建的Excel中
xssfworkbook.Write(file);
file.Close();
//关闭工作簿
xssfworkbook.Close();
}
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
return excelPath;
}
///
/// .xls后缀的Excel文件添加图片
///
///
///
private static string InsertImageToXLSExcel(string TagetPath, string imgpath)
{
FileStream file = new FileStream(TagetPath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite);
IWorkbook hssfworkbook = new HSSFWorkbook(file);
HSSFSheet sheet1 = (HSSFSheet)hssfworkbook.GetSheet("领料单");
System.Drawing.Image image = System.Drawing.Image.FromFile(imgpath);
MemoryStream ms = new MemoryStream();
image.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
HSSFPatriarch patriarch = (HSSFPatriarch)sheet1.CreateDrawingPatriarch();
//设置图片坐标与大小
//函数原型:XSSFClientAnchor(int dx1, int dy1, int dx2, int dy2, int col1, int row1, int col2, int row2);
//坐标(col1,row1)表示图片左上角所在单元格的位置,均从0开始,比如(5,2)表示(第六列,第三行),即F3;注意:图片左上角坐标与(col1,row1)单元格左上角坐标重合
//坐标(col2,row2)表示图片右下角所在单元格的位置,均从0开始,比如(10,3)表示(第十一列,第四行),即K4;注意:图片右下角坐标与(col2,row2)单元格左上角坐标重合
//坐标(dx1,dy1)表示图片左上角在单元格(col1,row1)基础上的偏移量(往右下方偏移);(dx1,dy1)的最大值为(1023, 255),为一个单元格的大小
//坐标(dx2,dy2)表示图片右下角在单元格(col2,row2)基础上的偏移量(往右下方偏移);(dx2,dy2)的最大值为(1023, 255),为一个单元格的大小
//注意:目前测试发现,对于.xlsx后缀的Excel文件,偏移量设置(dx1,dy1)(dx2,dy2)无效;只会对.xls生效
HSSFClientAnchor anchor = new HSSFClientAnchor(0, 0, 20, 15, 0, 2, 2, 6);
anchor.AnchorType = AnchorType.MoveDontResize;
int index = hssfworkbook.AddPicture(ms.ToArray(), PictureType.PNG);
HSSFPicture pict = (HSSFPicture)patriarch.CreatePicture(anchor, index);
int idex1 = hssfworkbook.GetSheetIndex("领料单");
hssfworkbook.SetSheetName(idex1, "领料单");
FileStream fs2 = new FileStream("E:/图片操2222222作.xls", FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite);
hssfworkbook.Write(fs2);
fs2.Close();
image.Dispose();
file.Close();
return TagetPath;
}
}