NPOI笔记

1,简介


NPOI 是 POI 项目的 .NET
版本。POI是一个开源的Java读写Excel、WORD等微软OLE2组件文档的项目。

使用 NPOI 你就可以在没有安装 Office 或者相应环境的机器上对 WORD/EXCEL 文档进行读写。NPOI是构建在POI
3.x
版本之上的,它可以在没有安装Office的情况下对Word/Excel文档进行读写操作

2,Excel基础


l整个Excel表格叫工作表:Workbook;工作簿,包含的叫页(工作表):Sheet;行:Row;单元格:Cell。

3,简介


a)   首先,对文件的操作都需要使用FileStream
 
FileStream file=new FileStream(“1.xls”,FileMode.Open,FileAccess.Read);
 
b)   对Excel工作薄操作时使用引用的NPOI类库中的一个类HSSFWorkbook
 
Workbook wkb=new HSSFWorkbook(filestream)
 
//HSSFWorkbook类实现了Workbook接口
 
对excel工作薄获取时需要HSSFWorkbook带参数的构造方法,参数为FileSteam的对象
 
c)   拿到工作薄厚获取其中的表:
 
Sheet sheet=wkb.GetSheet(“Sheet1”);//参数为工作薄中的表明
 
d)   获取表中的每一行,需要进行遍历
 
For(int i=0;i<sheet.LastRowNum+1;i++)//以最后一个为空的行为终点
 
{
 
    Row row=sheet.GetRow(i);//获取第i行的数据
 
    For(int j=0;j<row.LastCellNum;j++)//以最后一个有数据的cell为终点
 
    {
 
       Cell cell=row.GetCell(j);//获取第j个表格数据
 
       If(cell!=null)
 
       {
 
           String str=cell.StringCellValue;//获取表格数据
 
}
 
}
 
}

//////////////////////////////////

  

