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

433 lines
14 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.Common;
using System.Data.OleDb;
using System.IO;
using NPOI.SS.UserModel;
using NPOI.HSSF.UserModel;
namespace Mesnac.Basic
{
/// <summary>
/// 数据导出类
/// </summary>
public class DataToFileHandler
{
#region 单例实现
private static DataToFileHandler _instance;
private DataToFileHandler()
{
}
public static DataToFileHandler Instance
{
get
{
if (_instance == null)
{
_instance = new DataToFileHandler();
}
return _instance;
}
}
#endregion
#region 写入Excel文件
/// <summary>
/// 生成文件
/// </summary>
/// <returns></returns>
/// <remarks></remarks>
private HSSFWorkbook CreateHSSFWorkbook()
{
HSSFWorkbook hssfworkbook = new HSSFWorkbook();
return hssfworkbook;
}
/// <summary>
/// 生成表
/// </summary>
/// <param name="hssfworkbook">The hssfworkbook.</param>
/// <param name="sheetName">Name of the sheet.</param>
/// <returns></returns>
/// <remarks></remarks>
private ISheet CreateWorksheet(HSSFWorkbook hssfworkbook, string sheetName)
{
ISheet sheet = hssfworkbook.CreateSheet(sheetName);
return sheet;
}
/// <summary>
/// 字段头
/// </summary>
/// <param name="dt">The dt.</param>
/// <param name="sheet">The sheet.</param>
/// <returns></returns>
/// <remarks></remarks>
protected virtual int WriteTitle(DataTable dt, ISheet sheet)
{
int Result = 0;
int rowIndex = 0;
//IRow row0 = sheet.CreateRow(rowIndex);
//row0.CreateCell(0).SetCellValue("数据生成时间");
//row0.CreateCell(1).SetCellValue(System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
//Result++;
//rowIndex++;
IRow row1 = sheet.CreateRow(rowIndex);
for (int i = 0; i < dt.Columns.Count; i++)
{
row1.CreateCell(i).SetCellValue(dt.Columns[i].ColumnName);
}
Result++;
return Result;
}
/// <summary>
/// 每行数据
/// </summary>
/// <param name="dr">The dr.</param>
/// <param name="sheet">The sheet.</param>
/// <param name="irows">The irows.</param>
/// <returns></returns>
/// <remarks></remarks>
protected virtual int WriteRow(DataRow dr, ISheet sheet, int irows)
{
int Result = 0;
IRow row = sheet.CreateRow(irows);
for (int icell = 0; icell < dr.Table.Columns.Count; icell++)
{
if (dr[icell] == null)
{
row.CreateCell(icell).SetCellValue("");
}
if (dr[icell] is DateTime)
{
row.CreateCell(icell).SetCellValue(((DateTime)dr[icell]).ToString("yyyy-MM-dd HH:mm:ss").Replace(" 00:00:00", ""));
continue;
}
if (dr[icell] is double)
{
row.CreateCell(icell).SetCellValue((double)dr[icell]);
continue;
}
if (dr[icell] is decimal)
{
string s = dr[icell].ToString();
row.CreateCell(icell).SetCellValue(double.Parse(s));
continue;
}
if (dr[icell] is int)
{
row.CreateCell(icell).SetCellValue((int)dr[icell]);
continue;
}
row.CreateCell(icell).SetCellValue(dr[icell].ToString());
}
Result++;
return Result;
}
/// <summary>
/// 转化为Excel文件
/// </summary>
/// <param name="hssfworkbook">The hssfworkbook.</param>
/// <param name="dt">The dt.</param>
/// <remarks></remarks>
private void ToExcel(HSSFWorkbook hssfworkbook, DataTable dt)
{
const int onesheetrowscount = 60000;
int isheetrows = 0;
int isheetcount = 0;
ISheet sheet = null;
for (int idr = 0; idr < dt.Rows.Count; idr++)
{
if (isheetrows == 0)
{
string sheetName = dt.TableName;
if (string.IsNullOrEmpty(sheetName))
{
sheetName = "Sheet";
}
if (isheetcount > 0)
{
sheetName += isheetcount.ToString();
}
sheet = CreateWorksheet(hssfworkbook, sheetName);
isheetrows += WriteTitle(dt, sheet);
}
isheetrows += WriteRow(dt.Rows[idr], sheet, isheetrows);
if (idr == onesheetrowscount)
{
isheetrows = 0;
isheetcount++;
}
}
}
/// <summary>
/// 转化为Excel文件
/// </summary>
/// <param name="dt">The dt.</param>
/// <param name="excelStream">The excel stream.</param>
/// <remarks></remarks>
public void ToExcel(DataTable dt, ref Stream excelStream)
{
HSSFWorkbook hssfworkbook = CreateHSSFWorkbook();
ToExcel(hssfworkbook, dt);
hssfworkbook.Write(excelStream);
}
/// <summary>
/// 转化为Excel文件
/// </summary>
/// <param name="ds">The ds.</param>
/// <param name="excelStream">The excel stream.</param>
/// <remarks></remarks>
public void ToExcel(DataSet ds, ref Stream excelStream)
{
HSSFWorkbook hssfworkbook = CreateHSSFWorkbook();
foreach (DataTable dt in ds.Tables)
{
ToExcel(hssfworkbook, dt);
}
hssfworkbook.Write(excelStream);
}
#endregion
#region 读取Excel文件 NPOI
/// <summary>
/// 读取表头
/// </summary>
/// <param name="rows">The rows.</param>
/// <returns></returns>
/// <remarks></remarks>
private DataTable ReadColumn(System.Collections.IEnumerator rows)
{
DataTable Result = new DataTable();
IRow dc_row = (HSSFRow)rows.Current;
for (int idc = 0; idc < dc_row.LastCellNum; idc++)
{
string dc_name = string.Empty;
try
{
ICell cell = dc_row.GetCell(idc);
if (cell == null)
{
dc_name = "EmptyCell_" + idc.ToString();
}
else
{
dc_name = cell.ToString();
}
}
catch
{
dc_name = "EmptyCell_" + idc.ToString();
}
Result.Columns.Add(dc_name);
}
return Result;
}
/// <summary>
/// 读行信息
/// </summary>
/// <param name="rows">The rows.</param>
/// <param name="dt">The dt.</param>
/// <remarks></remarks>
private void ReadRow(System.Collections.IEnumerator rows, ref DataTable dt)
{
IRow row = (HSSFRow)rows.Current;
DataRow dr = dt.NewRow();
bool hasData = false;
for (int i = 0; i < dt.Columns.Count; i++)
{
try
{
ICell cell = row.GetCell(i);
if (cell == null)
{
dr[i] = string.Empty;
}
else
{
dr[i] = cell.ToString();
if (!string.IsNullOrEmpty(cell.ToString()))
{
hasData = true;
}
}
}
catch
{
dr[i] = string.Empty;
}
}
if (hasData)
{
dt.Rows.Add(dr);
}
}
/// <summary>
/// 读表信息
/// </summary>
/// <param name="sheet">The sheet.</param>
/// <param name="rows">The rows.</param>
/// <returns></returns>
/// <remarks></remarks>
private DataTable ReadDataTable(ISheet sheet, System.Collections.IEnumerator rows)
{
DataTable Result = ReadColumn(rows);
while (rows.MoveNext())
{
ReadRow(rows, ref Result);
}
Result.TableName = sheet.SheetName.Trim();
return Result;
}
/// <summary>
/// 读多表信息
/// </summary>
/// <param name="fileName">Name of the file.</param>
/// <param name="TableName">Name of the table.</param>
/// <returns></returns>
/// <remarks></remarks>
private DataSet ReadDataSet(string fileName, string TableName)
{
DataSet Result = new DataSet();
using (FileStream file = new FileStream(fileName, FileMode.Open, FileAccess.Read))
{
HSSFWorkbook hssfworkbook = new HSSFWorkbook(file);
for (int isheet = 0; isheet < hssfworkbook.NumberOfSheets; isheet++)
{
ISheet sheet = hssfworkbook.GetSheetAt(isheet);
System.Collections.IEnumerator rows = sheet.GetRowEnumerator();
if (!rows.MoveNext())
{
continue;
}
if (!string.IsNullOrEmpty(TableName))
{
if (TableName.Trim().ToUpper() != sheet.SheetName.Trim().ToUpper())
{
continue;
}
}
Result.Tables.Add(ReadDataTable(sheet, rows));
}
}
return Result;
}
/// <summary>
/// 读Excel文件
/// </summary>
/// <param name="FileName">Name of the file.</param>
/// <returns></returns>
/// <remarks></remarks>
public DataSet FromExcel(string FileName)
{
return ReadDataSet(FileName, string.Empty);
}
/// <summary>
/// 读Excel文件中的某个表
/// </summary>
/// <param name="FileName">Name of the file.</param>
/// <param name="TableName">Name of the table.</param>
/// <returns></returns>
/// <remarks></remarks>
public DataTable FromExcel(string FileName, string TableName)
{
DataTable Result = new DataTable();
DataSet ds = ReadDataSet(FileName, TableName);
if ((ds != null) && (ds.Tables.Count > 0))
{
Result = ds.Tables[0];
}
return Result;
}
#endregion
#region 读取Excel文件 ODBC
//需要安装 AccessDatabaseEngine.exe 而且系统需要运行在x86下
/// <summary>
/// 读Excel文件中的某个表
/// </summary>
/// <param name="fileName">Name of the file.</param>
/// <param name="TableName">Name of the table.</param>
/// <returns></returns>
/// <remarks></remarks>
private DataSet _ReadDataSet(string fileName, string TableName)
{
DataSet Result = new DataSet();
string strCon = "Provider=Microsoft.Jet.OLEDB.4.0;" +
"Extended Properties=Excel 8.0;" +
"data source=\"" + fileName + "\"";
OleDbConnection myConn = new OleDbConnection(strCon);
if ((!string.IsNullOrEmpty(TableName.Trim())) && (!TableName.Trim().EndsWith("$")))
{
TableName = TableName.Trim() + "$";
}
try
{
myConn.Open();
DataTable dt = myConn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
foreach (DataRow dr in dt.Rows)
{
string tablename = dr["TABLE_NAME"].ToString();
if ((!string.IsNullOrEmpty(TableName.Trim())) && (TableName.Trim() != tablename))
{
continue;
}
if (tablename.EndsWith("$"))
{
string sqlstr = " SELECT * FROM [" + tablename + "]";
DataTable mydatatable = new DataTable();
mydatatable.Clear();
mydatatable.Reset();
DbCommand mycommand = myConn.CreateCommand();
mycommand.CommandText = sqlstr;
DbDataReader myRd = mycommand.ExecuteReader();
mydatatable.Load(myRd, LoadOption.Upsert);
Result.Tables.Add(mydatatable);
}
}
}
finally
{
myConn.Close();
}
return Result;
}
/// <summary>
/// 读Excel文件
/// </summary>
/// <param name="FileName">Name of the file.</param>
/// <returns></returns>
/// <remarks></remarks>
public DataSet _FromExcel(string FileName)
{
return _ReadDataSet(FileName, string.Empty);
}
/// <summary>
/// 读Excel文件中的某个表
/// </summary>
/// <param name="FileName">Name of the file.</param>
/// <param name="TableName">Name of the table.</param>
/// <returns></returns>
/// <remarks></remarks>
public DataTable _FromExcel(string FileName, string TableName)
{
DataTable Result = new DataTable();
DataSet ds = _ReadDataSet(FileName, TableName);
if ((ds != null) && (ds.Tables.Count > 0))
{
Result = ds.Tables[0];
}
return Result;
}
#endregion
}
}