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的更多相关文章

  1. 读取Excel文件的两种方法

    第一种方法:传统方法,采用OleDB读取EXCEL文件, 优点:写法简单,缺点:服务器必须安有此组件才能用,不推荐使用 private DataSet GetConnect_DataSet2(stri ...

  2. .NET CORE 2.1 导出excel文件的两种方法

    最近在做 MVC 项目的时候遇到项目的导出,下面总结下两种导出到excel 的方法 第一种方法: 将文件写到本地,然后返回这个File 或者返回这个 File 的绝对地址  其中  _hostingE ...

  3. C#读取资源文件的两种方法及保存资源文件到本地

    方法1 GetManifestResourceStream   VB.NET中资源的名称为:项目默认命名空间.资源文件名 C#中则是:项目命名空间.资源文件所在文件夹名.资源文件名 例如:istr = ...

  4. Java导出Excel文件的两种方法

    将数据以Excel表格的形式导出:首先下载poi的jar包,导入项目中,或者使用maven仓库管理,在pom文件添加:<dependency>    <groupId>org. ...

  5. [转载]C#读写txt文件的两种方法介绍

    C#读写txt文件的两种方法介绍 by 大龙哥 1.添加命名空间 System.IO; System.Text; 2.文件的读取 (1).使用FileStream类进行文件的读取,并将它转换成char ...

  6. java分享第十六天( java读取properties文件的几种方法&java配置文件持久化:static块的作用)

     java读取properties文件的几种方法一.项目中经常会需要读取配置文件(properties文件),因此读取方法总结如下: 1.通过java.util.Properties读取Propert ...

  7. C#读写txt文件的两种方法介绍

    C#读写txt文件的两种方法介绍 1.添加命名空间 System.IO; System.Text; 2.文件的读取 (1).使用FileStream类进行文件的读取,并将它转换成char数组,然后输出 ...

  8. matlab读取cvs文件的几种方法

    matlab读取CVS文件的几种方法: 1,实用csvread()函数   csvread()函数有三种使用方法: 1.M = csvread('filename')2.M = csvread('fi ...

  9. elf格式转换为hex格式文件的两种方法

    这周工作终于不太忙了,可以写点笔记总结一下了. 之前的文章如何在Keil-MDK开发环境生成Bin格式文件,介绍了如何在Keil开发环境使用fromelf软件,将生成的axf文件转换为bin文件,这次 ...

随机推荐

  1. 1.Js 点击控件区域之外隐藏控件

    1.限制对象可以是 div 或者from 2.添加calss =stopProhide 3.需要添加jquery 类库 示例: $("#form_Query").click(fun ...

  2. js 实现继承

    我们现在要做的一件事情是像其他语言的面向对象一下实现继承多态 具体要求如下: 一个 Father 构造函数,一个 Child 构造函数,其中改写 Father中的部分参数, new Child() 表 ...

  3. 解决github下载慢的终极方法

    直接用ssr代理,使用全局代理. 下载墙外的软件,都可以,比如 GithubDsktop

  4. dedecms list标签调用附加表字段--绝对成功

    使用list标签调用附加表字段的时候会忽略一个地方,明明附加字段名已经添加进去了就是调用不出来 经过在网上查询了资料,说的天花乱坠,也都实践过一些,但是就是不成功鞋面介绍一下犯的低级错误在哪里 {de ...

  5. linux系统服务

    系统服务分类,根据其使用的方法来分,可以被分为三类 a.由init控制的服务:基本都是系统级别的服务,运行级别这一章讲的就是这一类的服务 b.由System V启动脚本启动的服务:和我们打交道最多的一 ...

  6. Javascript-随滚轮匀速滑动的浮动广告窗动画

    <!DOCTYPE html> <html lang="en" xmlns="http://www.w3.org/1999/xhtml"> ...

  7. [C#] 利用方向鍵移動 TextBox Focus

    論壇問題 版面上有 100 個 textbox,編號為 1-100,textbox 排列為 1 欄 20 個,共 5 欄,當一開打這個 form 會將在第一欄第一列第一個 textbox 的背景顏色變 ...

  8. 优化 Tengine HTTPS 握手时间

    背景 网络延迟是网络上的主要性能瓶颈之一.在最坏的情况下,客户端打开一个链接需要DNS查询(1个 RTT),TCP握手(1个 RTT),TLS 握手(2个RTT),以及最后的 HTTP 请求和响应,可 ...

  9. 发布Qt Widgets桌面应用程序的方法

    Qt是一款优秀的跨平台开发框架,它可以在桌面.移动平台以及嵌入式平台上运行.目前Qt 5介绍程序发布的文章帖子比较少.大家又非常想要知道如何发布Qt应用程序,于是我花了一点儿时间介绍一下如何发布Qt桌 ...

  10. hdu 3068 最长回文(manacher入门)

    最长回文 Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...