•workbook.NumberOfSheets//获得工作表的个数。
•workbook.GetSheetAt(i).GetRow(i) //获得行对象
•workbook.GetSheetAt(i).GetRow(i).LastRowNum//最后一样的索引
•workbook.GetSheetAt(i).GetRow(i).GetCell(j)//获得单元格对象
•workbook.GetSheetAt(i).GetRow(i).GetCell(j).ToString()//获得单元格的字符串表示形式。//StringCellValue、NumericCellValue等。
•workbook.GetSheetAt(i).GetRow(i).GetCell(j).CellType
4,代码
(在C#中对Excel进行读写操作时,先引用两个个类库NPOI.dll和Ionic.Zip.dll。)
(lnopi下载地址:http://npoi.codeplex.com/)

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using NPOI.SS.UserModel;
using NPOI.HSSF.UserModel;
using System.IO;
using System.Data.SqlClient;
using _01登录;

namespace _01NPOI操作
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        //读取Excel
        private void button1_Click(object sender, EventArgs e)
        {

            using (FileStream fs = File.OpenRead("ReadExcel.xls"))
            {
                // //1.创建一个工作薄对象,新版本不再需要调用Dispose()方法了。所以也不需要using了。
                //读取Excel的时候需要先创建一个流,指向对应的excel数据,然后把该流作为构造函数参数传递给HSSFWorkbook
                IWorkbook wk = new HSSFWorkbook(fs);

                //2.获取工作薄对象中的每个工作表
                //wk.NumberOfSheets 获取工作表格个数
                //遍历工作表
                for (int i = 0; i < wk.NumberOfSheets; i++)
                {
                    //根据索引获取某个sheet (工作表)
                    ISheet sheet = wk.GetSheetAt(i);
                    //输出当前工作表的名称
                    Console.WriteLine("=================={0}==================", sheet.SheetName);

                    //3.获取工作表中的每个行
                    //sheet.LastRowNum,获取的是最后一行的索引,所以循环遍历的时候需要加等号。
                    for (int r = 0; r <= sheet.LastRowNum; r++)
                    {
                        //获取当前行对象。
                        IRow row = sheet.GetRow(r);
                        if (row != null)
                        {
                            //4.获取每个行的每个单元格,并获取单元格内容。
                            //row.LastCellNum,获取的最后一个单元格的索引+1的值。
                            //遍历每个单元格
                            for (int c = 0; c < row.LastCellNum; c++)
                            {
                                //获取每个单元格
                                ICell cell = row.GetCell(c);
                                if (cell != null)
                                {
                                    //输出当前单元格的数据
                                    Console.Write(cell.ToString() + "\t");
                                }

                            }
                            Console.WriteLine();
                        }

                    }


                    Console.WriteLine("=======================================");
                    Console.WriteLine("=======================================");

                }



            }

        }


        //Excel写入。
        private void button2_Click(object sender, EventArgs e)
        {

            List<Person> list = new List<Person>() { 
            new Person(){ Name="张三", Age=18, Email="123@yahoo.com" },
            new Person(){ Name="李四", Age=19, Email="132@yahoo.com" },
            new Person(){ Name="王五", Age=20, Email="321@yahoo.com" },
            };

            //1.创建一个工作薄Workbook
            IWorkbook wk = new HSSFWorkbook();


            //2.创建若干Sheet工作表
            ISheet sheet = wk.CreateSheet("我的第一个Sheet");

            //3.向工作表中创建Row行。
            //向工作表中创建3行
            for (int i = 0; i < 3; i++)
            {
                //动态创建一行
                IRow row = sheet.CreateRow(i);

                //4.向Row中创建Cell单元格
                //向该行创建单元格
                //创建单元格1
                ICell cell = row.CreateCell(0);
                cell.SetCellValue(list[i].Name);

                row.CreateCell(1).SetCellValue(list[i].Age);

                row.CreateCell(2).SetCellValue(list[i].Email);

            }
            //5.将Workbook对象,写入到流中。
            using (FileStream fsWrite = File.OpenWrite("my.xls"))
            {
                wk.Write(fsWrite);
            }
            MessageBox.Show("ok");
        }

        //把数据库中的数据导出到Excel
        private void button3_Click(object sender, EventArgs e)
        {
            //1.读取数据库中的数据
            string sql = "select * from T_Seats";
            using (SqlDataReader reader = SqlHelper.ExecuteReader(sql, CommandType.Text))
            {
                if (reader.HasRows)
                {
                    //2.将数据导出到Excel文件
                    //在这里创建workbook工作薄对象,当查询到了数据后再创建工作薄
                    IWorkbook wk = new HSSFWorkbook();

                    //创建一个Sheet
                    ISheet sheet = wk.CreateSheet("T_Seats");

                    int row_index = 0;

                    #region 创建列名行
                    //创建第一行(显示列名)
                    IRow rowHeader = sheet.CreateRow(row_index);
                    row_index++;
                    //循环每一列
                    for (int i = 0; i < reader.FieldCount; i++)
                    {
                        //根据列索引获取列的名称 
                        string columnName = reader.GetName(i);
                        rowHeader.CreateCell(i).SetCellValue(columnName);

                    }
                    #endregion


                    //循环读取每行数据,并且创建该行对象。
                    while (reader.Read())
                    {
                        //每次reader.Read()读取一条数据就创建一个行对象
                        IRow row = sheet.CreateRow(row_index);
                        row_index++;


                        #region 创建列(单元格)

                        //循环读取每一条数据 ,获取当前行的每列的数据
                        //1.获取当前查询出的列的个数,然后再循环每一列
                        for (int i = 0; i < reader.FieldCount; i++)
                        {

                            //每次循环读取一列,就创建一个列的单元格
                            ICell cell = row.CreateCell(i);
                            //先获取对应列的数据类型,然后根据该列的数据类型,来决定应该调用哪个reader.GetXxxx();
                            if (reader.IsDBNull(i))
                            {
                                //如果数据库中为null值,则将单元格设置为“空单元格”
                                cell.SetCellType(CellType.BLANK);
                            }
                            else
                            {

                                switch (reader.GetDataTypeName(i))
                                {
                                    case "char":
                                    case "nchar":
                                    case "varchar":
                                    case "nvarchar":
                                    case "text":
                                    case "ntext":
                                        cell.SetCellValue(reader.GetString(i));
                                        break;
                                    case "int":
                                        cell.SetCellValue(reader.GetInt32(i));
                                        break;
                                    case "datetime":
                                        cell.SetCellValue(reader.GetDateTime(i));

                                        // 操作样式
                                        ICellStyle cellStyle = wk.CreateCellStyle();
                                        cellStyle.DataFormat = HSSFDataFormat.GetBuiltinFormat("m/d/yy h:mm");
                                        cell.CellStyle = cellStyle;

                                        break;
                                }
                            }
                            //获取列的数据类型
                            //Console.WriteLine(reader.GetDataTypeName(i) + "\t");
                            //                            reader.GetFieldType(
                        }
                        #endregion

                    }

                    //把wk写入到流中
                    using (FileStream fsWrite = File.OpenWrite("T_Seats.xls"))
                    {
                        wk.Write(fsWrite);
                    }
                    MessageBox.Show("导出成功!");
                }
                else
                {
                    MessageBox.Show("没有导出任何数据!");
                }
            }





        }


        //将Excel中的数据导入到表中
        private void button4_Click(object sender, EventArgs e)
        {
            //1.先读取Excel
            using (FileStream fsRead = File.OpenRead("T_Seats.xls"))
            {
                //创建Workbook
                IWorkbook wk = new HSSFWorkbook(fsRead);
                //读取Sheet
                ISheet sheet = wk.GetSheetAt(0);
                //读取Sheet中的每一行
                for (int i = 1; i <= sheet.LastRowNum; i++)
                {
                    //获取每一行
                    IRow row = sheet.GetRow(i);
                    if (row != null)//判断是否为空行
                    {

                        //每次读取一行,只要该行不为null,就为该行创建一个insert语句
                        string sql = "insert into T_Seats(CC_LoginId, CC_LoginPassword, CC_UserName, CC_ErrorTimes, CC_LockDateTime, CC_TestInt) values(@loginId,@password,@username,@errorTimes,@lockDate,@testInt)";
                        SqlParameter[] pms = new SqlParameter[] { 
                        new SqlParameter("@loginId",SqlDbType.NVarChar,50),
                        new SqlParameter("@password",SqlDbType.VarChar,50),
                        new SqlParameter("@username",SqlDbType.NVarChar,50),
                        new SqlParameter("@errorTimes",SqlDbType.Int),
                        new SqlParameter("@lockDate",SqlDbType.Decimal),
                        new SqlParameter("@testInt",SqlDbType.Int),
                        };

                        #region 读取Excel中的单元格内容,将其赋值到参数对象中

                        //============================================================
                        //循环读取每个单元格
                        for (int c = 1; c < row.LastCellNum; c++)
                        {
                            //从索引为1的行,索引为1的列开始
                            ICell cell = row.GetCell(c);
                            //经测试,当设置cell的CellType为CellType.BLANK时,该单元格并不是null而是一个已有的单元格。
                            if (cell != null)//判断是否为空单元格
                            {
                                //因为在创建参数对象的时候,明确指定了参数的数据类型,所以这里在获取参数的值的时候不能直接cell.ToString(),如果这样做就会为每个参数都赋值一个string类型变量,执行时会报错
                                //所以这里在获取cell(单元格)值的时候要根据单元格的类型来获取值。

                                // pms[c - 1].Value = cell.ToString();
                                switch (cell.CellType)
                                {
                                    case CellType.BLANK:
                                        //无论单元格是null,还是CellType.BLANK,都向数据库中插入一个Null值。
                                        pms[c - 1].Value = DBNull.Value;
                                        break;
                                    case CellType.NUMERIC:
                                        pms[c - 1].Value = cell.NumericCellValue;
                                        break;
                                    case CellType.STRING:
                                        pms[c - 1].Value = cell.StringCellValue;
                                        break;
                                }
                            }
                            else
                            {
                                //单元格为空,向数据库中插入空值,必须使用DBNull.Value
                                pms[c - 1].Value = DBNull.Value;
                            }
                        }

                        #endregion


                        //执行Sql语句实现导入
                        if (pms[4].Value != DBNull.Value)
                        {
                            var d = (double)pms[4].Value;
                            pms[4].SqlDbType = SqlDbType.DateTime;
                            pms[4].Value = DateTime.FromOADate(d);
                        }
                        SqlHelper.ExecuteNonQuery(sql, CommandType.Text, pms);
                    }

                }
            }
            MessageBox.Show("ok");



            //2.操作数据库,将Excel中的数据插入到数据库中。
        }
    }

    public class Person
    {
        public string Name
        {
            get;
            set;
        }
        public int Age
        {
            get;
            set;
        }
        public string Email
        {
            get;
            set;
        }

    }
}

  

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

posted @ 2013-11-10 10:15  那个故人  阅读(836)  评论(0)    收藏  举报