zoukankan      html  css  js  c++  java
  • 使用NPOI操作Excel

      Excel表格是工作中经常用到的数据整理工具。有时候我们可能会需要把数据库中的数据导出到Excel文件中或者将Excel文件中的数据导入到数据库,如果我们使用手动方式去操作,既费时又费力,这种大量重复的工作我们可以完全使用代码编程来完成。在.net下有多种方法可以操作Excel表格,如引用com组件:Microsoft.Office.Interop.Excel.dll采用OleDB读取Excel文件,开源的EPPlus(.xlsx)等。这里为大家介绍下一使用开源的NPOI(.xls)来进行数据库的操作。

      一、什么是NPOI

      1.NPOI是指构建在POI 3.x版本之上的一个程序,NPOI可以在没有安装Office的情况下对Word或Excel文档进行读写操作。

      2.开源的项目,可以完全免费使用。

      3.NPOI支持导出Excel和导入Excel,并能“理解”OLE2文档结构。

      官网下载链接:http://npoi.codeplex.com/documentation

      二、简介NOPI

      NPOI中操作Excel常用的的类和方法

    1.工作簿HSSFWorkbook

     描述工作簿的类:IWorkbook(接口),HSSFWorkbook(具体的实现类,一个HSSFWorkbook就表示了一个Excel文件,读写Excel文件都需要首先创建这个类的实例对象)
        构造方法,无参数表示创建一个新的工作本,可以接受一个流对象用于打开一个现有的工作簿
        方法CreateSheet(索引):创建指定索引的sheet对象
        方法GetSheetAt(索引):根据索引获取sheet对象
        方法CreateCellStyle();创建单元格样式对象
        方法CreateFont():创建字体对象
        方法Write(stream):将工作簿输出到流中
    2.工作表HSSFSheet

     描述工作表的类ISheet(接口),HSSFSheet(具体实现类)描述工作表的类ISheet(接口),HSSFSheet(具体实现类)
        方法CreateRow(索引):创建指定索引的行
        方法GetRow(索引):根据索引获取行
        方法AddMergedRegion():设置合并区域,参数包括开始行索引,开始列索引,结束行索引,结束列索引
        方法SetColumnWidth(索引,宽度):设置指定列的宽度
        属性FirstRowNum、LastRowNum:获取第一行、最后一行的索引
    3.行对象HSSFRow
        方法CreateCell(索引):创建指定索引的列
        方法GetCell(索引):根据索引获取指定列
        属性HeightInPoints:指顶或获取高度
    4.单元格对象HSSFCell
        方法SetCellValue():设置单元格中的值
        属性***CellValue:获取单元格中指定类型的值如果不匹配会抛出异常
        属性CellStyle:获取或设置单元格样式
    5.单元格样式对象HSSFCellStyle
        方法SetFont(字体对象):设置字体样式
        属性Alignment:水平对齐,1左,2中,3右
    6.字体对象HSSFFont
        属性FontHeightInPoints:获取或设置字体大小
        属性Boldweight:获取或设置字体加粗

       三、从数据库导出数据到Excel

      1.引入dll文件(2.0和4.0的两个版本可以根据需要选用)

      2.代码

    using System;
    using System.Collections.Generic;
    using System.Data.SqlClient;
    using System.IO;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using NPOI.HSSF.UserModel;
    using NPOI.SS.UserModel;
    
    namespace NPOITesst
    {
        class Program
        {
            static void Main(string[] args)
            {
                //从数据库中读取数据
                List<PhoneNum> phoneNums = GetAllPhoneNum();
    
                //保存到Excel中
                SaveToExcel(phoneNums);
                
    
                Console.WriteLine("OK!");
                Console.Read();
            }
    
            static List<PhoneNum> GetAllPhoneNum()
            {
                //数据库的简单查询,可以使用EF或者其他的微型ORM框架(代码很简单,就几行)
                List<PhoneNum> phoneNumList = new List<PhoneNum>();
                string constr = "Data source=localhost;Initial catalog=PhoneNumManager;Integrated security=true";
                string sql = "select pn.*,pt.ptName from PhoneNum as pn inner join PhoneType as pt on pn.pTypeId=pt.ptId";
                using (SqlConnection con = new SqlConnection(constr))
                {
                    using (SqlCommand command = new SqlCommand(sql, con))
                    {
                        con.Open();
                        using (SqlDataReader reader = command.ExecuteReader())
                        {
                            if (reader.HasRows)
                            {
                                while (reader.Read())
                                {
                                    PhoneNum model = new PhoneNum
                                    {
                                        PID = reader.GetInt32(0),
                                        PType = new PhoneType()
                                        {
                                            PTID = reader.GetInt32(1),
                                            PTName = reader.GetString(5)
                                        },
                                        PName = reader.GetString(2),
                                        PCellPhone = reader.GetString(3),
                                        PHomePhone = reader.GetString(4)
                                    };
                                    phoneNumList.Add(model);
                                }
                            }
                        }
                    }
                }
                return phoneNumList;
            }
    
            static void SaveToExcel(List<PhoneNum> phoneNumList)
            {
                //1.创建工作簿对象,
                IWorkbook workBook = new HSSFWorkbook();
    
                //2.在工作簿中创建工作表对象
                ISheet sheet = workBook.CreateSheet("PhoneNum");
    
                //第一行列名
                IRow firstRow = sheet.CreateRow(0);
                firstRow.CreateCell(0).SetCellValue("序号");
                firstRow.CreateCell(1).SetCellValue("姓名");
                firstRow.CreateCell(2).SetCellValue("手机");
                firstRow.CreateCell(3).SetCellValue("固话");
                firstRow.CreateCell(4).SetCellValue("备注");
    
                //剩下的数据
                for (int i = 0; i < phoneNumList.Count; i++)
                {
                    IRow row = sheet.CreateRow(i + 1);
                    row.CreateCell(0).SetCellValue(phoneNumList[i].PID);
                    row.CreateCell(1).SetCellValue(phoneNumList[i].PName);
                    row.CreateCell(2).SetCellValue(phoneNumList[i].PCellPhone);
                    row.CreateCell(3).SetCellValue(phoneNumList[i].PHomePhone);
                    row.CreateCell(4).SetCellValue(phoneNumList[i].PType.PTName);
                }
    
                //文件流写入
                using (FileStream fw = File.Open("PhoneNum.xls", FileMode.OpenOrCreate, FileAccess.Write))
                {
                    workBook.Write(fw);
                }
    
            }
        }
    
        class PhoneNum
        {
            public int PID { get; set; }
            public string PName { get; set; }
            public string PCellPhone { get; set; }
            public string PHomePhone { get; set; }
            public PhoneType PType { get; set; }
        }
    
        class PhoneType
        {
            public int PTID { get; set; }
            public string PTName { get; set; }
        }
    }
    View Code

    结果图片:

      四、从Excel导入数据到数据库

      直接上代码:

      

    class ExcelToDB
        {
            public static List<Person> GetAllDataFromExcel(string excelPath)
            {
                List<Person> personList = new List<Person>();
                //1.创建IWorkbook
                using (FileStream fr = File.OpenRead(excelPath))
                {
                    IWorkbook wkbook = new XSSFWorkbook(fr);
                    //遍历每个Sheet
                    for (int i = 0; i < wkbook.NumberOfSheets; i++)
                    {   //获取每个Sheet对象
                        ISheet sheet = wkbook.GetSheetAt(i);
    
                        //获取每个工作表中的行
                        //第一行是列名舍去,从第二行开始读取
                        for (int j = 1; j <= sheet.LastRowNum; j++)
                        {
                            IRow row = sheet.GetRow(j);
                            Person model = new Person
                            {
                                Name = row.GetCell(0).ToString(),
                                Age = Convert.ToInt32(row.GetCell(1).ToString())
                            };
    
                            personList.Add(model);
                        }
                    }
                }
    
                return personList;
            }
    
            public static void InsertToDB(List<Person> personList)
            {
                string constr = "Data source=localhost;Initial catalog=DataModel;Integrated security=true";
                string sql = "insert into Person values(@name,@age)";
    
                foreach (var person in personList)
                {
                    using (SqlConnection con = new SqlConnection(constr))
                    {
                        using (SqlCommand command = new SqlCommand(sql, con))
                        {
    
                            con.Open();
                            SqlParameter[] pms = new SqlParameter[]
                            {
                                new SqlParameter("@name", SqlDbType.NVarChar, 50) {Value = person.Name},
                                new SqlParameter("@age", SqlDbType.Int) {Value = person.Age},
                            };
                            command.Parameters.AddRange(pms);
                            command.ExecuteNonQuery();
                        }
                    }
                }
            }
        }
    
        class Person
        {
            public int AutoId { get; set; }
            public string Name { get; set; }
            public int Age { get; set; }
        }
    View Code

      五、其他的常见问题

      1.空值的问题

      在SqlServer数据库中,空值读取出来后是DBNull,这时可以先通过IsDBNull方法判断是不是DBNull,然后结合可空值类型与NOPI提供的CellType.BLANK结合来进行Excel写入(currentRow.CreateCell(i).SetCellType(CellType.BLANK);)。同理,读取Excel时,应该先判断是否是空值currentCell.CellType==CellType.BLANK,再根据情况向数据库中插入DBNull还是非空值。

      2.单元格数据格式样式问题

      有些类型的数据直接从Excel读取或者向Excel插入时需要做特殊的处理,如日期格式的数据,向Excel插入时,需要设置单元格样式

      {

        ICellStyle cellStyle = wk.CreateCellStyle();
                  cellStyle.DataFormat=HSSFDataFormat.GetBuiltinFormat("mm/dd/yyyy hh:mm:ss");

        ICell cell = currentRow.CreateCell(5);
                   cell.CellStyle = cellStyle;
                   cell.SetValue((DateTime)lockDate);   

      }

      从Excel读取日期数据时,需要这样处理

      DateTime.FromOADate(currentCell.NumericCellValue);

      类似的细节还有很多,遇到的时候可以参考NOPI文档:http://npoi.codeplex.com/documentation

      

  • 相关阅读:
    android ksoap2 访问webservice,连续两次调用时,第二次调用异常(转)
    iOS Programming – 触摸事件处理 (转)
    iPhone的解锁、越狱、激活、固件等等是什么意思,有什么分别?(转)
    pb中 执行动态sql
    Java的中文字体
    fastreport一些使用方法
    网页数据抓取
    base64
    TSelect
    解决DLL包组织的项目运行报 a class named Txxx exists
  • 原文地址:https://www.cnblogs.com/phasd/p/7486225.html
Copyright © 2011-2022 走看看