/******************************************************************
**-----------------------------------------------------------------
** Copyright (c) 2014
** Name:
** Version: 1.0
** Author: ming
* npoi: version 2.4.1.0
** Last Edit Time: 2019-11-07
** Remarks: Excel导入导出类
**-----------------------------------------------------------------
******************************************************************/
using NPOI.HPSF;
using NPOI.HSSF.UserModel;
using NPOI.HSSF.Util;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Reflection;
namespace Cmlabs
{
public class ExcelNPOIHelper
{
int perSheetCount = 50000;//每个sheet要保存的条数
public ExcelNPOIHelper()
{ }
/// <summary>
/// 最大接收5万条每页,大于5万时,使用系统默认的值(4万)
/// </summary>
/// <param name="perSheetCounts"></param>
public ExcelNPOIHelper(int perSheetCounts)
{
if (perSheetCount <= 50000)
perSheetCount = perSheetCounts;
}
private IFont GetFont(IWorkbook workbook, HSSFColor color)
{
IFont font = workbook.CreateFont();
font.Color = color.Indexed;
font.FontHeightInPoints = 10;
font.Boldweight = 700;
font.FontName = "宋体";
font.IsItalic = false;
return font;
}
private void SetCellValues(ICell cell, string cellType, string cellValue)
{
switch (cellType)
{
case "System.String": //字符串类型
cell.SetCellValue(cellValue);
break;
case "System.DateTime": //日期类型
DateTime dateV;
DateTime.TryParse(cellValue, out dateV);
cell.SetCellValue(cellValue);
break;
case "System.Boolean": //布尔型
bool boolV = false;
bool.TryParse(cellValue, out boolV);
cell.SetCellValue(boolV);
break;
case "System.Int16": //整型
case "System.Int32":
case "System.Int64":
case "System.Byte":
int intV = 0;
int.TryParse(cellValue, out intV);
cell.SetCellValue(intV);
break;
case "System.Decimal": //浮点型
case "System.Double":
double doubV = 0;
double.TryParse(cellValue, out doubV);
cell.SetCellValue(doubV);
break;
case "System.DBNull": //空值处理
cell.SetCellValue("");
break;
default:
cell.SetCellValue("");
break;
}
}
private void SetProperty(HSSFWorkbook workbook)
{
DocumentSummaryInformation dsi = PropertySetFactory.CreateDocumentSummaryInformation();
dsi.Company = "";
workbook.DocumentSummaryInformation = dsi;
SummaryInformation si = PropertySetFactory.CreateSummaryInformation();
si.Author = "ming"; //填加xls文件作者信息
si.ApplicationName = "ApplicationName"; //填加xls文件创建程序信息
si.LastAuthor = "ming"; //填加xls文件最后保存者信息
si.Comments = "ming"; //填加xls文件作者信息
si.Title = "Excle"; //填加xls文件标题信息
si.Subject = "Excle导出文件";//填加文件主题信息
si.CreateDateTime = DateTime.Now;
workbook.SummaryInformation = si;
}
private ICellStyle GetXlsStyle(HSSFWorkbook workbook)
{
//表头样式
ICellStyle style = workbook.CreateCellStyle();
style.Alignment = HorizontalAlignment.Center;
HSSFColor.Green green = new HSSFColor.Green();
style.SetFont(GetFont(workbook, green));
return style;
/*
//内容样式
style = workbook.CreateCellStyle();
style.Alignment = HorizontalAlignment.Center;
HSSFColor.Blue blue = new HSSFColor.Blue();
style.SetFont(GetFont(workbook, blue));
*/
}
private ICellStyle GetXlsxStyle(XSSFWorkbook workbook)
{
//表头样式
ICellStyle style = workbook.CreateCellStyle();
style.Alignment = HorizontalAlignment.Center;
HSSFColor.Green green = new HSSFColor.Green();
style.SetFont(GetFont(workbook, green));
return style;
}
/// <summary>
/// 从IDataReader导出到excle(xls)文件
/// </summary>
/// <param name="excelFileName"></param>
/// <param name="dtIn"></param>
private void ExportToXlsFromReader(string excelFileName, IDataReader reader, bool isMultiSheet = true)
{
int sheetCount = 1;//当前的sheet数量
int currentSheetCount = 0;//循环时当前保存的条数,每页都会清零
HSSFWorkbook workbook = new HSSFWorkbook();
SetProperty(workbook);
ISheet sheet = workbook.CreateSheet("Sheet" + sheetCount.ToString());
//填充表头
ICell cell = null;
IRow rowHeader = sheet.CreateRow(0);
ICellStyle style = GetXlsStyle(workbook);
for (int i = 0; i < reader.FieldCount; i++)
{
cell = rowHeader.CreateCell(i);
cell.SetCellValue(reader.GetName(i));
cell.CellStyle = style;
}
//填充内容
IRow row = null;
while (reader.Read())
{
if (isMultiSheet)
{
if (currentSheetCount >= perSheetCount)
{
sheetCount++;
currentSheetCount = 0;
sheet = workbook.CreateSheet("Sheet" + sheetCount.ToString());
row = sheet.CreateRow(currentSheetCount);
for (int j = 0; j < rowHeader.Cells.Count; j++)
{
cell = row.CreateCell(j);
cell.SetCellValue(rowHeader.Cells[j].StringCellValue);
cell.CellStyle = style;
}
}
}
currentSheetCount++;
try
{
row = sheet.CreateRow(currentSheetCount);
for (int j = 0; j < reader.FieldCount; j++)
{
cell = row.CreateCell(j);
cell.CellStyle = style;
SetCellValues(cell, reader[j].GetType().ToString(), reader[j].ToString());
}
}
catch (ArgumentException ep)
{
if (ep.Source == "NPOI" && ep.Message.Contains("Invalid row number"))
{
throw new Exception("65535");
}
}
catch
{ }
}
FileStream fs = new FileStream(excelFileName, FileMode.CreateNew, FileAccess.Write);
workbook.Write(fs);
fs.Close();
}
/// <summary>
/// 从IDataReader导出到excle(xlsx)文件
/// </summary>
/// <param name="excelFileName"></param>
/// <param name="dtIn"></param>
private void ExportToXlsxFromReader(string excelFileName, IDataReader reader, bool isMultiSheet = true)
{
int sheetCount = 1;//当前的sheet数量
int currentSheetCount = 0;//循环时当前保存的条数,每页都会清零
XSSFWorkbook workbookx = new XSSFWorkbook();
ISheet sheet = workbookx.CreateSheet("Sheet" + sheetCount.ToString());
//填充表头
ICell cell = null;
IRow rowHeader = sheet.CreateRow(0);
ICellStyle style = GetXlsxStyle(workbookx);
for (int i = 0; i < reader.FieldCount; i++)
{
cell = rowHeader.CreateCell(i);
cell.SetCellValue(reader.GetName(i));
cell.CellStyle = style;
}
//填充内容
IRow row = null;
while (reader.Read())
{
if (isMultiSheet)
{
if (currentSheetCount >= perSheetCount)
{
sheetCount++;
currentSheetCount = 0;
sheet = workbookx.CreateSheet("Sheet" + sheetCount.ToString());
//这种写法从第二页不要表头 上下互相注释就是
row = sheet.CreateRow(currentSheetCount);
for (int j = 0; j < rowHeader.Cells.Count; j++)
{
cell = row.CreateCell(j);
cell.SetCellValue(rowHeader.Cells[j].StringCellValue);
cell.CellStyle = style;
}
}
}
currentSheetCount++;
row = sheet.CreateRow(currentSheetCount);
for (int j = 0; j < reader.FieldCount; j++)
{
cell = row.CreateCell(j);
cell.CellStyle = style;
SetCellValues(cell, reader[j].GetType().ToString(), reader[j].ToString());
}
}
FileStream fs = new FileStream(excelFileName, FileMode.CreateNew, FileAccess.Write);
workbookx.Write(fs);
fs.Close();
}
/// <summary>
/// 从DataTable导出到excle(xls)文件
/// </summary>
/// <param name="excelFileName"></param>
/// <param name="dtIn"></param>
private void ExportToXls(string excelFileName, DataTable dtIn, bool isMultiSheet = true)
{
int sheetCount = 1;//当前的sheet数量
int currentSheetCount = 0;//循环时当前保存的条数,每页都会清零
HSSFWorkbook workbook = new HSSFWorkbook();
SetProperty(workbook);
ISheet sheet = workbook.CreateSheet("Sheet" + sheetCount.ToString());
//填充表头
ICell cell = null;
IRow rowHeader = sheet.CreateRow(0);
ICellStyle style = GetXlsStyle(workbook);
for (int i = 0; i < dtIn.Columns.Count; i++)
{
cell = rowHeader.CreateCell(i);
cell.SetCellValue(dtIn.Columns[i].ColumnName);
cell.CellStyle = style;
}
//填充内容
IRow row = null;
for (int i = 0; i < dtIn.Rows.Count; i++)
{
if (isMultiSheet)
{
if (currentSheetCount >= perSheetCount)
{
sheetCount++;
currentSheetCount = 0;
sheet = workbook.CreateSheet("Sheet" + sheetCount.ToString());
row = sheet.CreateRow(currentSheetCount);
for (int j = 0; j < rowHeader.Cells.Count; j++)
{
cell = row.CreateCell(j);
cell.SetCellValue(rowHeader.Cells[j].StringCellValue);
cell.CellStyle = style;
}
}
}
currentSheetCount++;
try
{
row = sheet.CreateRow(currentSheetCount);
for (int j = 0; j < dtIn.Columns.Count; j++)
{
cell = row.CreateCell(j);
cell.CellStyle = style;
SetCellValues(cell, dtIn.Columns[j].DataType.ToString(), dtIn.Rows[i][j].ToString());
}
}
catch (ArgumentException ep)
{
if (ep.Source == "NPOI" && ep.Message.Contains("Invalid row number"))
{
throw new Exception("65535");
}
}
catch
{ }
}
FileStream fs = new FileStream(excelFileName, FileMode.CreateNew, FileAccess.Write);
workbook.Write(fs);
fs.Close();
}
/// <summary>
/// 从DataTable导出到excle(xlsx)文件
/// </summary>
/// <param name="excelFileName"></param>
/// <param name="dtIn"></param>
private void ExportToXlsx(string excelFileName, DataTable dtIn, bool isMultiSheet = true)
{
int sheetCount = 1;//当前的sheet数量
int currentSheetCount = 0;//循环时当前保存的条数,每页都会清零
XSSFWorkbook workbookx = new XSSFWorkbook();
ISheet sheet = workbookx.CreateSheet("Sheet" + sheetCount.ToString());
//填充表头
ICell cell = null;
IRow rowHeader = sheet.CreateRow(0);
ICellStyle style = GetXlsxStyle(workbookx);
for (int i = 0; i < dtIn.Columns.Count; i++)
{
cell = rowHeader.CreateCell(i);
cell.SetCellValue(dtIn.Columns[i].ColumnName);
cell.CellStyle = style;
}
//填充内容
IRow row = null;
for (int i = 0; i < dtIn.Rows.Count; i++)
{
if (isMultiSheet)
{
if (currentSheetCount >= perSheetCount)
{
sheetCount++;
currentSheetCount = 0;
sheet = workbookx.CreateSheet("Sheet" + sheetCount.ToString());
//这种写法从第二页不要表头 上下互相注释就是
row = sheet.CreateRow(currentSheetCount);
for (int j = 0; j < rowHeader.Cells.Count; j++)
{
cell = row.CreateCell(j);
cell.SetCellValue(rowHeader.Cells[j].StringCellValue);
cell.CellStyle = style;
}
}
}
currentSheetCount++;
row = sheet.CreateRow(currentSheetCount);
for (int j = 0; j < dtIn.Columns.Count; j++)
{
cell = row.CreateCell(j);
cell.CellStyle = style;
SetCellValues(cell, dtIn.Columns[j].DataType.ToString(), dtIn.Rows[i][j].ToString());
}
}
FileStream fs = new FileStream(excelFileName, FileMode.CreateNew, FileAccess.Write);
workbookx.Write(fs);
fs.Close();
}
public DataTable Import(string fileName, string sheetName, bool hasheader)
{
FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
HSSFWorkbook workbook = new HSSFWorkbook(fs);
fs.Close();
sheetName = string.IsNullOrEmpty(sheetName) ? workbook.GetSheetName(0) : sheetName;
HSSFSheet sheet = workbook.GetSheet(sheetName) as HSSFSheet;
IEnumerator ie = sheet.GetRowEnumerator();
HSSFRow row = null;
while (ie.MoveNext())
{
row = ie.Current as HSSFRow;//取一行,为了得到column的总数
break;
}
IList<string> lst = new List<string>();
DataTable dt = new DataTable();
if (hasheader)
{
for (int i = 0; i < row.LastCellNum; i++)
{
if (!lst.Contains(row.Cells[i].StringCellValue))
{
dt.Columns.Add(row.Cells[i].StringCellValue);
lst.Add(row.Cells[i].StringCellValue);
}
else
dt.Columns.Add(row.Cells[i].StringCellValue + i.ToString());
}
}
else
{
for (int i = 0; i < row.LastCellNum; i++)
{
dt.Columns.Add("A" + i.ToString());
}
ie.Reset();
}
DataRow drow = null;
HSSFCell cell = null;
while (ie.MoveNext())
{
row = ie.Current as HSSFRow;
drow = dt.NewRow();
for (int i = 0; i < dt.Columns.Count; i++)
{
if (row.GetCell(i) == null)
{
drow[i] = null;
continue;
}
cell = row.GetCell(i) as HSSFCell;
switch (cell.CellType)
{
case CellType.Blank:
//drow[i] = "[null]";
drow[i] = "";
break;
case CellType.Boolean:
drow[i] = cell.BooleanCellValue;
break;
case CellType.Error:
drow[i] = cell.ErrorCellValue;
break;
case CellType.Formula:
//drow[i] = "=" + cell.CellFormula;
drow[i] = "=" + cell.NumericCellValue;
break;
case CellType.Numeric:
drow[i] = cell.NumericCellValue;
break;
case CellType.String:
drow[i] = cell.StringCellValue;
break;
case CellType.Unknown:
break;
default:
drow[i] = null;
break;
}
}
dt.Rows.Add(drow);
}
return dt;
}
public string Export(string excelFileName, DataTable dtIn, bool isMultiSheet = false)
{
if (Path.GetExtension(excelFileName).ToUpper() == ".XLSX")
{
ExportToXlsx(excelFileName, dtIn, isMultiSheet);
}
else
ExportToXls(excelFileName, dtIn, isMultiSheet);
return excelFileName;
}
public string Export(string excelFileName, IDataReader reader, bool isMultiSheet = false)
{
if (Path.GetExtension(excelFileName).ToUpper() == ".XLSX")
{
ExportToXlsxFromReader(excelFileName, reader, isMultiSheet);
}
else
ExportToXlsFromReader(excelFileName, reader, isMultiSheet);
return excelFileName;
}
public string Export<T>(string excelFileName, IList<T> lst)
{
int sheetCount = 1;//当前的sheet数量
int currentSheetCount = 0;//循环时当前保存的条数,每页都会清零
HSSFWorkbook workbook = new HSSFWorkbook();
SetProperty(workbook);
//表头样式
ICellStyle style = workbook.CreateCellStyle();
style.Alignment = HorizontalAlignment.Center;
HSSFColor.Black green = new HSSFColor.Black();
style.SetFont(GetFont(workbook, green));
//内容样式
//style = workbook.CreateCellStyle();
//style.Alignment = HorizontalAlignment.Center;
//HSSFColor.Blue blue = new HSSFColor.Blue();
//style.SetFont(GetFont(workbook, blue));
ISheet sheet = workbook.CreateSheet("Sheet" + sheetCount.ToString());
ICell cell = null;
//填充表头
IRow rowHeader = sheet.CreateRow(0);
PropertyInfo[] infos = lst[0].GetType().GetProperties();
for (int i = 0; i < infos.Length; i++)
{
cell = rowHeader.CreateCell(i);
cell.SetCellValue(infos[i].Name);
cell.CellStyle = style;
}
string result = null;
IRow row = null;
foreach (T item in lst)
{
if (currentSheetCount >= perSheetCount)
{
sheetCount++;
currentSheetCount = 0;
sheet = workbook.CreateSheet("Sheet" + sheetCount.ToString());
//这种写法从第二页不要表头 上下互相注释就是
row = sheet.CreateRow(currentSheetCount);
for (int j = 0; j < rowHeader.Cells.Count; j++)
{
cell = row.CreateCell(j);
cell.SetCellValue(rowHeader.Cells[j].StringCellValue);
cell.CellStyle = style;
}
}
//if (sheetCount == 1)//因为第一页有表头,所以从第二页开始写
// row = sheet.CreateRow(currentSheetCount + 1);
//else//以后没有表头了,所以从开始写,都是基于0的
// row = sheet.CreateRow(currentSheetCount);
currentSheetCount++;
for (int j = 0; j < infos.Length; j++)
{
cell = row.CreateCell(j);
cell.CellStyle = style;
result = infos[j].GetValue(item, null) != null ? infos[j].GetValue(item, null).ToString() : "";
SetCellValues(cell, infos[j].PropertyType.FullName, result);
}
}
FileStream fs = new FileStream(excelFileName, FileMode.CreateNew, FileAccess.Write);
workbook.Write(fs);
fs.Close();
return excelFileName;
}
}
}