|
|
|
|
using NPOI.HSSF.UserModel;
|
|
|
|
|
using NPOI.SS.UserModel;
|
|
|
|
|
using NPOI.XSSF.UserModel;
|
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Data;
|
|
|
|
|
using System.IO;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Web;
|
|
|
|
|
|
|
|
|
|
namespace DSWeb.MvcShipping.Helper
|
|
|
|
|
{
|
|
|
|
|
public static class ExcelHelper
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 将excel文件内容读取到DataTable数据表中
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="fileName">文件完整路径名</param>
|
|
|
|
|
/// <param name="sheetName">指定读取excel工作薄sheet的名称</param>
|
|
|
|
|
/// <param name="isFirstRowColumn">第一行是否是DataTable的列名:true=是,false=否</param>
|
|
|
|
|
/// <returns>DataTable数据表</returns>
|
|
|
|
|
public static DataTable ReadExcelToDataTable(string fileName, out string strMsg, string sheetName = null, bool isFirstRowColumn = true)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
strMsg = "";
|
|
|
|
|
//定义要返回的datatable对象
|
|
|
|
|
DataTable data = new DataTable();
|
|
|
|
|
//excel工作表
|
|
|
|
|
NPOI.SS.UserModel.ISheet sheet = null;
|
|
|
|
|
//数据开始行(排除标题行)
|
|
|
|
|
int startRow = 0;
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
if (!File.Exists(fileName))
|
|
|
|
|
{
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
//根据指定路径读取文件
|
|
|
|
|
FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
|
|
|
|
|
//根据文件流创建excel数据结构
|
|
|
|
|
NPOI.SS.UserModel.IWorkbook workbook = NPOI.SS.UserModel.WorkbookFactory.Create(fs);
|
|
|
|
|
//IWorkbook workbook = new HSSFWorkbook(fs);
|
|
|
|
|
//如果有指定工作表名称
|
|
|
|
|
if (!string.IsNullOrEmpty(sheetName))
|
|
|
|
|
{
|
|
|
|
|
sheet = workbook.GetSheet(sheetName);
|
|
|
|
|
//如果没有找到指定的sheetName对应的sheet,则尝试获取第一个sheet
|
|
|
|
|
if (sheet == null)
|
|
|
|
|
{
|
|
|
|
|
sheet = workbook.GetSheetAt(0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
//如果没有指定的sheetName,则尝试获取第一个sheet
|
|
|
|
|
sheet = workbook.GetSheetAt(0);
|
|
|
|
|
}
|
|
|
|
|
if (sheet != null)
|
|
|
|
|
{
|
|
|
|
|
NPOI.SS.UserModel.IRow firstRow = sheet.GetRow(0);
|
|
|
|
|
//一行最后一个cell的编号 即总的列数
|
|
|
|
|
int cellCount = firstRow.LastCellNum;
|
|
|
|
|
//如果第一行是标题列名
|
|
|
|
|
if (isFirstRowColumn)
|
|
|
|
|
{
|
|
|
|
|
for (int i = firstRow.FirstCellNum; i < cellCount; ++i)
|
|
|
|
|
{
|
|
|
|
|
NPOI.SS.UserModel.ICell cell = firstRow.GetCell(i);
|
|
|
|
|
if (cell != null)
|
|
|
|
|
{
|
|
|
|
|
string cellValue = cell.StringCellValue;
|
|
|
|
|
if (cellValue != null)
|
|
|
|
|
{
|
|
|
|
|
DataColumn column = new DataColumn(cellValue);
|
|
|
|
|
data.Columns.Add(column);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
startRow = sheet.FirstRowNum + 1;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
startRow = sheet.FirstRowNum;
|
|
|
|
|
}
|
|
|
|
|
//最后一列的标号
|
|
|
|
|
int rowCount = sheet.LastRowNum;
|
|
|
|
|
for (int i = startRow; i <= rowCount; ++i)
|
|
|
|
|
{
|
|
|
|
|
NPOI.SS.UserModel.IRow row = sheet.GetRow(i);
|
|
|
|
|
if (row == null) continue; //没有数据的行默认是null
|
|
|
|
|
|
|
|
|
|
DataRow dataRow = data.NewRow();
|
|
|
|
|
for (int j = row.FirstCellNum; j < cellCount; ++j)
|
|
|
|
|
{
|
|
|
|
|
if (row.GetCell(j) != null) //同理,没有数据的单元格都默认是null
|
|
|
|
|
dataRow[j] = row.GetCell(j).ToString();
|
|
|
|
|
}
|
|
|
|
|
data.Rows.Add(dataRow);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
strMsg = ex.Message;
|
|
|
|
|
}
|
|
|
|
|
return data;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static DateTime GetDateTime(int timestamp)
|
|
|
|
|
{
|
|
|
|
|
//DateTime dtStart = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1));
|
|
|
|
|
//使用上面的方式会显示TimeZone已过时
|
|
|
|
|
//DateTime dtStart = TimeZoneInfo.ConvertTime(new DateTime(1970, 1, 1), TimeZoneInfo.Local);
|
|
|
|
|
//long lTime = long.Parse(timestamp + "0000");
|
|
|
|
|
//TimeSpan timeSpan = new TimeSpan(lTime);
|
|
|
|
|
//DateTime targetDt = dtStart.Add(timeSpan).AddHours(8);
|
|
|
|
|
DateTime dtStart = Convert.ToDateTime("1970-01-01");
|
|
|
|
|
DateTime targetDt = dtStart.AddDays(timestamp-1);
|
|
|
|
|
return targetDt;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 将文件流读取到DataTable数据表中
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="fileStream">文件流</param>
|
|
|
|
|
/// <param name="sheetName">指定读取excel工作薄sheet的名称</param>
|
|
|
|
|
/// <param name="isFirstRowColumn">第一行是否是DataTable的列名:true=是,false=否</param>
|
|
|
|
|
/// <returns>DataTable数据表</returns>
|
|
|
|
|
public static DataTable ReadStreamToDataTable(Stream fileStream, out string strMsg, string sheetName = null, bool isFirstRowColumn = true)
|
|
|
|
|
{
|
|
|
|
|
strMsg = "";
|
|
|
|
|
//定义要返回的datatable对象
|
|
|
|
|
DataTable data = new DataTable();
|
|
|
|
|
//excel工作表
|
|
|
|
|
NPOI.SS.UserModel.ISheet sheet = null;
|
|
|
|
|
|
|
|
|
|
//数据开始行(排除标题行)
|
|
|
|
|
int startRow = 0;
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
//根据文件流创建excel数据结构,NPOI的工厂类WorkbookFactory会自动识别excel版本,创建出不同的excel数据结构
|
|
|
|
|
NPOI.SS.UserModel.IWorkbook workbook = NPOI.SS.UserModel.WorkbookFactory.Create(fileStream);
|
|
|
|
|
//如果有指定工作表名称
|
|
|
|
|
if (!string.IsNullOrEmpty(sheetName))
|
|
|
|
|
{
|
|
|
|
|
sheet = workbook.GetSheet(sheetName);
|
|
|
|
|
//如果没有找到指定的sheetName对应的sheet,则尝试获取第一个sheet
|
|
|
|
|
if (sheet == null)
|
|
|
|
|
{
|
|
|
|
|
sheet = workbook.GetSheetAt(0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
//如果没有指定的sheetName,则尝试获取第一个sheet
|
|
|
|
|
sheet = workbook.GetSheetAt(0);
|
|
|
|
|
}
|
|
|
|
|
if (sheet != null)
|
|
|
|
|
{
|
|
|
|
|
NPOI.SS.UserModel.IRow firstRow = sheet.GetRow(0);
|
|
|
|
|
//一行最后一个cell的编号 即总的列数
|
|
|
|
|
int cellCount = firstRow.LastCellNum;
|
|
|
|
|
//如果第一行是标题列名
|
|
|
|
|
if (isFirstRowColumn)
|
|
|
|
|
{
|
|
|
|
|
for (int i = firstRow.FirstCellNum; i < cellCount; ++i)
|
|
|
|
|
{
|
|
|
|
|
NPOI.SS.UserModel.ICell cell = firstRow.GetCell(i);
|
|
|
|
|
if (cell != null)
|
|
|
|
|
{
|
|
|
|
|
string cellValue = cell.StringCellValue;
|
|
|
|
|
if (cellValue != null)
|
|
|
|
|
{
|
|
|
|
|
DataColumn column = new DataColumn(cellValue);
|
|
|
|
|
data.Columns.Add(column);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
startRow = sheet.FirstRowNum + 1;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
startRow = sheet.FirstRowNum;
|
|
|
|
|
}
|
|
|
|
|
//最后一列的标号
|
|
|
|
|
int rowCount = sheet.LastRowNum;
|
|
|
|
|
for (int i = startRow; i <= rowCount; ++i)
|
|
|
|
|
{
|
|
|
|
|
NPOI.SS.UserModel.IRow row = sheet.GetRow(i);
|
|
|
|
|
if (row == null || row.FirstCellNum < 0) continue; //没有数据的行默认是null
|
|
|
|
|
|
|
|
|
|
DataRow dataRow = data.NewRow();
|
|
|
|
|
for (int j = row.FirstCellNum; j < cellCount; ++j)
|
|
|
|
|
{
|
|
|
|
|
//同理,没有数据的单元格都默认是null
|
|
|
|
|
NPOI.SS.UserModel.ICell cell = row.GetCell(j);
|
|
|
|
|
if (cell != null)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
if (cell.CellType == NPOI.SS.UserModel.CellType.Numeric)
|
|
|
|
|
{
|
|
|
|
|
//判断是否日期类型
|
|
|
|
|
if (NPOI.SS.UserModel.DateUtil.IsCellDateFormatted(cell))
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
dataRow[j] = row.GetCell(j).DateCellValue;
|
|
|
|
|
}
|
|
|
|
|
catch
|
|
|
|
|
{
|
|
|
|
|
dataRow[j] = GetDateTime((int)row.GetCell(j).NumericCellValue);
|
|
|
|
|
//strMsg = row.GetCell(j).NumericCellValue.ToString();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
dataRow[j] = row.GetCell(j).ToString().Trim();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
dataRow[j] = row.GetCell(j).ToString().Trim();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
data.Rows.Add(dataRow);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
strMsg = ex.Message;
|
|
|
|
|
}
|
|
|
|
|
return data;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 将Excel单表转为Datatable
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="stream"></param>
|
|
|
|
|
/// <param name="fileType"></param>
|
|
|
|
|
/// <param name="strMsg"></param>
|
|
|
|
|
/// <param name="sheetName"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
public static DataTable ExcelToDatatable(Stream stream, string fileType, out string strMsg, string sheetName = null,int startrow=0)
|
|
|
|
|
{
|
|
|
|
|
strMsg = "";
|
|
|
|
|
DataTable dt = new DataTable();
|
|
|
|
|
ISheet sheet = null;
|
|
|
|
|
IWorkbook workbook = null;
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
#region 判断excel版本
|
|
|
|
|
//2007以上版本excel
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (fileType == ".xlsx")
|
|
|
|
|
{
|
|
|
|
|
stream.Seek(0, SeekOrigin.Begin);
|
|
|
|
|
// workbook = new XSSFWorkbook(stream);
|
|
|
|
|
workbook = NPOI.SS.UserModel.WorkbookFactory.Create(stream);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
//2007以下版本excel
|
|
|
|
|
else if (fileType == ".xls")
|
|
|
|
|
{
|
|
|
|
|
workbook = new HSSFWorkbook(stream);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
throw new Exception("传入的不是Excel文件!");
|
|
|
|
|
}
|
|
|
|
|
#endregion
|
|
|
|
|
if (!string.IsNullOrEmpty(sheetName))
|
|
|
|
|
{
|
|
|
|
|
sheet = workbook.GetSheet(sheetName);
|
|
|
|
|
if (sheet == null)
|
|
|
|
|
{
|
|
|
|
|
sheet = workbook.GetSheetAt(0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
sheet = workbook.GetSheetAt(0);
|
|
|
|
|
}
|
|
|
|
|
if (sheet != null)
|
|
|
|
|
{
|
|
|
|
|
IRow firstRow = sheet.GetRow(startrow);
|
|
|
|
|
int cellCount = firstRow.LastCellNum;
|
|
|
|
|
for (int i = firstRow.FirstCellNum; i < cellCount; i++)
|
|
|
|
|
{
|
|
|
|
|
ICell cell = firstRow.GetCell(i);
|
|
|
|
|
if (cell != null)
|
|
|
|
|
{
|
|
|
|
|
string cellValue = cell.StringCellValue.Trim();
|
|
|
|
|
if (!string.IsNullOrEmpty(cellValue))
|
|
|
|
|
{
|
|
|
|
|
DataColumn dataColumn = new DataColumn(cellValue);
|
|
|
|
|
dt.Columns.Add(dataColumn);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
DataRow dataRow = null;
|
|
|
|
|
//遍历行
|
|
|
|
|
for (int j = sheet.FirstRowNum + 1; j <= sheet.LastRowNum; j++)
|
|
|
|
|
{
|
|
|
|
|
IRow row = sheet.GetRow(j);
|
|
|
|
|
dataRow = dt.NewRow();
|
|
|
|
|
if (row == null || row.FirstCellNum < 0)
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
//遍历列
|
|
|
|
|
|
|
|
|
|
var isadd =false;
|
|
|
|
|
for (int i = row.FirstCellNum; i < cellCount; i++)
|
|
|
|
|
{
|
|
|
|
|
ICell cellData = row.GetCell(i);
|
|
|
|
|
if (cellData != null)
|
|
|
|
|
{
|
|
|
|
|
if (cellData.CellType == NPOI.SS.UserModel.CellType.Numeric)
|
|
|
|
|
{
|
|
|
|
|
//判断是否日期类型
|
|
|
|
|
if (NPOI.SS.UserModel.DateUtil.IsCellDateFormatted(cellData))
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
dataRow[j] = cellData.DateCellValue;
|
|
|
|
|
}
|
|
|
|
|
catch
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
dataRow[j] = GetDateTime((int)cellData.NumericCellValue);
|
|
|
|
|
}
|
|
|
|
|
catch {
|
|
|
|
|
|
|
|
|
|
dataRow[i] = "";
|
|
|
|
|
}
|
|
|
|
|
//strMsg = row.GetCell(j).NumericCellValue.ToString();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
dataRow[i] = cellData.NumericCellValue;
|
|
|
|
|
}
|
|
|
|
|
catch
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
dataRow[i] = cellData.StringCellValue;
|
|
|
|
|
}
|
|
|
|
|
catch
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
dataRow[i] = "";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
dataRow[i] = cellData.StringCellValue;
|
|
|
|
|
}
|
|
|
|
|
catch
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
dataRow[i] = cellData.NumericCellValue;
|
|
|
|
|
}
|
|
|
|
|
catch
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
dataRow[i] = "";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//判断是否为数字型,必须加这个判断不然下面的日期判断会异常
|
|
|
|
|
//if (cellData.CellType == CellType.Numeric)
|
|
|
|
|
//{
|
|
|
|
|
// try
|
|
|
|
|
// {
|
|
|
|
|
// dataRow[j] = row.GetCell(j).DateCellValue;
|
|
|
|
|
// }
|
|
|
|
|
// catch
|
|
|
|
|
// {
|
|
|
|
|
// dataRow[j] = GetDateTime((int)row.GetCell(j).NumericCellValue);
|
|
|
|
|
// //strMsg = row.GetCell(j).NumericCellValue.ToString();
|
|
|
|
|
// }
|
|
|
|
|
//} else if (cellData.CellType == CellType.Formula)
|
|
|
|
|
//{
|
|
|
|
|
// try
|
|
|
|
|
// {
|
|
|
|
|
// dataRow[i] = cellData.StringCellValue;
|
|
|
|
|
// }
|
|
|
|
|
// catch {
|
|
|
|
|
// dataRow[i] = cellData.NumericCellValue;
|
|
|
|
|
// }
|
|
|
|
|
//}
|
|
|
|
|
//else
|
|
|
|
|
//{
|
|
|
|
|
// dataRow[i] = cellData.ToString().Trim();
|
|
|
|
|
//}
|
|
|
|
|
// dt.Rows.Add(dataRow);
|
|
|
|
|
isadd = true;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
dataRow[i] ="";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (isadd) dt.Rows.Add(dataRow);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
throw new Exception("没有获取到Excel中的数据表!");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
stream.Position = 0; // 增加这句
|
|
|
|
|
workbook = new HSSFWorkbook(stream);
|
|
|
|
|
strMsg = ex.Message;
|
|
|
|
|
}
|
|
|
|
|
return dt;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|