c#与NPOI

简介

操作指南
某些API参考
视频讲解
完整代码
1、简介

  • NPOI是源于一个用于读取xls,doc,ppt文档的POI 项目,POI是Java项目,后面因为有.Net的市场,于是将POI移植到.Net上。
  • Npoi 可以在没有安装Office 的情况写 对 Word 或 Excel 文档进行读写操作。另外一种方法是使用.NET自带的excel API,但是这种方法需要运行环境安装微软的excel才行。
  • NPOI尤其适合在服务器端生成数据文件!因为服务器一般是不安装office这么庞大的办公软件的

2、名词介绍

  • 整个Excel:工作簿
  • Sheet页:页签,一个工作簿中可以包含多个Sheet页
  • 表格: 对应一个Sheet
  • 行、列、单元格

3、C#中的常规操作:

  • 导出一个Excel:其实就是要生成一个Excel文件,Excel文件对应的文件流
  • 导入一个Excel:读取一个文件,读取文件流,需要从文件流中读取我们需要的各种数据,解析Excel的数据

4、安装
在这里插入图片描述

5、细节

  • 里面的行列都是从0开始计数的,也即第一行和第一列都是0(但是表格中写的是1开始)
  • 注意操作每个步骤的时候要创建、写入、然后关闭文件流

生成

在这里插入图片描述

在这里插入图片描述

主函数

        private void creatBut_Click(object sender, EventArgs e)
        {
    
    
            IWorkbook workbook = ExcelOperationHelper.CreateExcelWorkbook();
            FileStream file = new FileStream("C:\\StudyData_ele\\testnew\\NPOI\\Test.xls", FileMode.Create);
            workbook.Write(file);
            file.Close();
        }

类库

        /// <summary>
        /// 创建一个ExcelWorkbook
        /// </summary>
        /// <returns></returns>
        public static IWorkbook CreateExcelWorkbook()
        {
    
    
            HSSFWorkbook _Workbook = new HSSFWorkbook();
            ISheet sheet1 = _Workbook.CreateSheet("Sheet1");
            //创建第一行
            {
    
    
                IRow Row0 = sheet1.CreateRow(0);
                MessageBox.Show("row:" + Row0);

                ICell cell = Row0.CreateCell(0);
                cell.SetCellValue("姓名");
                ICell cel2 = Row0.CreateCell(1);
                cel2.SetCellValue("成绩");
            }
            //创建第二行
            {
    
    
                IRow Row1 = sheet1.CreateRow(1);

                ICell cell = Row1.CreateCell(0);
                cell.SetCellValue("王刚");
                ICell cel2 = Row1.CreateCell(1);
                cel2.SetCellValue("70");
            }
            return _Workbook;
        }

using

using NPOI.OpenXmlFormats.Spreadsheet;
using NPOI.SS.Formula.Functions;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;

获取数据

在这里插入图片描述
在这里插入图片描述

读取Excel

      //读取 Excel 文件
        public IWorkbook ReadWorkbook = null;
        public string FilePath = "E:\\StudyData_ele\\testnew\\NPOI\\Test.xls";//输错地址会报错
        private void read_Click(object sender, EventArgs e)
        {
    
    
            // 获取扩展名
            string ExtensionName = System.IO.Path.GetExtension(FilePath);
            // 文件流
            FileStream FileStream = new FileStream(FilePath, FileMode.Open, FileAccess.ReadWrite);
            // 把xls写入workbook中 2003版本
            if (ExtensionName.Equals(".xls"))
            {
    
    
                ReadWorkbook = new HSSFWorkbook(FileStream);
            }
            // 把xlsx 写入workbook中 2007版本
            else if (ExtensionName.Equals(".xlsx"))
            {
    
    
                ReadWorkbook = new XSSFWorkbook(FileStream);
            }
            else
            {
    
    
                ReadWorkbook = null;
            }
            FileStream.Close();
        }

读取sheet

      //获取 Sheet
        public List<ISheet> Sheets = null;
        ISheet sheet1;
        ISheet sheet2;
        private void button1_Click(object sender, EventArgs e)
        {
    
    
            // 获取所有sheet
            Sheets = new List<ISheet>();
            var SheetCount = ReadWorkbook.NumberOfSheets;
            for (int i = 0; i < SheetCount; i++)
            {
    
    
                Sheets.Add(ReadWorkbook.GetSheetAt(i));
            }

            //获取单个sheet
            //1、通过sheetName获取sheet
             sheet1 = ReadWorkbook.GetSheet("Sheet1");

            // 2、a通过Sheet 名获取 Sheet数组对应的下标;
            int sheetIndex = ReadWorkbook.GetSheetIndex("光照度");
            //    b 通过 Sheet下标获取 对应的 Sheet 数据
             sheet2 = ReadWorkbook.GetSheetAt(sheetIndex);

        }

