读取Excel文件的两种方法比较 以及用NPOI写入Excel
1. 采用NPOI方式,只需引用NPOI.dll,但目前最高只能到2.4.0版。
缺点:只支持.xls,不支持.xlsx格式。github上的2.4.1版支持.xlsx,但总提示缺ICSharpCode.SharpZipLib.dll,但找不到合适版本,暂时不能用。
优点:读取excel文件极快,1万行*9列的excel文件0.5秒就能读完,比下面的传统Office方法快将近1000倍!首选此方法。
using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
DataSet ds = null;
try
{
FileStream fileStream = new FileStream(tbFilePath.Text, FileMode.Open);
HSSFWorkbook workbook = new HSSFWorkbook(fileStream);
ISheet sheet = null;
IRow row = null;
ds = new DataSet();
DataTable dt = null;
for (int i = 0; i < workbook.Count; i++)
{
dt = new DataTable();
dt.TableName = "table" + i.ToString();
//获取 sheet 表
sheet = workbook.GetSheetAt(i);
//起始行索引
int rowIndex = sheet.FirstRowNum;
//获取行数
int rowCount = sheet.LastRowNum;
//获取第一行
IRow firstRow = sheet.GetRow(rowIndex);
//起始列索引
int colIndex = firstRow.FirstCellNum;
//获取列数
int colCount = firstRow.LastCellNum;
DataColumn dc = null;
//获取列名
for (int j = colIndex; j < colCount; j++)
{
dc = new DataColumn(firstRow.GetCell(j).StringCellValue);
dt.Columns.Add(dc);
}
//跳过第一行列名
rowIndex++;
for (int k = rowIndex; k <= rowCount; k++)
{
DataRow dr = dt.NewRow();
row = sheet.GetRow(k);
for (int l = colIndex; l < colCount; l++)
{
if (row.GetCell(l) == null)
{
continue;
}
if (row.GetCell(l).CellType == CellType.Numeric)
dr[l] = row.GetCell(l).NumericCellValue.ToString();
else
dr[l] = row.GetCell(l).StringCellValue;
}
dt.Rows.Add(dr);
}
ds.Tables.Add(dt);
}
sheet = null;
workbook = null;
fileStream.Close();
fileStream.Dispose();
}
catch (Exception ex)
{
throw;
}
方法二、传统的通过引用Office Excel dll读取
缺点:速度极慢,1万行*9列的excel文件要6.5分钟才能读完,比上面的方法一慢1000倍
DataSet ds = null;
DataTable dt = null;
Microsoft.Office.Interop.Excel.Application excel = new Microsoft.Office.Interop.Excel.Application();
Microsoft.Office.Interop.Excel.Workbook workbook = null;
Microsoft.Office.Interop.Excel.Worksheet worksheet = null;
Microsoft.Office.Interop.Excel.Sheets sheets = null;
Microsoft.Office.Interop.Excel.Range range = null;
object missing = System.Reflection.Missing.Value;
try
{
if (excel == null)
{
return null;
}
//打开 Excel 文件
workbook = excel.Workbooks.Open(filePath, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing);
//获取所有的 sheet 表
sheets = workbook.Worksheets;
ds = new DataSet();
for (int i = 1; i <= sheets.Count; i++)
{
//获取第一个表
worksheet = (Microsoft.Office.Interop.Excel.Worksheet)sheets.get_Item(i);
int rowCount = worksheet.UsedRange.Rows.Count;
int colCount = worksheet.UsedRange.Columns.Count;
int rowIndex = 1; //起始行为 1
int colIndex = 1; //起始列为 1
DataColumn dc;
dt = new DataTable();
dt.TableName = "table" + i.ToString();
//读取列名
for (int j = 0; j < colCount; j++)
{
range = worksheet.Cells[rowIndex, colIndex + j];
dc = new DataColumn();
dc.DataType = Type.GetType("System.String");
dc.ColumnName = range.Text.ToString().Trim();
//添加列
dt.Columns.Add(dc);
}
//读取行数据
for (int k = 1; k < rowCount; k++)
{
DataRow dr = dt.NewRow();
for (int l = 0; l < colCount; l++)
{
range = worksheet.Cells[rowIndex + k, colIndex + l];
//使用 range.Value.ToString(); 或 range.Value2.ToString(); 或 range.Text.ToString(); 都可以获取单元格的值
dr[l] = range.Text.ToString();
}
dt.Rows.Add(dr.ItemArray);
}
ds.Tables.Add(dt);
}
}
catch
{
throw;
}
finally
{
workbook.Close();
//关闭退出
excel.Quit();
//释放 COM 对象
Marshal.ReleaseComObject(worksheet);
Marshal.ReleaseComObject(workbook);
Marshal.ReleaseComObject(excel);
worksheet = null;
workbook = null;
excel = null;
GC.Collect();
}
return ds;
///NPOI写入大内容Excel,效率也是惊人的高,而且设置样式很方便/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
private static void DataWrite2Sheet(DataTable dt, int startRow, int endRow, IWorkbook book, string sheetName)
{
//创建标题行字体
IFont titleFont = (HSSFFont)book.CreateFont();
titleFont.IsBold = true; //字体加粗
titleFont.FontHeightInPoints = 13; //字体大小
titleFont.FontName = "仿宋";
//创建列头样式
ICellStyle titleStyle = (HSSFCellStyle)book.CreateCellStyle();
titleStyle.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Left; //居左
titleStyle.VerticalAlignment = NPOI.SS.UserModel.VerticalAlignment.Center; //垂直居中
titleStyle.SetFont(titleFont); //将字体绑定到样式
//创建内容样式
ICellStyle cellStyle = (HSSFCellStyle)book.CreateCellStyle();
cellStyle.WrapText = true; //自动换行,也使内容中的换行符生效
ISheet sheet = book.CreateSheet(sheetName);
sheet.CreateFreezePane(1,1); //冻结列头行
//设置标题行
IRow header = sheet.CreateRow(0);//创建标题行
for (int i = 0; i < dt.Columns.Count; i++)
{
ICell cell = header.CreateCell(i);
string val = dt.Columns[i].Caption ?? dt.Columns[i].ColumnName;
cell.SetCellValue(val);
cell.CellStyle = titleStyle;
}
//设置每行、每列内容
int rowIndex = 1;
for (int i = startRow; i <= endRow; i++)
{
DataRow dtRow = dt.Rows[i];
IRow excelRow = sheet.CreateRow(rowIndex++);
for (int j = 0; j < dtRow.ItemArray.Length; j++)
{
ICell cell_Conent = excelRow.CreateCell(j);
cell_Conent.SetCellValue(dtRow[j].ToString());
cell_Conent.CellStyle = cellStyle;
}
}
//列宽自适应,只对英文和数字有效
for (int i = 0; i <= dt.Rows.Count; i++)
{
sheet.AutoSizeColumn(i);
}
}
//此外关于计算中文内容自动计算列宽的方法
//先设置自动列宽
for (int i = 0; i <= dt.Rows.Count; i++)
{
sheet.AutoSizeColumn(i);
}
//再根据中文列宽计算,注意,该方法无法区分有换行符的内容,都按单行计算长度,而且也未考虑字体大小的影响,不准确
for (int columnNum = 0; columnNum <= 26; columnNum++)
{
int columnWidth = ffSheet.GetColumnWidth(columnNum) / 256;//获取当前列宽度
for (int rowNum = 1; rowNum <= ffSheet.LastRowNum; rowNum++)//在这一列上循环行
{
IRow currentRow = ffSheet.GetRow(rowNum);
ICell currentCell = currentRow.GetCell(columnNum);
int length = Encoding.UTF8.GetBytes(currentCell.ToString()).Length;//获取当前单元格的内容宽度
if (columnWidth < length + 1)
{
columnWidth = length + 1;
}//若当前单元格内容宽度大于列宽,则调整列宽为当前单元格宽度,后面的+1是我人为的将宽度增加一个字符
}
ffSheet.SetColumnWidth(columnNum, columnWidth * 256);
}</span>
columnNum是列号,从0开始循环到表格最后一列,循环的范围可以自己指定,原理很简单,就是在先循环列,在列上循环行,比对行内容宽度与列宽度,若行内容宽度大于列宽则增大列宽,循环以后,每列宽度等于该列中最宽的那一行的宽度。
值得注意的是使用UTF8编码来计算的,在UTF8编码中数字和英文字母宽度为2,汉字宽度为3。而且字号越小,其效果就越好。在实际使用中内容为10磅的时候,其效果就相当不错。
读取Excel文件的两种方法比较 以及用NPOI写入Excel的更多相关文章
- 读取Excel文件的两种方法
第一种方法:传统方法,采用OleDB读取EXCEL文件, 优点:写法简单,缺点:服务器必须安有此组件才能用,不推荐使用 private DataSet GetConnect_DataSet2(stri ...
- .NET CORE 2.1 导出excel文件的两种方法
最近在做 MVC 项目的时候遇到项目的导出,下面总结下两种导出到excel 的方法 第一种方法: 将文件写到本地,然后返回这个File 或者返回这个 File 的绝对地址 其中 _hostingE ...
- C#读取资源文件的两种方法及保存资源文件到本地
方法1 GetManifestResourceStream VB.NET中资源的名称为:项目默认命名空间.资源文件名 C#中则是:项目命名空间.资源文件所在文件夹名.资源文件名 例如:istr = ...
- Java导出Excel文件的两种方法
将数据以Excel表格的形式导出:首先下载poi的jar包,导入项目中,或者使用maven仓库管理,在pom文件添加:<dependency> <groupId>org. ...
- [转载]C#读写txt文件的两种方法介绍
C#读写txt文件的两种方法介绍 by 大龙哥 1.添加命名空间 System.IO; System.Text; 2.文件的读取 (1).使用FileStream类进行文件的读取,并将它转换成char ...
- java分享第十六天( java读取properties文件的几种方法&java配置文件持久化:static块的作用)
java读取properties文件的几种方法一.项目中经常会需要读取配置文件(properties文件),因此读取方法总结如下: 1.通过java.util.Properties读取Propert ...
- C#读写txt文件的两种方法介绍
C#读写txt文件的两种方法介绍 1.添加命名空间 System.IO; System.Text; 2.文件的读取 (1).使用FileStream类进行文件的读取,并将它转换成char数组,然后输出 ...
- matlab读取cvs文件的几种方法
matlab读取CVS文件的几种方法: 1,实用csvread()函数 csvread()函数有三种使用方法: 1.M = csvread('filename')2.M = csvread('fi ...
- elf格式转换为hex格式文件的两种方法
这周工作终于不太忙了,可以写点笔记总结一下了. 之前的文章如何在Keil-MDK开发环境生成Bin格式文件,介绍了如何在Keil开发环境使用fromelf软件,将生成的axf文件转换为bin文件,这次 ...
随机推荐
- 【python之路39】Python 正则表达式
Python 正则表达式 正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配. Python 自1.5版本起增加了re 模块,它提供 Perl 风格的正则表达式模式. r ...
- Django项目:CRM(客户关系管理系统)--44--36PerfectCRM实现King_admin密码修改
# king_urls.py # ————————02PerfectCRM创建ADMIN页面———————— from django.conf.urls import url from king_ad ...
- bzoj 3029 守卫者的挑战——概率期望dp+状态数思考
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3029 先随便写了个dfs,记录“前 i 次.成功 j 次.容量-残片=k”的概率.因为是否可 ...
- TZ_02MyBatis_lazy SqlMapConfig.xml
Mybatis的延迟加载又称为懒加载 mybatis在一对多的查询中,例如查询一个用户时需要查询这个用户下的所有账户信息,如果一次性的select * from user u left join ac ...
- DLX
#include <iostream> #include <cstdlib> #include <cstring> #include <queue> # ...
- 项目中的那些事---Java反射的应用
最近工作中遇到一个这样的问题: 为某个项目中的所有接口做一个测试工具,使用java Swing技术,该项目有不同的版本,不是所有版本中的接口都是相同的,而我做的工具需要兼容所有版本. 于是就引入了这样 ...
- Python3入门机器学习 经典算法与应用
Python3入门机器学习 整个课程都看完了,这个课程的分享可以往下看,下面有链接,之前做java开发也做了一些年头,也分享下自己看这个视频的感受,单论单个知识点课程本身没问题,大家看的时候可以关注下 ...
- history-之前发生了什么
查看一下之前服务器上执行过的命令.看一下总是没错的,加上前面看的谁登录过的信息,应该有点用.另外作为admin要注意,不要利用自己的权限去侵犯别人的隐私哦. 到这里先提醒一下,等会你可能会需要更新 H ...
- 【weex】publishTask
这个小项目还挺有意思的,是一个效果取快递的项目 我们看下效果 放博客的github地址:https://github.com/xiaomaer/publishTask 我们来看下代码,这几个页面运行的 ...
- Django用户名密码错误提示
from django.shortcuts import render # Create your views here. from django.shortcuts import render fr ...