old_flsystem/类库/Api.Framework/Tools/Nopi/ExcelStreamExport.cs

666 lines
26 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Collections.Generic;
using NPOI.XSSF.UserModel;
using NPOI.SS.UserModel;
using NPOI.HSSF.UserModel;
using System.IO;
using System.Data;
using System.Web;
namespace Eson.Utils.ExcelHelper
{
/// <summary>
/// 导出Excel帮助类(内存流形式)
/// </summary>
public class ExcelStreamExport
{
private static ExcelStreamExport _instance;
/// <summary>
/// 实例化导出Excel帮助类
/// </summary>
/// <returns></returns>
public static ExcelStreamExport GetInstance()
{
if (_instance == null)
_instance = new ExcelStreamExport();
return _instance;
}
public IWorkbook workBook;
public ISheet workSheet;
public MemoryStream ms;
#region Excel文件基本操作
/// <summary>
/// 初始化工作簿(Book)
/// </summary>
/// <param name="strSaveName">文件名称,也作为工作簿名称</param>
/// <param name="is07Excel">是否导出2007以上版本的Excel</param>
public void InitializeWorkbook(string strSaveName, bool is07Excel)
{
//内存流导出
workBook = is07Excel ? (new XSSFWorkbook() as IWorkbook) : (new HSSFWorkbook() as IWorkbook);
ms = new MemoryStream();
workSheet = workBook.CreateSheet(strSaveName);
}
/// <summary>
/// 初始化工作簿(Book)
/// </summary>
/// <param name="strSaveName">文件名称,也作为工作簿名称</param>
/// <param name="is07Excel">是否导出2007以上版本的Excel(默认是)</param>
/// <param name="isFirstCreateSheet">是否第一次创建Excel的Sheet页默认是</param>
public void InitializeWorkSheet(string strSaveName, bool is07Excel = true, bool isFirstCreateSheet = true)
{
//内存流导出
workBook = is07Excel ? (new XSSFWorkbook() as IWorkbook) : (new HSSFWorkbook() as IWorkbook);
if (isFirstCreateSheet)
{
ms = new MemoryStream();
}
workSheet = workBook.CreateSheet(strSaveName);
}
/// <summary>
/// 按序号打开工作表(Sheet)
/// </summary>
/// <param name="intSheetIndex">工作表序号,为空时默认第一个工作表</param>
public void GetSheetByIndex(int? intSheetIndex)
{
if (intSheetIndex == null)
workSheet = workBook.GetSheetAt(0);
else
workSheet = workBook.GetSheetAt(Convert.ToInt32(intSheetIndex));
}
/// <summary>
/// 按名称打开工作表(Sheet)
/// </summary>
/// <param name="strSheetName">工作表名称</param>
public void GetSheetByName(string strSheetName)
{
workSheet = workBook.GetSheet(strSheetName);
}
/// <summary>
/// 初始化工作簿自动打开第intSheetIndex个SheetintSheetIndex默认为0
/// </summary>
/// <param name="strExcelFilePath">原Excel文件路径</param>
/// <param name="intSheetIndex">第几个Sheet默认为0</param>
/// <param name="is07Excel">是否导出2007以上版本的Excel</param>
public void GetSheetFromExcel(string strExcelFilePath, int? intSheetIndex, bool is07Excel)
{
InitializeWorkbook(strExcelFilePath, is07Excel);
GetSheetByIndex(intSheetIndex);
}
/// <summary>
/// 将工作簿写入文件
/// 如果目标文件已经存在,先删除
/// </summary>
/// <param name="strSaveFilePath">要保存的文件地址</param>
public void WriteToFile(string strSaveFilePath)
{
FileInfo fi = new FileInfo(strSaveFilePath);
if (fi.Exists)
fi.Delete();
FileStream fs = new FileStream(strSaveFilePath, FileMode.Create);
workBook.Write(fs);
fs.Close();
}
#endregion
#region excel文件
/// <summary>
/// 导出Excel传入泛型数据
/// </summary>
/// <typeparam name="T">T类型</typeparam>
/// <param name="lst">泛型</param>
/// <param name="dicProperties">想要转换的属性名称列表[key值对应Model属性,value值对应Excel显示的列名]</param>
/// <param name="strSaveName">保存名称</param>
/// <param name="is07Excel">是否导出2007以上版本的Excel默认是</param>
//public void WriteListDate<T>(List<T> lst, Dictionary<string, string> dicProperties, string strSaveName, bool is07Excel = true)
// where T : class
//{
// #region 初始化工作簿
// InitializeWorkbook(strSaveName, is07Excel);
// //转换数据
// DataTable dtbl = ExtensiveHelper.ConvertListToTable<T>(lst, dicProperties);
// //初始化行
// int rowIndex = 0;
// int intColumn = 0;
// IRow rowExcel = workSheet.CreateRow(rowIndex);
// ICell cellExcel;
// //初始化列
// foreach (KeyValuePair<string, string> property in dicProperties)
// {
// cellExcel = rowExcel.CreateCell(intColumn);
// cellExcel.SetCellValue(property.Value);
// ++intColumn;
// }
// #endregion
// #region 写入内容
// foreach (DataRow rowInfo in dtbl.Rows)
// {
// ++rowIndex;
// rowExcel = workSheet.CreateRow(rowIndex);
// int intColumnContent = 0;
// foreach (KeyValuePair<string, string> property in dicProperties)
// {
// cellExcel = rowExcel.CreateCell(intColumnContent);
// cellExcel.SetCellValue(rowInfo[property.Value].ToString());
// ++intColumnContent;
// }
// }
// #endregion
// //内存流导出
// ExportExcel(ms, strSaveName, is07Excel);
//}
/// <summary>
/// 输出Excel文件
/// </summary>
/// <param name="ms">MemoryStream内存流</param>
/// <param name="strSaveName">文件保存名称</param>
/// <param name="is07Excel">是否导出2007以上版本的Excel</param>
//private void ExportExcel(MemoryStream ms, string strSaveName, bool is07Excel)
//{
// try
// {
// ms.Flush();
// ms.Position = 0;
// workBook.Write(ms);
// workBook = null;
// HttpContext current = HttpContext.Current;
// current.Response.ContentType = "application/ms-excel";
// current.Response.AppendHeader("Content-Disposition", "attachment;filename=" + UrlOper.GetToExcelName(strSaveName) + (is07Excel ? ".xlsx" : ".xls"));
// current.Response.BinaryWrite(ms.ToArray());
// ms.Close();
// ms = null;
// current.Response.Flush();
// current.Response.End();
// //current.Response.Close();
// }
// catch (Exception ex) { }
//}
#region ExcelDataTable内存表
/// <summary>
/// 导出Excel传入DataTable内存表
/// </summary>
/// <param name="dtbl">DataTabke内存表</param>
/// <param name="dicProperties">想要转换的属性名称列表[key值对应Model属性,value值对应Excel显示的列名]</param>
/// <param name="strSaveName">保存名称</param>
/// <param name="is07Excel">是否导出2007以上版本的Excel默认是</param>
//public void WriteListDate(DataTable dtbl, Dictionary<string, string> dicProperties, string strSaveName, bool is07Excel = true)
//{
// #region 初始化工作簿
// InitializeWorkbook(strSaveName, is07Excel);
// //初始化行
// int rowIndex = 0;
// int intColumn = 0;
// IRow rowExcel = workSheet.CreateRow(rowIndex);
// ICell cellExcel;
// //初始化列
// foreach (KeyValuePair<string, string> property in dicProperties)
// {
// cellExcel = rowExcel.CreateCell(intColumn);
// cellExcel.SetCellValue(property.Value);
// ++intColumn;
// }
// #endregion
// #region 写入内容
// foreach (DataRow rowInfo in dtbl.Rows)
// {
// ++rowIndex;
// rowExcel = workSheet.CreateRow(rowIndex);
// int intColumnContent = 0;
// foreach (KeyValuePair<string, string> property in dicProperties)
// {
// cellExcel = rowExcel.CreateCell(intColumnContent);
// cellExcel.SetCellValue(GetColumValue(dtbl, rowInfo, property.Key));
// ++intColumnContent;
// }
// }
// #endregion
// //内存流导出
// ExportExcel(ms, strSaveName, is07Excel);
//}
#endregion
#region DataTable内存表数据Excel
/// <summary>
/// 传入多张DataTable内存表数据导出Excel
/// </summary>
/// <param name="dtblList">DataTabke内存表泛型数据</param>
/// <param name="strSaveName">保存名称</param>
/// <param name="sheetNameList">导出excel每页数据的Sheet名称不传入则按照dtblList的序号展示</param>
/// <param name="is07Excel">是否导出2007以上版本的Excel默认是</param>
//public void WriteListDate(List<DataTable> dtblList, string strSaveName = null, List<string> sheetNameList = null, bool is07Excel = true)
//{
// #region Excel每月Sheet名称初始化
// if (sheetNameList == null || (sheetNameList != null && dtblList.Count < sheetNameList.Count))
// {
// sheetNameList = new List<string>();
// for (var i = 1; i < dtblList.Count + 1; i++)
// {
// sheetNameList.Add(string.Format("数据表_{0}", i));
// }
// }
// if (string.IsNullOrEmpty(strSaveName))
// {
// strSaveName = DateTime.Now.ToString("yyyyMMddHHmmss");
// }
// #endregion
// #region 遍历数据表源
// var dtCount = 0;
// workBook = is07Excel ? (new XSSFWorkbook() as IWorkbook) : (new HSSFWorkbook() as IWorkbook);
// //创建流对象
// ms = new MemoryStream();
// foreach (var tb in dtblList)
// {
// if (tb != null && tb.Rows.Count > 0)
// {
// #region 获取表头列名称
// Dictionary<string, string> dicProperties = new Dictionary<string, string>();
// foreach (DataColumn column in tb.Columns)
// {
// dicProperties.Add(column.ColumnName, column.ColumnName);
// }
// #endregion
// var currSheet = workBook.CreateSheet(sheetNameList[dtCount]);
// //初始化行
// int rowIndex = 0;
// int intColumn = 0;
// IRow rowExcel = currSheet.CreateRow(rowIndex);
// ICell cellExcel;
// //初始化列
// foreach (KeyValuePair<string, string> property in dicProperties)
// {
// cellExcel = rowExcel.CreateCell(intColumn);
// cellExcel.SetCellValue(property.Value);
// ++intColumn;
// }
// #region 写入内容
// foreach (DataRow rowInfo in tb.Rows)
// {
// ++rowIndex;
// rowExcel = currSheet.CreateRow(rowIndex);
// int intColumnContent = 0;
// foreach (KeyValuePair<string, string> property in dicProperties)
// {
// cellExcel = rowExcel.CreateCell(intColumnContent);
// cellExcel.SetCellValue(GetColumValue(tb, rowInfo, property.Key));
// ++intColumnContent;
// }
// }
// #endregion
// }
// dtCount++;
// }
// #endregion
// //内存流导出
// ExportExcel(ms, strSaveName, is07Excel);
//}
#endregion
/// <summary>
/// 通过提供的列名和具体行返回DataTable中具体的某一列的值
/// </summary>
/// <param name="dtbl">内存表</param>
/// <param name="rowInfo">具体行</param>
/// <param name="columName">列名</param>
/// <returns>具体某列的值</returns>
public string GetColumValue(DataTable dtbl, DataRow rowInfo, string columName)
{
string clumValue = "";
foreach (DataColumn clum in dtbl.Columns)
{
if (clum.ColumnName.Equals(columName))
{
clumValue = rowInfo[clum].ToString();
break;
}
}
return clumValue;
}
/// <summary>
/// 将DataTable导出成Excel文件
/// </summary>
/// <param name="lstDtbl">DataTabke内存表泛型</param>
/// <param name="dicProperties">字典泛型,想要转换的属性名称列表[key值对应Model属性,value值对应Excel显示的列名]</param>
/// <param name="strSaveName">保存名称</param>
/// <param name="intLineCount">换行数,表之间的间距,不换行可以默认输入null,也可以输入0</param>
/// <param name="is07Excel">是否导出2007以上版本的Excel默认是</param>
//public void WriteListDate(List<DataTable> lstDtbl, List<Dictionary<string, string>> lstDicProperties, string strSaveName, int? intLineCount, bool is07Excel = true)
//{
// #region 初始化工作簿
// InitializeWorkbook(strSaveName, is07Excel);
// //初始化行
// int rowIndex = 0;
// IRow rowExcel;
// ICell cellExcel;
// #endregion
// #region 写内容
// for (int i = 0; i < lstDicProperties.Count; i++)
// {
// //写表头
// rowExcel = workSheet.CreateRow(rowIndex);
// int intColumn = 0;
// foreach (KeyValuePair<string, string> property in lstDicProperties[i])
// {
// cellExcel = rowExcel.CreateCell(intColumn);
// cellExcel.SetCellValue(property.Value);
// ++intColumn;
// }
// //写入内容
// foreach (DataRow rowInfo in lstDtbl[i].Rows)
// {
// ++rowIndex;
// rowExcel = workSheet.CreateRow(rowIndex);
// int intColumnContent = 0;
// foreach (KeyValuePair<string, string> property in lstDicProperties[i])
// {
// cellExcel = rowExcel.CreateCell(intColumnContent);
// cellExcel.SetCellValue(GetColumValue(lstDtbl[i], rowInfo, property.Key));
// ++intColumnContent;
// }
// }
// ++rowIndex;
// //换行
// rowIndex += intLineCount == null ? 0 : Convert.ToInt32(intLineCount);
// }
// #endregion
// //内存流导出
// ExportExcel(ms, strSaveName, is07Excel);
//}
#endregion
#region Excel2007数据
/// <summary>
/// 将Excel2007以上版本文件中的数据读出到DataTable中(xlsx)
/// </summary>
/// <param name="filePath">Excel2007版本以上文件地址</param>
/// <param name="sheetIndex">需读取Sheet的IndexSheet1的index是0默认0</param>
/// <returns></returns>
public DataTable ConvertExcelToTable(string filePath, int sheetIndex = 0)
{
DataTable dt = new DataTable();
string extension = System.IO.Path.GetExtension(filePath).ToLower();
using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
if (extension.Equals(".xls"))
{
workBook = new HSSFWorkbook(fs) as IWorkbook;
workSheet = workBook.GetSheetAt(sheetIndex);
#region
IRow header = workSheet.GetRow(workSheet.FirstRowNum);
List<int> columns = new List<int>();
for (int i = 0; i < header.LastCellNum; i++)
{
object obj = GetValueTypeForXLS(header.GetCell(i) as HSSFCell);
if (obj == null || obj.ToString() == string.Empty)
{
dt.Columns.Add(new DataColumn("Columns" + i.ToString()));
}
else
dt.Columns.Add(new DataColumn(obj.ToString()));
columns.Add(i);
}
#endregion
#region
for (int i = workSheet.FirstRowNum + 1; i <= workSheet.LastRowNum; i++)
{
DataRow dr = dt.NewRow();
int count = columns.Count; ;
foreach (int j in columns)
{
object obj = GetValueTypeForXLS(workSheet.GetRow(i).GetCell(j) as HSSFCell);
if (obj == null || string.IsNullOrEmpty(obj.ToString()))
{
count--;
dr[j] = "";
}
else
{
dr[j] = obj;
}
}
if (count != 0)
{
dt.Rows.Add(dr);
}
}
#endregion
}
else
{
try
{
workBook = new XSSFWorkbook(fs) as IWorkbook;
workSheet = workBook.GetSheetAt(sheetIndex);
#region
IRow header = workSheet.GetRow(workSheet.FirstRowNum);
List<int> columns = new List<int>();
for (int i = 0; i < header.LastCellNum; i++)
{
object obj = GetValueTypeForXLSX(header.GetCell(i) as XSSFCell);
if (obj == null || obj.ToString() == string.Empty)
{
dt.Columns.Add(new DataColumn("Columns" + i.ToString()));
}
else
dt.Columns.Add(new DataColumn(obj.ToString()));
columns.Add(i);
}
#endregion
#region
for (int i = workSheet.FirstRowNum + 1; i <= workSheet.LastRowNum; i++)
{
DataRow dr = dt.NewRow();
int count = columns.Count;
foreach (int j in columns)
{
object obj = GetValueTypeForXLSX(workSheet.GetRow(i).GetCell(j) as XSSFCell);
if (obj == null || string.IsNullOrEmpty(obj.ToString()))
{
count--;
dr[j] = "";
}
else
{
dr[j] = obj;
}
}
if (count != 0)
{
dt.Rows.Add(dr);
}
}
#endregion
}
catch (Exception)
{
workBook = new HSSFWorkbook(fs) as IWorkbook;
workSheet = workBook.GetSheetAt(sheetIndex);
#region
IRow header = workSheet.GetRow(workSheet.FirstRowNum);
List<int> columns = new List<int>();
for (int i = 0; i < header.LastCellNum; i++)
{
object obj = GetValueTypeForXLS(header.GetCell(i) as HSSFCell);
if (obj == null || obj.ToString() == string.Empty)
{
dt.Columns.Add(new DataColumn("Columns" + i.ToString()));
}
else
dt.Columns.Add(new DataColumn(obj.ToString()));
columns.Add(i);
}
#endregion
#region
for (int i = workSheet.FirstRowNum + 1; i <= workSheet.LastRowNum; i++)
{
DataRow dr = dt.NewRow();
int count = columns.Count; ;
foreach (int j in columns)
{
object obj = GetValueTypeForXLS(workSheet.GetRow(i).GetCell(j) as HSSFCell);
if (obj == null || string.IsNullOrEmpty(obj.ToString()))
{
count--;
dr[j] = "";
}
else
{
dr[j] = obj;
}
}
if (count != 0)
{
dt.Rows.Add(dr);
}
}
#endregion
}
}
}
return dt;
}
#endregion
#region
/// <summary>
/// 获取单元格类型(xlsx)
/// </summary>
/// <param name="cell">单元格</param>
/// <returns></returns>
private static object GetValueTypeForXLSX(XSSFCell cell)
{
if (cell == null)
return null;
switch (cell.CellType)
{
case CellType.Blank: //BLANK:
return null;
case CellType.Boolean: //BOOLEAN:
return cell.BooleanCellValue;
case CellType.Numeric: //NUMERIC:
//short format = cell.CellStyle.DataFormat;
//if (format == 14 || format == 31 || format == 57 || format == 58 || format == 178)
//{
// return cell.DateCellValue;
//}
//else
//{
// return cell.NumericCellValue;
//}
//NPOI中数字和日期都是NUMERIC类型的这里对其进行判断是否是日期类型
if (HSSFDateUtil.IsCellDateFormatted(cell))//日期类型
{
return cell.DateCellValue;
}
else//其他数字类型
{
return cell.NumericCellValue;
}
case CellType.String: //STRING:
return cell.StringCellValue;
case CellType.Error: //ERROR:
return cell.ErrorCellValue;
case CellType.Formula: //FORMULA:
default:
return "=" + cell.CellFormula;
}
}
/// <summary>
/// 获取单元格类型(xls)
/// </summary>
/// <param name="cell">单元格</param>
/// <returns></returns>
private static object GetValueTypeForXLS(HSSFCell cell)
{
if (cell == null)
return null;
switch (cell.CellType)
{
case CellType.Blank: //BLANK:
return null;
case CellType.Boolean: //BOOLEAN:
return cell.BooleanCellValue;
case CellType.Numeric: //NUMERIC:
//short format = cell.CellStyle.DataFormat;
//if (format == 14 || format == 31 || format == 57 || format == 58 || format == 178)
//{
// return cell.DateCellValue;
//}
//else
//{
// return cell.NumericCellValue;
//}
//NPOI中数字和日期都是NUMERIC类型的这里对其进行判断是否是日期类型
if (HSSFDateUtil.IsCellDateFormatted(cell))//日期类型
{
return cell.DateCellValue;
}
else//其他数字类型
{
return cell.NumericCellValue;
}
case CellType.String: //STRING:
return cell.StringCellValue;
case CellType.Error: //ERROR:
return cell.ErrorCellValue;
case CellType.Formula: //FORMULA:
default:
return "=" + cell.CellFormula;
}
}
#endregion
}
}