You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

837 lines
31 KiB

using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using OfficeOpenXml;
using OfficeOpenXml.Style;
namespace CK.SCP.Utils
{
public class ExcelHelper
{
// Methods
/// <summary>
/// excle 2003
/// </summary>
/// <param name="stream"></param>
/// <returns></returns>
public static DataTable GetDataTable(Stream stream)
{
IWorkbook workbook;
try
{
workbook = new HSSFWorkbook(stream);
}
catch (Exception exception)
{
try
{
workbook = new XSSFWorkbook(stream);
}
catch(Exception e)
{
throw e;
}
}
ISheet sheetAt = workbook.GetSheetAt(0);
IEnumerator rowEnumerator = sheetAt.GetRowEnumerator();
DataTable table = new DataTable();
IRow row = sheetAt.GetRow(0);
if (row != null)
{
for (int j = 0; j < row.LastCellNum; j++)
{
ICell cell = row.GetCell(j);
if (cell == null)
{
table.Columns.Add("cell" + j.ToString());
}
else
{
table.Columns.Add(cell.ToString());
}
}
}
int count = table.Columns.Count;
for (int i = 0; rowEnumerator.MoveNext(); i++)
{
if (i > 0)
{
IRow current = (HSSFRow)rowEnumerator.Current;
DataRow row3 = table.NewRow();
for (int k = 0; k < count; k++)
{
ICell cell2 = current.GetCell(k);
if (cell2 == null)
{
row3[k] = null;
}
else
{
row3[k] = cell2.ToString();
}
}
table.Rows.Add(row3);
}
}
return table;
}
/// <summary>
/// excle 2007
/// </summary>
/// <param name="stream"></param>
/// <returns></returns>
public static DataTable GetDataTableOfXlsx(Stream stream)
{
IWorkbook workbook;
try
{
workbook = new XSSFWorkbook(stream);
}
catch (Exception exception)
{
try
{
workbook = new XSSFWorkbook(stream);
}
catch (Exception e)
{
throw e;
}
}
ISheet sheetAt = workbook.GetSheetAt(0);
IEnumerator rowEnumerator = sheetAt.GetRowEnumerator();
DataTable table = new DataTable();
IRow row = sheetAt.GetRow(0);
if (row != null)
{
for (int j = 0; j < row.LastCellNum; j++)
{
ICell cell = row.GetCell(j);
if (cell == null)
{
table.Columns.Add("cell" + j.ToString());
}
else
{
table.Columns.Add(cell.ToString());
}
}
}
int count = table.Columns.Count;
for (int i = 0; rowEnumerator.MoveNext(); i++)
{
if (i > 0)
{
IRow current = (XSSFRow)rowEnumerator.Current;
DataRow row3 = table.NewRow();
for (int k = 0; k < count; k++)
{
ICell cell2 = current.GetCell(k);
if (cell2 == null)
{
row3[k] = null;
}
else
{
row3[k] = cell2.ToString();
}
}
table.Rows.Add(row3);
}
}
return table;
}
/// <summary>
/// 删除空行
/// </summary>
/// <param name="dt"></param>
/// <returns></returns>
public static DataTable RemoveEmpty(DataTable dt)
{
List<DataRow> removelist = new List<DataRow>();
for (int i = 0; i < dt.Rows.Count; i++)
{
bool IsNull = true;
for (int j = 0; j < dt.Columns.Count; j++)
{
if (!string.IsNullOrEmpty(dt.Rows[i][j].ToString().Trim()))
{
IsNull = false;
}
}
if (IsNull)
{
removelist.Add(dt.Rows[i]);
}
}
for (int i = 0; i < removelist.Count; i++)
{
dt.Rows.Remove(removelist[i]);
}
return dt;
}
public static DataTable GetDataTable(string filePath)
{
HSSFWorkbook workbook;
try
{
using (FileStream stream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
workbook = new HSSFWorkbook(stream);
}
}
catch (Exception exception)
{
throw exception;
}
ISheet sheetAt = workbook.GetSheetAt(0);
IEnumerator rowEnumerator = sheetAt.GetRowEnumerator();
DataTable table = new DataTable();
IRow row = sheetAt.GetRow(0);
if (row != null)
{
for (int j = 0; j < row.LastCellNum; j++)
{
ICell cell = row.GetCell(j);
if (cell == null)
{
table.Columns.Add("cell" + j.ToString());
}
else
{
table.Columns.Add(cell.ToString());
}
}
}
int count = table.Columns.Count;
for (int i = 0; rowEnumerator.MoveNext(); i++)
{
if (i > 0)
{
IRow current = (HSSFRow)rowEnumerator.Current;
DataRow row3 = table.NewRow();
for (int k = 0; k < count; k++)
{
ICell cell2 = current.GetCell(k);
if (cell2 == null)
{
row3[k] = null;
}
else
{
row3[k] = cell2.ToString();
}
}
table.Rows.Add(row3);
}
}
return table;
}
/// <summary>
/// 导入数据到excel文件
/// </summary>
/// <param name="data">待导入的数据</param>
/// <param name="fileName">文件路径</param>
/// <param name="sheetName">excel表名</param>
/// <param name="hiddenColmnIndexs">隐藏列索引</param>
/// <param name="header">列头字典;原始列头=>重命名列名</param>
/// <param name="redHeaderClomnIndexs">标记红色加粗的列索引</param>
/// <param name="comments">列头批注字典;列名=>批注内容</param>
/// <returns></returns>
public static string SetDataTableToExcel(DataTable data, string fileName, string sheetName, int[] hiddenColmnIndexs = null, Dictionary<string, string> header = null, int[] redHeaderClomnIndexs = null, Dictionary<string, string> comments = null)
{
int num4 = 0;
int num = 0;
int column = 0;
int rownum = 0;
ISheet sheet = null;
IWorkbook workbook = new HSSFWorkbook();
//todo:tans
var stream = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.ReadWrite);
try
{
sheet = workbook.CreateSheet(sheetName);
IRow row = sheet.CreateRow(0);
column = 0;
int maxCount = Math.Max(header != null ? header.Count : 0, data.Columns.Count);
IDrawing patr1 = sheet.CreateDrawingPatriarch();// as HSSFPatriarch;
//创建列头
while (column < data.Columns.Count)
{
var col = data.Columns[column];
var colName = col.ColumnName;
ICell cell = row.GetCell(column);
if (header != null && header.ContainsKey(colName))
{
string temp = header[colName];//列重命名
header.Remove(colName);
cell = row.CreateCell(column);
cell.SetCellValue(temp);
}
//创建批注
colName = cell.StringCellValue;
if (comments != null && comments.ContainsKey(colName))
{
var commentStr = comments[colName];
IComment comment1 = patr1.CreateCellComment(new HSSFClientAnchor(0, 0, 0, 0, 1, 3, 3, 7));// as HSSFComment;
comment1.String = new HSSFRichTextString(commentStr);
cell.CellComment = comment1;
}
column++;
}
//附加列头
int colCount = data.Columns.Count;
foreach (var colName in header.Keys)
{
row.CreateCell(colCount).SetCellValue(header[colName]);
colCount++;
}
//设置列头样式
redHeaderClomnIndexs = redHeaderClomnIndexs ?? new int[] { };
for (int i = 0, l = 0, rl = redHeaderClomnIndexs.Length; i < row.Cells.Count; i++, l++)
{
var cell = row.GetCell(i);
if (cell == null)
{
continue;
}
//设置字体
IFont font = workbook.CreateFont();
font.Boldweight = (short)FontBoldWeight.Bold;
if (l < rl)
{
int index = redHeaderClomnIndexs[l];
cell = row.GetCell(index);
font.Color = (short)FontColor.Red;
}
//设置样式
ICellStyle style = workbook.CreateCellStyle();
style.Alignment = HorizontalAlignment.Center;
style.SetFont(font);
cell.CellStyle = style;
}
//创建数据列,并填充数据
rownum = 1;
for (num = 0; num < data.Rows.Count; num++)
{
IRow row2 = sheet.CreateRow(rownum);
for (column = 0; column < data.Columns.Count; column++)
{
row2.CreateCell(column).SetCellValue(data.Rows[num][column].ToString());
}
rownum++;
}
//设置隐藏列
if (hiddenColmnIndexs != null && hiddenColmnIndexs.Length <= column)
{
for (int i = 0, l = hiddenColmnIndexs.Length; i < l; i++)
{
sheet.SetColumnHidden(hiddenColmnIndexs[i], true);
}
}
//当创建完毕所有cell,设置居中才有效
for (int i = 0; i < row.Cells.Count; i++)
{
sheet.AutoSizeColumn(i);
}
workbook.Write(stream);
}
catch (Exception ex)
{
return null;
}
finally
{
stream.Close();
}
return fileName;
}
}
public class EpPlusHelper
{
private DataSet _dsExcel;
private DataTable _dtExcel;
private string _excelFileName;
private List<string> _readSheetNames;
private string _pasword = string.Empty;
public event Action<string,string> ExportExcelCompleted = null;
public EpPlusHelper()
{
}
#region Read
public DataTable ReadExcelToDt(string fileName, string password = "")
{
_excelFileName = fileName;
_pasword = password;
var excelFileExt = GetFileExt(fileName);
switch (excelFileExt)
{
case ".XLSX":
var poDv = new ProcessOperator { BackgroundWork = ReadExcelToDataTable };
poDv.BackgroundWorkerCompleted += ReadExcel_Completed;
poDv.Start();
break;
case ".XLS":
throw new Exception($"需要使用NPOI解析后缀名为{excelFileExt}的文件!");
default:
throw new Exception($"无法解析后缀名为{excelFileExt}的文件!");
}
return _dtExcel;
}
private DataTable ReadData(ExcelWorksheet sheet)
{
var dt = new DataTable(sheet.Name);
int colStart = sheet.Dimension.Start.Column;
int colEnd = sheet.Dimension.End.Column;
int rowStart = sheet.Dimension.Start.Row;
int rowEnd = sheet.Dimension.End.Row;
for (var i = colStart; i < colEnd + 1; i++)//从1开始计数
{
var columnName = sheet.Cells[rowStart, i].Value.ToString();
dt.Columns.Add(columnName);
}
for (var row = rowStart + 1; row < rowEnd + 1; row++)//从1开始计数,跳过第一行
{
var dr = dt.NewRow();
for (var col = colStart; col < colEnd + 1; col++)//从1开始计数
{
dr[col - 1] = sheet.Cells[row, col]?.Value?.ToString();
}
dt.Rows.Add(dr);
}
RemoveEmptyRow(dt);
return dt;
}
private void ReadExcelToDataTable()
{
_readSheetNames = new List<string>();
_dsExcel = new DataSet();
var fs = new FileStream(_excelFileName, FileMode.Open);
try
{
using (
var package = string.IsNullOrEmpty(_pasword)
? new ExcelPackage(fs)
: new ExcelPackage(fs, _pasword)
)
{
var validSheetList = GetValidSheetList(package);
if (validSheetList.Count == 0) throw new Exception("未找到有效的Excel表单");
var sheet = validSheetList[0];
_readSheetNames.Add(sheet.Name);
_dtExcel = ReadData(sheet);
}
}
finally
{
fs.Close();
fs.Dispose();
}
}
private void ReadExcel_Completed(object sender, BackgroundWorkerEventArgs e)
{
if (e.BackGroundException == null)
{
if (_readSheetNames == null || _readSheetNames.Count == 0)
{
throw new Exception("文件读失败,未找到符合的系统要求的工作表!");
}
}
else
{
throw new Exception("文件读取失败,请联系管理员!");
}
}
private List<ExcelWorksheet> GetValidSheetList(ExcelPackage package)
{
var list = new List<ExcelWorksheet>();
for (var i = 1; i <= package.Workbook.Worksheets.Count; i++)
{
var sheet = package.Workbook.Worksheets[i];
var tableName = sheet.Name;
if (!tableName.Equals("_xlnm#_FilterDatabase") &&
tableName.IndexOf("_", StringComparison.Ordinal) != tableName.Length - 1 &&
tableName.IndexOf("FilterDatabase", StringComparison.Ordinal) == -1)
{
list.Add(sheet);
}
}
return list;
}
private void GetFileName(string fileName)
{
_excelFileName = fileName;
}
private string GetFileExt(string fileName)
{
return Path.GetExtension(fileName)?.ToUpper();
}
#endregion
#region Write
public void WriteDsToExcel(string p_sheetName, DataSet ds, string title ,string password = "")
{
string fileName = p_sheetName + "-" + DateTime.Now.ToString("yyyyMMddHHmmssfff") + ".xls"; // 文件名称
string urlPath = "/exportfiles/" + fileName; // 文件下载的URL地址,供给前台下载
string filePath = HttpContext.Current.Server.MapPath("\\" + urlPath); // 文件路径
// 1.检测是否存在文件夹,若不存在就建立个文件夹
string directoryName = Path.GetDirectoryName(filePath);
if (!Directory.Exists(directoryName))
{
Directory.CreateDirectory(directoryName);
}
WriteDataSetToExcel(ds, filePath, password,title);
if (ExportExcelCompleted != null)
{
ExportExcelCompleted(filePath,fileName);
}
}
private void WriteDataSetToExcel(DataSet ds, string excelFileName, string password ,string title)
{
var newFile = GetNewFile(excelFileName);
_excelFileName = excelFileName;
using (var package = string.IsNullOrEmpty(password) ? new ExcelPackage(newFile) : new ExcelPackage(newFile, password))
{
foreach (DataTable dt in ds.Tables)
{
if (string.IsNullOrEmpty(dt?.TableName) || dt.Rows.Count == 0) continue;
EpPlusHelper.RemoveEmptyRow(dt);
var sheetName = "sheet1";
if (!string.IsNullOrEmpty(dt.TableName))
sheetName = dt.TableName;
var worksheet = package.Workbook.Worksheets.Add(sheetName);
if (string.IsNullOrWhiteSpace(title))
{
//表头
SetTitle(dt, worksheet);
//各行数据
SetData(dt, worksheet);
//设置单元格格式
SetFormat(worksheet);
}
else
{
//表头
SetTitle_h(dt, worksheet);
//各行数据
SetData_h(dt, worksheet);
//设置单元格格式
SetFormat_h(worksheet,title);
}
}
if (package.Workbook.Worksheets.Count <= 0) return;
if (string.IsNullOrEmpty(password))
package.Save();
else
package.Save(password);
}
}
private static FileInfo GetNewFile(string excelFileName)
{
var newFile = new FileInfo(excelFileName);
if (newFile.Exists)
{
newFile.Delete(); // ensures we create a new workbook
newFile = new FileInfo(excelFileName);
}
return newFile;
}
//public void WriteDtToExcel(DataTable dt, string password = "")
//{
// WriteDtToExcel(dt, fileName, password);
//}
//public void WriteDtToExcel(DataTable dt, string excelFileName, string password)
//{
// var excelFileExt = GetFileExt(excelFileName);
// switch (excelFileExt)
// {
// case ".XLSX":
// if (dt == null || dt.Rows.Count <= 0) throw new Exception("当前表单没有任何数据");
// var poDv = new ProcessOperator { BackgroundWork = () => WriteDataTableToExcel(dt, excelFileName, password) };
// poDv.BackgroundWorkerCompleted += WriteExcel_Completed;
// poDv.Start();
// break;
// case ".XLS":
// throw new Exception($"需要使用NPOI解析后缀名为{excelFileExt}的文件!");
// default:
// throw new Exception($"无法解析后缀名为{excelFileExt}的文件!");
// }
//}
private void WriteDataTableToExcel(DataTable dt, string excelFileName, string password)
{
var newFile = GetNewFile(excelFileName);
_excelFileName = excelFileName;
using (var package = string.IsNullOrEmpty(password) ? new ExcelPackage(newFile) : new ExcelPackage(newFile, password))
{
var sheetName = "sheet1";
if (!string.IsNullOrEmpty(dt.TableName))
sheetName = dt.TableName;
using (var worksheet = package.Workbook.Worksheets.Add(sheetName))
{
//表头
SetTitle(dt, worksheet);
//各行数据
SetData(dt, worksheet);
//设置单元格格式
SetFormat(worksheet);
if (string.IsNullOrEmpty(password))
package.Save();
else
package.Save(password);
}
}
}
//private void WriteExcel_Completed(object sender, BackgroundWorkerEventArgs e)
//{
// var newFile = new FileInfo(_excelFileName);
// if (newFile.Exists)
// Process.Start(_excelFileName);
//}
private static void SetFormat(ExcelWorksheet worksheet)
{
if (worksheet.Dimension == null) return;
int colStart = worksheet.Dimension.Start.Column;
int colEnd = worksheet.Dimension.End.Column;
int rowStart = worksheet.Dimension.Start.Row;
int rowEnd = worksheet.Dimension.End.Row;
// using (var range = worksheet.Cells[1, 1, 1, dt.Columns.Count])
using (var range = worksheet.Cells[rowStart, colStart, rowStart, colEnd])
{
range.Style.Fill.PatternType = ExcelFillStyle.LightGrid;
range.Style.Fill.BackgroundColor.SetColor(Color.LightYellow);
range.Style.HorizontalAlignment = ExcelHorizontalAlignment.CenterContinuous;
}
// using (var range = worksheet.Cells[1, 1, dt.Rows.Count + 1, dt.Columns.Count])
using (var range = worksheet.Cells[rowStart, colStart, rowEnd, colEnd])
{
range.Style.Border.BorderAround(ExcelBorderStyle.Thin);
range.Style.Font.Name = "微软雅黑";
range.Style.Font.Size = 12;
range.AutoFitColumns();
}
}
/// <summary>
/// 设置单元格(带标题)
/// </summary>
/// <param name="worksheet"></param>
private static void SetFormat_h(ExcelWorksheet worksheet,string title)
{
if (worksheet.Dimension == null) return;
int colStart = worksheet.Dimension.Start.Column;
int colEnd = worksheet.Dimension.End.Column;
int rowStart = worksheet.Dimension.Start.Row;
int rowEnd = worksheet.Dimension.End.Row;
using (var range = worksheet.Cells[1, 1, 1, worksheet.Dimension.End.Column])
{
range.Merge = true;
range.Style.HorizontalAlignment = ExcelHorizontalAlignment.CenterContinuous;
range.Value = title;
range.Style.Font.Size = 24;
}
// using (var range = worksheet.Cells[1, 1, 1, dt.Columns.Count])
using (var range = worksheet.Cells[rowStart, colStart, rowStart, colEnd])
{
range.Style.Fill.PatternType = ExcelFillStyle.LightGrid;
range.Style.Fill.BackgroundColor.SetColor(Color.LightYellow);
range.Style.HorizontalAlignment = ExcelHorizontalAlignment.CenterContinuous;
}
// using (var range = worksheet.Cells[1, 1, dt.Rows.Count + 1, dt.Columns.Count])
using (var range = worksheet.Cells[rowStart, colStart, rowEnd, colEnd])
{
range.Style.Border.BorderAround(ExcelBorderStyle.Thin);
range.Style.Font.Name = "微软雅黑";
range.Style.Font.Size = 12;
range.AutoFitColumns();
}
}
private static void SetData(DataTable dt, ExcelWorksheet worksheet)
{
for (int i = 0; i < dt.Rows.Count; i++)
{
var row = i + 2;
for (int j = 0; j < dt.Columns.Count; j++)
{
var col = j + 1;
var s = dt.Rows[i][j];
//////////////////
//格式化日期字段
var dc = dt.Columns[j];
if (dc.DataType.FullName == "System.DateTime")
{
DateTime time;
DateTime.TryParse(s.ToString(), out time);
s = time.ToString("yyyy-MM-dd HH:mm:ss");
}
//使用EPPLUS貌似不需要做这个转换了?
// if (dc.DataType.FullName == "System.String")
// {
// s = "'" + s;
// }
decimal d;
if (decimal.TryParse(s.ToString(), out d))
{
if (Math.Round(d, 5) == 0)
{
s = 0;
}
}
worksheet.Cells[row, col].Value = s;
}
}
}
/// <summary>
/// 设置各行数据(带标题)
/// </summary>
/// <param name="dt"></param>
/// <param name="worksheet"></param>
private static void SetData_h(DataTable dt, ExcelWorksheet worksheet)
{
for (int i = 0; i < dt.Rows.Count; i++)
{
var row = i + 3;
for (int j = 0; j < dt.Columns.Count; j++)
{
var col = j + 1;
var s = dt.Rows[i][j];
//////////////////
//格式化日期字段
var dc = dt.Columns[j];
if (dc.DataType.FullName == "System.DateTime")
{
DateTime time;
DateTime.TryParse(s.ToString(), out time);
s = time.ToString("yyyy-MM-dd HH:mm:ss");
}
//使用EPPLUS貌似不需要做这个转换了?
// if (dc.DataType.FullName == "System.String")
// {
// s = "'" + s;
// }
decimal d;
if (decimal.TryParse(s.ToString(), out d))
{
if (Math.Round(d, 5) == 0)
{
s = 0;
}
}
worksheet.Cells[row, col].Value = s;
}
}
}
private static void SetTitle(DataTable dt, ExcelWorksheet worksheet)
{
int row = 1;
for (int i = 0; i < dt.Columns.Count; i++)
{
var dc = dt.Columns[i];
row = 1;
var col = i + 1;
worksheet.Cells[row, col].Value = dc.ColumnName;
}
worksheet.View.FreezePanes(row + 1, 1); //冻结表头
}
/// <summary>
/// 设置表头(带标题)
/// </summary>
/// <param name="dt"></param>
/// <param name="worksheet"></param>
private static void SetTitle_h(DataTable dt, ExcelWorksheet worksheet)
{
int row = 2;
for (int i = 0; i < dt.Columns.Count; i++)
{
var dc = dt.Columns[i];
row = 2;
var col = i + 1;
worksheet.Cells[row, col].Value = dc.ColumnName;
}
worksheet.View.FreezePanes(row + 1, 1); //冻结表头
}
#endregion
public static void RemoveEmptyRow(DataTable dt)
{
if (dt == null || dt.Rows.Count == 0)
return;
var isEmpty = true;
for (var idx = dt.Rows.Count - 1; idx >= 0; idx--)
{
var dr = dt.Rows[idx];
for (var i = 0; i < dt.Columns.Count; i++)
{
if (dr[i].ToString().Trim() != string.Empty)
{
isEmpty = false;
}
}
if (isEmpty)
dt.Rows.Remove(dr);
}
}
}
}