(编程语言界的丐帮 C#).NET Framework 读取Excel到DataTable
(编程语言界的丐帮 C#).NET Framework 读取Excel到DataTable
生成DataTable到Excel,支持 2007 .xlsx,2003 .xls。
nuget 引用 NPOI 。
ExcelHelper:
using NPOI.HPSF;
using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using System;
using System.Collections;
using System.Data;
using System.IO; namespace CommonUtils
{
/// <summary>
/// Excel操作相关
/// </summary>
public class ExcelHelper
{
#region 读取Excel到DataTable /// <summary>
/// 读取Excel文件的内容
/// </summary>
/// <param name="path"></param>
/// <param name="sheetName">工作表名称</param>
/// <returns></returns>
public static DataTable GetDataTable(string path, string sheetName = null)
{
string contentType = "application/vnd.ms-excel";
if (path.ToLower().EndsWith(".xlsx"))
contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; using (FileStream file = new FileStream(path, FileMode.Open, FileAccess.Read))
{
return GetDataTable(file, contentType, sheetName);
}
} /// <summary>
/// 从Excel文件流读取内容
/// </summary>
/// <param name="file"></param>
/// <param name="sheetName"></param>
/// <returns></returns>
public static DataTable GetDataTable(Stream file, string contentType, string sheetName = null)
{
//载入工作簿
IWorkbook workBook = null;
if (contentType == "application/vnd.ms-excel")
{
workBook = new HSSFWorkbook(file);
}
else if (contentType == "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
{
workBook = new XSSFWorkbook(file);
}
else
{
throw new Exception("文件格式不被支持!");
} //获取工作表(sheetName为空则默认获取第一个工作表)
var sheet = string.IsNullOrEmpty(sheetName) ? workBook.GetSheetAt(0) : workBook.GetSheet(sheetName);
//生成DataTable
if (sheet != null)
return GetDataTable(sheet);
else
throw new Exception(string.Format("工作表{0}不存在!", sheetName ?? "")); } /// <summary>
/// 读取工作表数据
/// </summary>
/// <param name="sheet"></param>
/// <returns></returns>
private static DataTable GetDataTable(ISheet sheet)
{
IEnumerator rows = sheet.GetRowEnumerator(); DataTable dt = new DataTable(sheet.SheetName); //默认第一个非空行为列头
bool isTitle = true;
//标题行索引
int titleRowIndex = 0;
//默认列头后的第一个数据行,作为DataTable列类型的依据
IRow firstDataRow = null; while (rows.MoveNext())
{
IRow row = null;
if (rows.Current is XSSFRow)//*.xlsx
{
row = (XSSFRow)rows.Current;
}
else//*.xls
{
row = (HSSFRow)rows.Current;
} //是否空行
if (IsEmptyRow(row))
{
if (isTitle)
{
titleRowIndex++;
}
continue;
}
else
{
if (isTitle)
{
firstDataRow = sheet.GetRow(titleRowIndex + 1);//默认列头后的第一个数据行,作为DataTable列类型的依据
}
} DataRow dr = dt.NewRow(); for (int i = 0; i < row.LastCellNum; i++)
{
var cell = row.GetCell(i); if (isTitle)
{
var firstDataRowCell = firstDataRow.GetCell(i);
if (firstDataRowCell != null || cell != null)
{
dt.Columns.Add(cell.StringCellValue.Trim());
}
else
{
dt.Columns.Add(string.Format("未知列{0}", i + 1));
}
}
else
{
if (i > dt.Columns.Count - 1) break;
dr[i] = GetCellValue(cell, dt.Columns[i].DataType);
} }
if (!isTitle && !IsEmptyRow(dr, dt.Columns.Count))
{
dt.Rows.Add(dr);
}
isTitle = false;
} return dt;
} /// <summary>
/// 获取单元格值
/// </summary>
/// <param name="cell"></param>
/// <param name="colType"></param>
/// <returns></returns>
private static object GetCellValue(ICell cell, Type colType)
{
if (cell == null || cell.ToString().ToUpper().Equals("NULL") || cell.CellType == NPOI.SS.UserModel.CellType.Blank)
return DBNull.Value; object val = null;
switch (cell.CellType)
{
case NPOI.SS.UserModel.CellType.Boolean:
val = cell.BooleanCellValue;
break;
case NPOI.SS.UserModel.CellType.Numeric:
var cellValueStr = cell.ToString().Trim();
if (cellValueStr.IndexOf('-') >= 0 || cellValueStr.IndexOf('/') >= 0)
{
DateTime d = DateTime.MinValue;
DateTime.TryParse(cellValueStr, out d);
if (!d.Equals(DateTime.MinValue)) val = cellValueStr;
}
if (val == null)
{
decimal vNum = 0;
decimal.TryParse(cellValueStr, out vNum);
val = vNum;
}
break;
case NPOI.SS.UserModel.CellType.String:
val = cell.StringCellValue;
break;
case NPOI.SS.UserModel.CellType.Error:
val = cell.ErrorCellValue;
break;
case NPOI.SS.UserModel.CellType.Formula:
default:
val = "=" + cell.CellFormula;
break;
} return val;
} /// <summary>
/// 检查是否空数据行
/// </summary>
/// <param name="dr"></param>
/// <returns></returns>
private static bool IsEmptyRow(DataRow dr, int colCount)
{
bool isEmptyRow = true;
for (int i = 0; i < colCount; i++)
{
if (dr[i] != null && !dr[i].Equals(DBNull.Value))
{
isEmptyRow = false;
break;
}
}
return isEmptyRow;
} /// <summary>
/// 检查是否空的Excel行
/// </summary>
/// <param name="row"></param>
/// <returns></returns>
private static bool IsEmptyRow(IRow row)
{
bool isEmptyRow = true;
for (int i = 0; i < row.LastCellNum; i++)
{
if (row.GetCell(i) != null)
{
isEmptyRow = false;
break;
}
} return isEmptyRow;
}
#endregion #region 生成DataTable到Excel /// <summary>
/// 生成Excel数据到路径
/// </summary>
/// <param name="data"></param>
/// <param name="path"></param>
public static void GenerateExcel(DataTable data, string path)
{
var workBook = GenerateExcelData(data, path);
//保存至路径
using (FileStream fs = File.OpenWrite(path)) //打开一个xls文件,如果没有则自行创建,如果存在则在创建时不要打开该文件!
{
workBook.Write(fs); //向打开的这个xls文件中写入mySheet表并保存。
}
} /// <summary>
/// 生成Excel数据到字节流
/// </summary>
/// <param name="data"></param>
/// <param name="path"></param>
public static byte[] GenerateExcel2(DataTable data, string path)
{
var workBook = GenerateExcelData(data, path);
using (MemoryStream ms = new MemoryStream())
{
workBook.Write(ms);
return ms.GetBuffer();
}
} /// <summary>
/// 生成DataTable到Excel
/// </summary>
/// <param name="data"></param>
/// <param name="path"></param>
private static IWorkbook GenerateExcelData(DataTable data, string path)
{
//创建工作簿
IWorkbook workBook = null;
if (path.ToLower().EndsWith(".xls"))
workBook = new HSSFWorkbook();
else if (path.ToLower().EndsWith(".xlsx"))
workBook = new XSSFWorkbook();
else
throw new Exception("不支持的后缀名。"); //生成文件基本信息
//GenerateSummaryInformation(workBook);
//创建工作表
var sheet = workBook.CreateSheet("Sheet1");
//创建标题行
if (data != null && data.Columns.Count > 0)
{
IRow row = sheet.CreateRow(0);
for (int i = 0; i < data.Columns.Count; i++)
{
var cell = row.CreateCell(i);
cell.SetCellValue(data.Columns[i].ColumnName);
}
}
//创建数据行
if (data != null && data.Rows.Count > 0)
{
for (int rowIndex = 1; rowIndex <= data.Rows.Count; rowIndex++)
{
IRow row = sheet.CreateRow(rowIndex);
for (int colIndex = 0; colIndex < data.Columns.Count; colIndex++)
{
var cell = row.CreateCell(colIndex);
var cellValue = data.Rows[rowIndex - 1][colIndex];
switch (data.Columns[colIndex].DataType.Name)
{
case "Byte":
case "Int16":
case "Int32":
case "Int64":
case "Decimal":
case "Single":
case "Double":
double doubleVal = 0;
if (cellValue != null && !cellValue.Equals(System.DBNull.Value))
{
double.TryParse(cellValue.ToString(), out doubleVal);
cell.SetCellValue(doubleVal);
}
break;
case "DateTime":
DateTime dtVal = DateTime.MinValue;
if (cellValue != null && !cellValue.Equals(System.DBNull.Value))
{
DateTime.TryParse(cellValue.ToString(), out dtVal);
if (dtVal != DateTime.MinValue)
{
cell.SetCellValue(dtVal);
}
}
break;
default:
if (cellValue != null && !cellValue.Equals(System.DBNull.Value))
{
cell.SetCellValue(cellValue.ToString());
}
break;
} }
}
} return workBook;
} /// <summary>
/// 创建文档的基本信息(右击文件属性可看到的)
/// </summary>
/// <param name="workBook"></param>
private static void GenerateSummaryInformation(HSSFWorkbook workBook)
{
DocumentSummaryInformation dsi = PropertySetFactory.CreateDocumentSummaryInformation();
dsi.Company = "Company"; SummaryInformation si = PropertySetFactory.CreateSummaryInformation();
si.Subject = "Subject";//主题
si.Author = "Author";//作者 workBook.DocumentSummaryInformation = dsi;
workBook.SummaryInformation = si;
} #endregion
}
}
使用:
DataTable dt1 = new DataTable();
dt1.Columns.Add("name");
dt1.Columns.Add("age");
dt1.Rows.Add("liu","13");
dt1.Rows.Add("hally", "16"); string excelFullName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory,"第1个EXCEL.xlsx"); ExcelHelper.GenerateExcel(dt1, excelFullName);
Console.WriteLine("保存EXCEL完成。" ); DataTable dt2 = ExcelHelper.GetDataTable(excelFullName);
Console.WriteLine("读取到DataTable完成。");
foreach (DataRow dr in dt2.Rows)
{
Console.WriteLine(string.Format("Name:{0},Age:{1}",dr[0].ToString(), dr[1].ToString()));
}
-
(编程语言界的丐帮 C#).NET Framework 读取Excel到DataTable的更多相关文章
- 使用NPOI读取Excel到DataTable
一.NPOI介绍: 使用 NPOI 你就可以在没有安装 Office 或者相应环境的机器上对 WORD/EXCEL 文档进行读写.NPOI是构建在POI 3.x版本之上的,它可以在没有安装Office ...
- C#读取Excel,DataTable取值为空的解决办法
连接字符串这么些就行了 string strConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + opnFileName ...
- .net读取Excel转datatable、.net读取的Excel存在合并单元格并且转成datatable
项目中经常会遇到Excel导入数据,Excel的模板会可能是存在合并单元格的,模板如下图所示 读取时需要填充合并单元格的值,转成datatable单元格值时,填充合并单元格的值,如下图所示: 合并单元 ...
- (编程语言界的丐帮 C#).NET MD5 HASH 哈希 加密 与JAVA 互通
一.注意要点 1:输入字符串的的编码双方保持统一,如:UTF8: 2:HASH计算输出结果 byte[] 数组转String 时,编码要统一,如:转16进制小写字符串.当然也可以转Base64. 3: ...
- NPOI 读取excel到DataTable 读取隐藏列 读取公式列
处理思路: 1.打开excel 用NPOI进行读取: 2.读取第一个Sheet: 读取过程中: a.先设置相应列 不隐藏 b.读取Cell时 先判断是否的包含公式 相应代码如下: public sta ...
- C# 读取Excel到DataTable两种方式对比
方式一 OLEDB读取 数据库引擎 优点:读取速度快,依据sheet排序读取 缺点:对于Excel版本依赖强,无法读取指定sheet 错误提示:本地计算机未指定 Microsoft.ACE.OLEDB ...
- C#读取Excel转为DataTable
需要的Dll: NPOI.OOXML.dll https://files.cnblogs.com/files/CityOfThousandFires/NPOI.dl.rar /// <su ...
- C# oleDb方法读取Excel文件
今天学习的是从FTP上下载Excel文件,DataTable接收数据之后,在DataTable中通过筛选,删减修改之后把数据插入到DB相应表中. 优点:读取方式简单.读取速度快 缺点:除了读取过程不太 ...
- 基于.NET的程序读取Excel文件的解决方案
目录 0. 前言 1. 使用NPOI库读取Excel文件 2. 使用OleDbConnection 3. 相关参考 shanzm-2020年12月8日 23:48:11 0. 前言 以前基于 .NET ...
- .Net读取Excel文件时丢失数据的问题 (转载)
相信很多人都试过通过OleDB读取Excel文件,这种方法效率十分高,只是有一点会让人十分头痛,就是当一列中既有混合型数据,又有纯数据时,往往容易丢失数据. 百度过后,改连接字符串 “HDR=YES; ...
随机推荐
- App隐私合规“免费”自动化检测
简介: App隐私合规检测提供了全面的隐私合规检测报告和专家建议,从确保形式合规(隐私政策文本合规性)及实质合规(代码层合规性)的一致性,从个人信息收集.权限使用场景.超范围采集.隐私政策.三方SDK ...
- DataFunTalk:阿里建设一站式实时数仓的经验分享
简介: 本文内容整理于阿里资深技术专家姜伟华在DataFunTalk上的演讲,为大家介绍阿里巴巴基于一站式实时数仓Hologres建设实时数仓的经验和解决方案. 导读:大数据计算正从规模化走向实时化, ...
- 百信银行基于 Apache Hudi 实时数据湖演进方案
简介: 本文介绍了百信银行实时计算平台的建设情况,实时数据湖构建在 Hudi 上的方案和实践方法,以及实时计算平台集成 Hudi 和使用 Hudi 的方式. 本文介绍了百信银行实时计算平台的建设情况, ...
- 业内首款云原生技术中台产品云原生 Stack 来了!
简介: 云原生 Stack 满足了各种典型场景下客户对于线下高集成平台的诉求,让企业数字话转型不受技术约束,专注业务本身,加速企业数字化迭代. 今天,企业数字化转型依然面临很大的挑战,虽然有很多新技术 ...
- dotnet 7 已知问题 WPF 的 TreeView 开启虚拟化之后只显示首项
本文记录 WPF 在 dotnet 7 的一个已知问题,此问题当前已修复,只需更新 SDK 或运行时即可.使用 TreeView 在开启虚拟化之后只显示首项,其他项不显示.本文将告诉大家此问题的原因和 ...
- 2019-8-31-C#-转换类型和字符串
title author date CreateTime categories C# 转换类型和字符串 lindexi 2019-08-31 16:55:58 +0800 2018-2-13 17:2 ...
- Vue源码-手写mustache源码
引言 在Vue中使用模板语法能够非常方便的将数据绑定到视图中,使得在开发中可以更好的聚焦到业务逻辑的开发. mustache是一个很经典且优秀的模板引擎,vue中的模板引擎也对其有参考借鉴,了解它能更 ...
- STM32 USART串口通信
一.介绍 通用同步异步收发器(USART)提供了一种灵活的方法与使用工业标准NRZ异步串行数据格式的外部设备之间进行全双工数据交换.USART利用分数波特率发生器提供宽范围的波特率选择.它支持同步单向 ...
- 电路笔记03—kcl、kvl,独立源,受控源
电路笔记03-kcl.kvl,独立源,受控源 听起来简单,做起来需要思考.所以做作业,思考很有 必要.电路的功率守恒,4种受控源,用两类约束列方程.电路分析力最难的一部分,怎么把一个量用其它量表示,后 ...
- [Java]线程生命周期与线程通信
[版权声明]未经博主同意,谢绝转载!(请尊重原创,博主保留追究权) https://www.cnblogs.com/cnb-yuchen/p/18162522 出自[进步*于辰的博客] 线程生命周期与 ...