NPOI 操作Excel学习总结

NPOI读写Excel

http://www.cnblogs.com/luxiaoxun/p/3374992.html

1、整个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.html
Npoi 简介

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文件作为输入,运行结果为:
========
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值