读取sheet数据

        //读取 Sheet 数据
        private void button2_Click(object sender, EventArgs e)
        {
    
    
            if (Sheets == default)
            {
    
    
                return ;
            }
            IRow row;
            // 1. 获取行数
            var rowCount = sheet1.LastRowNum;
            //因为Excel表中是从1开始的,而这个是从0开始的,所以行数比Excel中的行数值少1
            log.SaveLog("rowCount:" + rowCount);

            // 从第2行(下标为1)开始获取数据,第一行是表头
            // 如果从第一行开始,则i=0就可以了
            for (int i = 1; i <= rowCount; i++)
            {
    
    
                //var dataTable = new DataTable_Model();
                // 获取具体行
                row = sheet1.GetRow(i);
                //都打印了这个row:NPOI.HSSF.UserModel.HSSFRow
                log.SaveLog("row:"+row);
                if (row != null)
                {
    
    
                    // 2. 获取行对应的列数
                    var column = row.LastCellNum;
                    //计数到最后出现数据的那一列
                    log.SaveLog("column:" + column);
                    for (int j = 0; j < column; j++)
                    {
    
    
                        // 3. 获取某行某列对应的单元格数据
                        var cellValue = row.GetCell(j).ToString();
                        // 4. 输出单元格数据        
                        log.SaveLog(cellValue + " ");
                    }
                }
            }
        }

写入数据

在这里插入图片描述

在这里插入图片描述

修改某个数据

使用该方法,xls可以正常使用,但是xlsx不知道怎么使用玩了无法打开,但是确实可以更改了,因为我再点击插入图片就可以了。不知道为什么,但是另存为就不会出问题。可以打开

        //修改单元格数据
        private void button3_Click(object sender, EventArgs e)
        {
    
    
            // 创建文件流
            FileStream fsWrite = new FileStream(FilePath, FileMode.Open, FileAccess.Write);
            try
            {
    
    
                // 1. 通过Sheet名 获取对应的ISeet--其中 ReadWorkbook 为读取Excel文档时获取
                var sheet = ReadWorkbook.GetSheet("光照度");
                // 2. 获取行数
                int rowCount = sheet.LastRowNum;
                for (int i = 0; i < rowCount; i++)
                {
    
    
                    // 3. 获取行对应的列数
                    int columnount = sheet.GetRow(i).LastCellNum;
                    for (int j = 0; j < columnount; j++)
                    {
    
    
                        // 4. 获取某行某列对应的单元格数据
                        // 其中第一行设计为表头,故i+1,从第二行开始,这里可以自己定义
                        var sheetCellValue = sheet.GetRow(i + 1).GetCell(j);
                        if (sheetCellValue == null)
                        {
    
    
                            //创建第一行
                            {
    
    
                                IRow row = sheet.GetRow(i + 1);//这样就是插入了
                                // 为第一列设置文本 这里的列也是从0开始的
                                row.CreateCell(j).SetCellValue("空");
                            }
                        }
                        //碰到a改成这样 碰到aa也是不变的
                        else if (sheetCellValue.ToString() == "a")
                        {
    
    
                            sheetCellValue.SetCellValue("原本为a" );
                        }
                        else
                        {
    
    
                            //如果某个内容为空 还用了下面这句话 那么就会报错:
                            //未将对象引用设置到对象的实例
                            // 5. 向单元格传值,以覆盖对应的单元格数据
                            sheetCellValue.SetCellValue(sheetCellValue + "更新");
                        }

                    }
                }
                // 6. 对 Workbook 的修改写入文件流,对文件进行相应操作
                // 6. 对 Workbook 的修改写入文件流,对文件进行相应操作
                FileStream file = new FileStream("C:\\log\\new.xlsx", FileMode.CreateNew, FileAccess.Write);//这是要保存的地址
                ReadWorkbook.Write(file);
                ReadWorkbook.Write(fsWrite);
                file.Close();


            }
            catch (Exception ex)
            {
    
    
                throw ex;
            }
            finally
            {
    
    
                // 7. 关闭文件流:报不报错都关闭
                fsWrite.Close();
            }
        }

