NPOI读写Excel
http://www.cnblogs.com/luxiaoxun/p/3374992.html1、整个Excel表格叫做工作表:WorkBook(工作薄),包含的叫页(工作表):Sheet;行:Row;单元格Cell。
2、NPOI是POI的C#版本,NPOI的行和列的index都是从0开始
3、POI读取Excel有两种格式一个是HSSF,另一个是XSSF。 HSSF和XSSF的区别如下:
HSSF is the POI Project's pure Java implementation of the Excel '97(-2007) file format.
XSSF is the POI Project's pure Java implementation of the Excel 2007 OOXML (.xlsx) file format.
即:HSSF适用2007以前的版本,XSSF适用2007版本及其以上的。
下面是用NPOI读写Excel的例子:ExcelHelper封装的功能主要是把DataTable中数据写入到Excel中,或者是从Excel读取数据到一个DataTable中。
ExcelHelper类:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using NPOI.HSSF.UserModel;
using System.IO;
using System.Data;
namespace NetUtilityLib
{
public class ExcelHelper : IDisposable
{
private string fileName = null; //文件名
private IWorkbook workbook = null;
private FileStream fs = null;
private bool disposed;
public ExcelHelper(string fileName)
{
this.fileName = fileName;
disposed = false;
}
/// <summary>
/// 将DataTable数据导入到excel中
/// </summary>
/// <param name="data">要导入的数据</param>
/// <param name="isColumnWritten">DataTable的列名是否要导入</param>
/// <param name="sheetName">要导入的excel的sheet的名称</param>
/// <returns>导入数据行数(包含列名那一行)</returns>
public int DataTableToExcel(DataTable data, string sheetName, bool isColumnWritten)
{
int i = 0;
int j = 0;
int count = 0;
ISheet sheet = null;
fs = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.ReadWrite);
if (fileName.IndexOf(".xlsx") > 0) // 2007版本
workbook = new XSSFWorkbook();
else if (fileName.IndexOf(".xls") > 0) // 2003版本
workbook = new HSSFWorkbook();
try
{
if (workbook != null)
{
sheet = workbook.CreateSheet(sheetName);
}
else
{
return -1;
}
if (isColumnWritten == true) //写入DataTable的列名
{
IRow row = sheet.CreateRow(0);
for (j = 0; j < data.Columns.Count; ++j)
{
row.CreateCell(j).SetCellValue(data.Columns[j].ColumnName);
}
count = 1;
}
else
{
count = 0;
}
for (i = 0; i < data.Rows.Count; ++i)
{
IRow row = sheet.CreateRow(count);
for (j = 0; j < data.Columns.Count; ++j)
{
row.CreateCell(j).SetCellValue(data.Rows[i][j].ToString());
}
++count;
}
workbook.Write(fs); //写入到excel
return count;
}
catch (Exception ex)
{
Console.WriteLine("Exception: " + ex.Message);
return -1;
}
}
/// <summary>
/// 将excel中的数据导入到DataTable中
/// </summary>
/// <param name="sheetName">excel工作薄sheet的名称</param>
/// <param name="isFirstRowColumn">第一行是否是DataTable的列名</param>
/// <returns>返回的DataTable</returns>
public DataTable ExcelToDataTable(string sheetName, bool isFirstRowColumn)
{
ISheet sheet = null;
DataTable data = new DataTable();
int startRow = 0;
try
{
fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
if (fileName.IndexOf(".xlsx") > 0) // 2007版本
workbook = new XSSFWorkbook(fs);
else if (fileName.IndexOf(".xls") > 0) // 2003版本
workbook = new HSSFWorkbook(fs);
if (sheetName != null)
{
sheet = workbook.GetSheet(sheetName);
if (sheet == null) //如果没有找到指定的sheetName对应的sheet,则尝试获取第一个sheet
{
sheet = workbook.GetSheetAt(0);
}
}
else
{
sheet = workbook.GetSheetAt(0);
}
if (sheet != null)
{
IRow firstRow = sheet.GetRow(0);
int cellCount = firstRow.LastCellNum; //一行最后一个cell的编号 即总的列数
if (isFirstRowColumn)
{
for (int i = firstRow.FirstCellNum; i < cellCount; ++i)
{
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)
{
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);
}
}
return data;
}
catch (Exception ex)
{
Console.WriteLine("Exception: " + ex.Message);
return null;
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
if (fs != null)
fs.Close();
}
fs = null;
disposed = true;
}
}
}
}
测试代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
namespace NPOIExcelExample
{
class Program
{
static DataTable GenerateData()
{
DataTable data = new DataTable();
for (int i = 0; i < 5; ++i)
{
data.Columns.Add("Columns_" + i.ToString(), typeof(string));
}
for (int i = 0; i < 10; ++i)
{
DataRow row = data.NewRow();
row["Columns_0"] = "item0_" + i.ToString();
row["Columns_1"] = "item1_" + i.ToString();
row["Columns_2"] = "item2_" + i.ToString();
row["Columns_3"] = "item3_" + i.ToString();
row["Columns_4"] = "item4_" + i.ToString();
data.Rows.Add(row);
}
return data;
}
static void PrintData(DataTable data)
{
if (data == null) return;
for (int i = 0; i < data.Rows.Count; ++i)
{
for (int j = 0; j < data.Columns.Count; ++j)
Console.Write("{0} ", data.Rows[i][j]);
Console.Write("\n");
}
}
static void TestExcelWrite(string file)
{
try
{
using (ExcelHelper excelHelper = new ExcelHelper(file))
{
DataTable data = GenerateData();
int count = excelHelper.DataTableToExcel(data, "MySheet", true);
if (count > 0)
Console.WriteLine("Number of imported data is {0} ", count);
}
}
catch (Exception ex)
{
Console.WriteLine("Exception: " + ex.Message);
}
}
static void TestExcelRead(string file)
{
try
{
using (ExcelHelper excelHelper = new ExcelHelper(file))
{
DataTable dt = excelHelper.ExcelToDataTable("MySheet", true);
PrintData(dt);
}
}
catch (Exception ex)
{
Console.WriteLine("Exception: " + ex.Message);
}
}
static void Main(string[] args)
{
string file = "..\\..\\myTest.xlsx";
TestExcelWrite(file);
TestExcelRead(file);
}
}
}
签于这篇文章阅读量较高,更新一下我使用Aspose.Cells的另一个版本:
PS:Aspose是要收费的
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Text;
using Aspose.Cells;
namespace NetUtilityLib
{
public static class ExcelHelper
{
public static int DataTableToExcel(DataTable data, string fileName, string sheetName, bool isColumnNameWritten)
{
int num = -1;
try
{
Workbook workBook;
Worksheet worksheet = null;
if (File.Exists(fileName))
workBook = new Workbook(fileName);
else
workBook = new Workbook();
if (sheetName == null)
{
if (workBook.Worksheets.Count > 0)
{
worksheet = workBook.Worksheets[0];
}
else
{
sheetName = "Sheet1";
workBook.Worksheets.RemoveAt(sheetName);
worksheet = workBook.Worksheets.Add(sheetName);
}
}
if (worksheet != null)
{
worksheet.Cells.Clear();
num = worksheet.Cells.ImportDataTable(data, isColumnNameWritten, 0, 0, false);
workBook.Save(fileName);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
return num;
}
public static void AddOneRowToExcel(DataRow dataRow, string fileName, string sheetName)
{
try
{
Workbook workBook;
if (File.Exists(fileName))
workBook = new Workbook(fileName);
else
workBook = new Workbook();
Worksheet worksheet=null;
if (sheetName == null)
{
worksheet = workBook.Worksheets[0];
}
else
{
worksheet = workBook.Worksheets[sheetName];
}
if (worksheet != null)
{
worksheet.Cells.ImportDataRow(dataRow, worksheet.Cells.MaxDataRow + 1,0);
//worksheet.Cells.ImportArray(dataArray, worksheet.Cells.MaxDataRow+1, 0, false);
workBook.Save(fileName);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
public static DataTable ExcelToDataTable(string fileName, string sheetName, bool isFirstRowColumnName)
{
DataTable data = new DataTable();
try
{
Workbook workbook = null;
FileInfo fileInfo = new FileInfo(fileName);
if (fileInfo.Extension.ToLower().Equals(".xlsx"))
workbook = new Workbook(fileName, new LoadOptions(LoadFormat.Xlsx));
else if (fileInfo.Extension.ToLower().Equals(".xls"))
workbook = new Workbook(fileName, new LoadOptions(LoadFormat.Excel97To2003));
if (workbook != null)
{
Worksheet worksheet = null;
if (sheetName != null)
{
worksheet = workbook.Worksheets[sheetName];
}
else
{
worksheet = workbook.Worksheets[0];
}
if (worksheet != null)
{
data = worksheet.Cells.ExportDataTable(0, 0, worksheet.Cells.MaxRow+1, worksheet.Cells.MaxColumn+1,
isFirstRowColumnName);
return data;
}
}
else
{
return data;
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
return data;
}
}
}
Excel相关DLL下载:NPOI-Lib.rar
1.NPOI下载地址:http://npoi.codeplex.com/releases/view/38113
2.NPOI学习系列教程推荐:http://www.cnblogs.com/tonyqus/archive/2009/04/12/1434209.html
参考:
http://www.cnblogs.com/Erik_Xu/archive/2012/06/08/2541957.html
http://www.cnblogs.com/linzheng/archive/2010/12/20/1912137.html
http://www.cnblogs.com/knowledgesea/archive/2012/11/16/2772547.html
========
Npoi操作excel
http://www.cnblogs.com/knowledgesea/archive/2012/11/16/2772547.htmlNpoi 简介
1.整个Excel表格叫做工作表:WorkBook(工作薄),包含的叫页(工作表):Sheet;行:Row;单元格Cell。
2.Npoi 下载地址:http://npoi.codeplex.com/releases/view/38113
3.Npoi 学习系列教程推荐:http://www.cnblogs.com/tonyqus/archive/2009/04/12/1434209.html
4.忘了告诉大家npoi是做什么的了,npoi 能够读写几乎所有的Office 97-2003文件格式,至少能够支持Word, PowerPoint, Excel, Visio的格式。
使用Npoi创建一个简单的xls文件
//创建xls文件
private void button1_Click(object sender, EventArgs e)
{
//创建工作薄
HSSFWorkbook wk = new HSSFWorkbook();
//创建一个名称为mySheet的表
ISheet tb = wk.CreateSheet("mySheet");
//创建一行,此行为第二行
IRow row = tb.CreateRow(1);
for (int i = 0; i < 20; i++)
{
ICell cell = row.CreateCell(i); //在第二行中创建单元格
cell.SetCellValue(i);//循环往第二行的单元格中添加数据
}
using (FileStream fs = File.OpenWrite(@"c:/myxls.xls")) //打开一个xls文件,如果没有则自行创建,如果存在myxls.xls文件则在创建是不要打开该文件!
{
wk.Write(fs); //向打开的这个xls文件中写入mySheet表并保存。
MessageBox.Show("提示:创建成功!");
}
}
使用Npoi读取一个简单的xls文件
//读取xls文件
private void button2_Click(object sender, EventArgs e)
{ StringBuilder sbr = new StringBuilder();
using (FileStream fs = File.OpenRead(@"c:/myxls.xls")) //打开myxls.xls文件
{
HSSFWorkbook wk = new HSSFWorkbook(fs); //把xls文件中的数据写入wk中
for (int i = 0; i < wk.NumberOfSheets; i++) //NumberOfSheets是myxls.xls中总共的表数
{
ISheet sheet = wk.GetSheetAt(i); //读取当前表数据
for (int j = 0; j <= sheet.LastRowNum; j++) //LastRowNum 是当前表的总行数
{
IRow row = sheet.GetRow(j); //读取当前行数据
if (row != null)
{
sbr.Append("-------------------------------------\r\n"); //读取行与行之间的提示界限
for (int k = 0; k <= row.LastCellNum; k++) //LastCellNum 是当前行的总列数
{
ICell cell = row.GetCell(k); //当前表格
if (cell != null)
{
sbr.Append(cell.ToString()); //获取表格中的数据并转换为字符串类型
}
}
}
}
}
}
sbr.ToString();
using (StreamWriter wr = new StreamWriter(new FileStream(@"c:/myText.txt", FileMode.Append))) //把读取xls文件的数据写入myText.txt文件中
{
wr.Write(sbr.ToString());
wr.Flush();
}
}
使用Npoi创建一个常用的xls文件
//创建一个常用的xls文件
private void button3_Click(object sender, EventArgs e)
{
IWorkbook wb = new HSSFWorkbook();
//创建表
ISheet sh = wb.CreateSheet("zhiyuan");
//设置单元的宽度
sh.SetColumnWidth(0, 15 * 256);
sh.SetColumnWidth(1, 35 * 256);
sh.SetColumnWidth(2, 15 * 256);
sh.SetColumnWidth(3, 10 * 256);
int i = 0;
#region 练习合并单元格
sh.AddMergedRegion(new NPOI.SS.Util.CellRangeAddress(0, 0, 0, 3));
//CellRangeAddress()该方法的参数次序是:开始行号,结束行号,开始列号,结束列号。
IRow row0 = sh.CreateRow(0);
row0.Height = 20 * 20;
ICell icell1top0 = row0.CreateCell(0);
icell1top0.CellStyle = Getcellstyle(wb, stylexls.头);
icell1top0.SetCellValue("标题合并单元");
#endregion
i++;
#region 设置表头
IRow row1 = sh.CreateRow(1);
row1.Height = 20 * 20;
ICell icell1top = row1.CreateCell(0);
icell1top.CellStyle = Getcellstyle(wb, stylexls.头);
icell1top.SetCellValue("网站名");
ICell icell2top = row1.CreateCell(1);
icell2top.CellStyle = Getcellstyle(wb, stylexls.头);
icell2top.SetCellValue("网址");
ICell icell3top = row1.CreateCell(2);
icell3top.CellStyle = Getcellstyle(wb, stylexls.头);
icell3top.SetCellValue("百度快照");
ICell icell4top = row1.CreateCell(3);
icell4top.CellStyle = Getcellstyle(wb, stylexls.头);
icell4top.SetCellValue("百度收录");
#endregion
using(FileStream stm=File.OpenWrite(@"c:/myMergeCell.xls"))
{
wb.Write(stm);
MessageBox.Show("提示:创建成功!");
}
}
#region 定义单元格常用到样式的枚举
public enum stylexls
{
头,
url,
时间,
数字,
钱,
百分比,
中文大写,
科学计数法,
默认
}
#endregion
#region 定义单元格常用到样式
static ICellStyle Getcellstyle(IWorkbook wb, stylexls str)
{
ICellStyle cellStyle = wb.CreateCellStyle();
//定义几种字体
//也可以一种字体,写一些公共属性,然后在下面需要时加特殊的
IFont font12 = wb.CreateFont();
font12.FontHeightInPoints = 10;
font12.FontName = "微软雅黑";
IFont font = wb.CreateFont();
font.FontName = "微软雅黑";
//font.Underline = 1;下划线
IFont fontcolorblue = wb.CreateFont();
fontcolorblue.Color = HSSFColor.OLIVE_GREEN.BLUE.index;
fontcolorblue.IsItalic = true;//下划线
fontcolorblue.FontName = "微软雅黑";
//边框
cellStyle.BorderBottom = NPOI.SS.UserModel.BorderStyle.DOTTED;
cellStyle.BorderLeft = NPOI.SS.UserModel.BorderStyle.HAIR;
cellStyle.BorderRight = NPOI.SS.UserModel.BorderStyle.HAIR;
cellStyle.BorderTop = NPOI.SS.UserModel.BorderStyle.DOTTED;
//边框颜色
cellStyle.BottomBorderColor = HSSFColor.OLIVE_GREEN.BLUE.index;
cellStyle.TopBorderColor = HSSFColor.OLIVE_GREEN.BLUE.index;
//背景图形,我没有用到过。感觉很丑
//cellStyle.FillBackgroundColor = HSSFColor.OLIVE_GREEN.BLUE.index;
//cellStyle.FillForegroundColor = HSSFColor.OLIVE_GREEN.BLUE.index;
cellStyle.FillForegroundColor = HSSFColor.WHITE.index;
// cellStyle.FillPattern = FillPatternType.NO_FILL;
cellStyle.FillBackgroundColor = HSSFColor.BLUE.index;
//水平对齐
cellStyle.Alignment = NPOI.SS.UserModel.HorizontalAlignment.LEFT;
//垂直对齐
cellStyle.VerticalAlignment = VerticalAlignment.CENTER;
//自动换行
cellStyle.WrapText = true;
//缩进;当设置为1时,前面留的空白太大了。希旺官网改进。或者是我设置的不对
cellStyle.Indention = 0;
//上面基本都是设共公的设置
//下面列出了常用的字段类型
switch (str)
{
case stylexls.头:
// cellStyle.FillPattern = FillPatternType.LEAST_DOTS;
cellStyle.SetFont(font12);
break;
case stylexls.时间:
IDataFormat datastyle = wb.CreateDataFormat();
cellStyle.DataFormat = datastyle.GetFormat("yyyy/mm/dd");
cellStyle.SetFont(font);
break;
case stylexls.数字:
cellStyle.DataFormat = HSSFDataFormat.GetBuiltinFormat("0.00");
cellStyle.SetFont(font);
break;
case stylexls.钱:
IDataFormat format = wb.CreateDataFormat();
cellStyle.DataFormat = format.GetFormat("¥#,##0");
cellStyle.SetFont(font);
break;
case stylexls.url:
fontcolorblue.Underline = 1;
cellStyle.SetFont(fontcolorblue);
break;
case stylexls.百分比:
cellStyle.DataFormat = HSSFDataFormat.GetBuiltinFormat("0.00%");
cellStyle.SetFont(font);
break;
case stylexls.中文大写:
IDataFormat format1 = wb.CreateDataFormat();
cellStyle.DataFormat = format1.GetFormat("[DbNum2][$-804]0");
cellStyle.SetFont(font);
break;
case stylexls.科学计数法:
cellStyle.DataFormat = HSSFDataFormat.GetBuiltinFormat("0.00E+00");
cellStyle.SetFont(font);
break;
case stylexls.默认:
cellStyle.SetFont(font);
break;
}
return cellStyle;
}
#endregion
提示:1.以上使用npoi版本为1.2.5版本,版本目前属于最高版本,跟以前版本的使用是有些差别的。
2.使用以上代码,需要添加两个npoi的dll。Ionic.Zip.dll,NPOI.dll
错误提示:The supplied data appears to be in the Office 2007+ XML. You are calling the part of POI that deals with OLE2 Office Documents. You need to call a different part of POI to process this data (eg XSSF instead of HSSF)
错误原因:
HSSFWorkbook:是操作Excel2003以前(包括2003)的版本,扩展名是.xls
XSSFWorkbook:是操作Excel2007的版本,扩展名是.xlsx
解决方案:(引用npoi2.0)
ISheet sheet;
FileStream fs = null;
try
{
fs = new FileStream(txtPath.Text, FileMode.Open, FileAccess.Read);
HSSFWorkbook wk = new HSSFWorkbook(fs);
sheet = wk.GetSheet(sheetName);
}
catch
{
fs = new FileStream(txtPath.Text, FileMode.Open, FileAccess.Read);
XSSFWorkbook wk = new XSSFWorkbook(fs);
sheet = wk.GetSheet(sheetName);
}
finally
{
fs.Close();
fs.Dispose();
}
if (sheet.LastRowNum < 1)
{
MessageBox.Show("表内容不能为空");
return;
}
for (int j = 1; j <= sheet.LastRowNum; j++)
========
C#项目中操作Excel文件——使用NPOI库
http://blog.csdn.net/dcrmg/article/details/52356236实际C#项目中经常会涉及到需要对本地Excel文件进行操作,特别是一些包含数据记录、分析、汇总功能模块的项目。常用的操作Excel文件的方法主要有三个:
1. OleDb:
这种方式是把整个Excel文件当做一个数据源来进行数据的读取操作。
优点:实现方式简单,读取速度快;
缺点:读取Excel数据的过程不太灵活,对内存的占用比较高,当数据量变的很大时,容易由于内存空间不足导致内存溢出异常。(不过貌似对于今天电脑的硬件配置来说,内存问题不大)
2. Com组件
这种方式是通过Com组件 Microsoft.Office.Interop.Excel.dll实现Excel文件的操作。
优点:读取Excel数据非常灵活,可以实现Excel具有的各种数据处理功能;
缺点:对数据的访问时基于单元格方式实现的,所以读写数据较慢,特别是当数据量较大时,访问效率问题更为突出。另一点是要求本机安装了Microsoft Office组件。
3. NPOI
这种方式是通过NPOI库实现Excel文件操作,可以在没有安装微软Office的情况下使用。
优点:读取Excel数据速度较快,操作方式灵活;
缺点:试了再说!
NPOI支持的文件格式处理xls、xlsx外,还包括doc、ppt、vsd等,功能强大,人称Excel一哥。本文就准备单独谈一谈NPOI对Excel的基本操作。
NPOI是什么?
NPOI的log图标如下:
NPOI中N指代的是.Net,POI是一个完全开源的Java写成的库,能够在没有安装微软Office或者相应环境的情况下读写Excel、Word等微软OLE2组件文档,几乎支持所有的Office97~Office2007的文件格式。所以NPOI就是POI项目的.Net版本。目前NPOI的最新版本是今年5月份发布的V2.2.1,包含了.Net Framework2和.Net Framework4两个版本。
各个版本.Net Framework对应信息如下:
可以在C盘——C:\Windows\Microsoft.NET\Framework 下查看本机已经安装的.Net Framework版本,在我的机器上安装了以下版本:
NPOI库下载、解压
NPOI官网下载地址:点击打开链接,打开之后,点击红色框里的“NPOI 2.2.1 package”即可下载:
下载完成的压缩包大小只有3.5MB,解压后可以看到主要文件其实就是5个Dll文件(.Net 2.0和.Net 4.0):
使用的时候只要在自己的C#项目中添加这几个动态库文件的引用就可以了。
在C#工程中添加NPOI动态库引用
新建Visual Studio C# 控制台应用程序(或Windows窗体应用程序、WPF应用程序等均可),在解决方案管理器里项目下的“引用”上右击“添加引用”:
在弹出的“引用管理器”对话框中单击“浏览(B)”,选择NPOI所在的文件夹,根据机器上.Net Framework版本,选择Net20或Net40下的动态库。
添加完成之后展开项目下的“引用”项,可以看到刚才所添加的动态库。
经过简单的“添加引用”之后就可以在自己的代码中使用NPOI提供的接口实现各种Excel操作了。
Excel工作簿、工作表、xls、xlsx概念
在用NPOI编码之前,简单明确一下Excel中工作簿、工作表、xls、xlsx的概念,行、列、单元格等很明了的概念就不啰嗦了。
1. 每一个Excel文件都可以看做是一个工作簿,当打开一个Excel文件时,就等于打开了一个Excel工作簿。
2. 当打开了excel工作簿后在窗口底部看到的“Sheet”标签标示的是工作表,有几个标签就表示有几个工作表。
简单做一个类比,一个Excel文件即一个工作簿可以看做一本书,一个工作表即一个Sheet页面是书内的一页,可以 有很多页。Excel2003最多可以添加255(有强迫症的程序猿最爱的数字之一)个,Excel2007随意加。
3. xls是Office 2003以及之前版本Excel的扩展名,xlsx是Office 2007及之后版本Excel所用的扩展名。xlsx用新的基于 XML的压缩文件格式取代了之前的默认文件格式,在传统的文件名后面添加了字面x(即.docx取代.doc、.xlsx取 代.xls,等等),使其占用的空间更小。xlsx向下兼容xls。
新建一个Excel工作表
除添加Dll文件的引用外,还需要添加名称空间:
using NPOI.SS.UserModel;
using NPOI.HSSF.UserModel;
using NPOI.XSSF.UserModel;
HSSF使用于2007之前的xls版本,XSSF适用于2007及其之后的xlsx版本。
以下程序新建一个Excel 2003 xls和一个2007 xlsx文件,跟用Office建立的标准Excel格式一样,每一个Excel文件初始包含了3个工作表。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NPOI.SS.UserModel;
using NPOI.HSSF.UserModel;
using NPOI.XSSF.UserModel;
using System.IO;
namespace Excel_NPOI
{
class Program
{
static void Main(string[] args)
{
HSSFWorkbook workbook2003 = new HSSFWorkbook(); //新建xls工作簿
workbook2003.CreateSheet("Sheet1"); //新建3个Sheet工作表
workbook2003.CreateSheet("Sheet2");
workbook2003.CreateSheet("Sheet3");
FileStream file2003 = new FileStream(@"E:\Excel2003.xls", FileMode.Create);
workbook2003.Write(file2003);
file2003.Close(); //关闭文件流
workbook2003.Close();
XSSFWorkbook workbook2007 = new XSSFWorkbook(); //新建xlsx工作簿
workbook2007.CreateSheet("Sheet1");
workbook2007.CreateSheet("Sheet2");
workbook2007.CreateSheet("Sheet3");
FileStream file2007 = new FileStream(@"E:\Excel2007.xlsx", FileMode.Create);
workbook2007.Write(file2007);
file2007.Close();
workbook2007.Close();
}
}
}
运行之后会在E盘根目录下生成Excel2003.xls和Excel2007.xlsx两个文件。
写入Excel文件数据
以xls文件为例,介绍把数据写入Excel文件的方法。
写数据要遵循一定的顺序,可以概括为:读取(或新建一个工作簿)->获取工作表->对工作表添加行->对每一行添加单元格->对单元格赋值;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NPOI.SS.UserModel;
using NPOI.HSSF.UserModel;
using NPOI.XSSF.UserModel;
using System.IO;
namespace Excel_NPOI
{
class Program
{
static void Main(string[] args)
{
HSSFWorkbook workbook2003 = new HSSFWorkbook(); //新建工作簿
workbook2003.CreateSheet("Sheet1"); //新建1个Sheet工作表
HSSFSheet SheetOne = (HSSFSheet)workbook2003.GetSheet("Sheet1"); //获取名称为Sheet1的工作表
//对工作表先添加行,下标从0开始
for (int i = 0; i < 10; i++)
{
SheetOne.CreateRow(i); //创建10行
}
//对每一行创建10个单元格
HSSFRow SheetRow = (HSSFRow)SheetOne.GetRow(0); //获取Sheet1工作表的首行
HSSFCell[] SheetCell = new HSSFCell[10];
for (int i = 0; i < 10; i++)
{
SheetCell[i] = (HSSFCell)SheetRow.CreateCell(i); //为第一行创建10个单元格
}
//创建之后就可以赋值了
SheetCell[0].SetCellValue(true); //赋值为bool型
SheetCell[1].SetCellValue(0.000001); //赋值为浮点型
SheetCell[2].SetCellValue("Excel2003"); //赋值为字符串
SheetCell[3].SetCellValue("123456789987654321");//赋值为长字符串
for (int i = 4; i < 10; i++)
{
SheetCell[i].SetCellValue(i); //循环赋值为整形
}
FileStream file2003 = new FileStream(@"E:\Excel2003.xls", FileMode.Create);
workbook2003.Write(file2003);
file2003.Close();
workbook2003.Close();
}
}
}
运行之后在生成的Exce2003.xls中的内容为:
读取Excel文件数据
HSSFWorkbook类和XSSFWorkbook类都继承自IWorkbook类,所以在不知道所要读取的Excel文件时xls还是xlsx时,可以使用IWorkbook来声明一个通用的工作簿变量,随后根据传入的文件名判断是xls还是xlsx。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NPOI.SS.UserModel;
using NPOI.HSSF.UserModel;
using NPOI.XSSF.UserModel;
using System.IO;
namespace Excel_NPOI
{
class Program
{
static void Main(string[] args)
{
IWorkbook workbook = null; //新建IWorkbook对象
string fileName = "E:\\Excel2003.xls";
FileStream fileStream = new FileStream(@"E:\Excel2003.xls", FileMode.Open, FileAccess.Read);
if (fileName.IndexOf(".xlsx") > 0) // 2007版本
{
workbook = new XSSFWorkbook(fileStream); //xlsx数据读入workbook
}
else if (fileName.IndexOf(".xls") > 0) // 2003版本
{
workbook = new HSSFWorkbook(fileStream); //xls数据读入workbook
}
ISheet sheet = workbook.GetSheetAt(0); //获取第一个工作表
IRow row;// = sheet.GetRow(0); //新建当前工作表行数据
for (int i = 0; i < sheet.LastRowNum; i++) //对工作表每一行
{
row = sheet.GetRow(i); //row读入第i行数据
if (row != null)
{
for (int j = 0; j < row.LastCellNum; j++) //对工作表每一列
{
string cellValue = row.GetCell(j).ToString(); //获取i行j列数据
Console.WriteLine(cellValue);
}
}
}
Console.ReadLine();
fileStream.Close();
workbook.Close();
}
}
}
这段代码实现读取一个Excel文件内第一个工作表中的所有单元格内容,并打印输出。
取在上段代码中生成的xml文件作为输入,运行结果为:
========