插入一行

      private void button4_Click(object sender, EventArgs e)
        {
    
    
            // 创建文件流
            FileStream fsWrite = new FileStream(FilePath, FileMode.Open, FileAccess.Write);
            try
            {
    
    
                // 1. 通过Sheet名 获取对应的ISeet--其中 ReadWorkbook 为读取Excel文档时获取
                var sheet = ReadWorkbook.GetSheet("光照度");
                // 2. 获取行数
                int rowCount = sheet.LastRowNum;
                //MessageBox.Show(rowCount.ToString());
                // 3、获取列数 列数也是从0开始的
                int columnount =3;            
                //创建第一行
                {
    
    
                    IRow Row0 = sheet.CreateRow(rowCount+1);

                    
                    for (int j = 0; j < columnount; j++)
                    {
    
    
                        ICell cell = Row0.CreateCell(j);
                        cell.SetCellValue("111");
                    }

                }
     
                
                // 6. 对 Workbook 的修改写入文件流,对文件进行相应操作
                ReadWorkbook.Write(fsWrite);
            }
            catch (Exception ex)
            {
    
    
                throw ex;
            }
            finally
            {
    
    
                // 7. 关闭文件流:报不报错都关闭
                fsWrite.Close();
            }
        }
    }

插入图片

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

        //插入图片 注意要用xlsx格式
        private void button5_Click(object sender, EventArgs e)
        {
    
    
            // 创建文件流
            FileStream fsWrite = new FileStream(FilePath, FileMode.Open, FileAccess.Write);

            // 第一步:读入图片数据
            byte[] bytes = System.IO.File.ReadAllBytes(@"E:\StudyData_ele\testnew\NPOI\12.png");
            //图片大小(不是图片占用字节)
            //MessageBox.Show("bytes.Length:" + bytes.Length.ToString());

            // 2.向Excel添加图片,获取到图片索引
            int picIdx = ReadWorkbook.AddPicture(bytes, PictureType.PNG);
            // 3.构建Excel图像
            sheet1 = ReadWorkbook.GetSheet("Sheet1");
            // 获取第二行,第一行是标题
            //IRow row = sheet1.CreateRow(1);//这个是新创建一行 原本第二行都没有了
            IRow row = sheet1.GetRow(1);//这样就是插入了
            // 为第一列设置文本 这里的列也是从0开始的
            row.CreateCell(1).SetCellValue("测试图片");
            // 设置行高和列宽
            //sheet1.SetColumnWidth(1, 413 * 32);   // Excel的宽将1个像素分为32份
            //row.Height = (short)(891 * 16);      // Excel的高将1个像素分为16份

            var drawing = sheet1.CreateDrawingPatriarch();
            // 4.确定图像的位置
            // new XSSFClientAnchor(int dx1, int dy1, int dx2, int dy2, int col1, int row1, int col2, int row2)
            // 前四个参数是单元格内的偏移量,这里需要填满整个单元格所以不设置。
            // col1,row1表示图片的左上角在哪个单元格的左上角;col2,row2表示图片的右下角在哪个单元格的左上角
            XSSFClientAnchor anchor = new XSSFClientAnchor(0, 0, 0, 0, 1, 1, 4, 4);
            // 5.将图片设置到上面的位置中
            drawing.CreatePicture(anchor, picIdx);

            // 6. 对 Workbook 的修改写入文件流,对文件进行相应操作
            ReadWorkbook.Write(fsWrite);

            // 7. 关闭文件流:报不报错都关闭
            fsWrite.Close();
        }

另存为

在这里插入图片描述

            // 创建文件流 这个是打开的源文件
            FileStream fsWrite = new FileStream(FilePath, FileMode.Open, FileAccess.Write);
			/*
					.................
			*/
            // 6. 对 Workbook 的修改写入文件流,对文件进行相应操作
            FileStream file = new FileStream("C:\\log\\new.xlsx", FileMode.CreateNew, FileAccess.Write);//这是要保存的地址
            ReadWorkbook.Write(file);

            // 7. 关闭文件流:报不报错都关闭
            file.Close();
            fsWrite.Close();

报错

Wrong Local header signature: 0xE011CFD0

文件应该是直接创建为后缀xlsx,而不是创建完成后改为这个。这样就会报错了

猜你喜欢

转载自blog.csdn.net/chengcao123/article/details/130682456