【C#常用方法】2.DataTable(或DataSet)与Excel文件之间的导出与导入(使用NPOI)

2022-10-13,,,,

datatable与excel之间的互导

1.项目添加npoi的引用 


 

  • npoi项目简介:

  npoi是一个开源的c#读写excel、word等微软ole2组件文档的项目,特点是可以在没有安装office的情况下对word或excel文档进行读写操作。并且对老版本office(2003-)与新版本office(2007+)均有较好的支持。npoi功能非常强大,可以操作excel或word文档的各个细节,如果你对npoi想进行细致的学习,淘宝上有专门有书来讲npoi,当然也可以访问npoi的官方网站查看他们的文档与demo。

  • 关于excel扩展名.xls与.xlsx简介:

  .xls是excel2003及以前的版本所保存的文件格式,老版本及新版本的excel对其均可兼容,.xlsx是excel2007及以后的excel版本所默认保存的文件格式,这种格式只能被excel2007及以后的版本所兼容,老版本excel无法打开。

  • npoi项目的引用:

  使用visualstudio,打开nuget包管理器,搜索npoi,并添加到当前项目。

  

 

 

 

2.将excel文件导入到dataset(datatable)中


 

  因为一个excel文件可以有多个sheet页,所以c#方法最好使用与excel文档结构相对应的dataset类,即将dataset(可以包含多个datatable)导出为excel,dataset中的每个datatabel对应一个excel中的sheet页。

  

  方法解释:此方法将一个excel文件导入为一个dataset,excel中每个sheet页都会生成一个datatable存放在导入的dataset中,并且每个datatable的tablename与每个sheet的sheetname一一对应。参数isfirstlinecolumnname用来表示excel文件各表第一行是否为表头。

  代码如下:

        /// <summary>
        /// 读取execl数据到datatable(dataset)中
        /// </summary>
        /// <param name="filepath">指定execl文件路径</param>
        /// <param name="isfirstlinecolumnname">设置第一行是否是列名</param>
        /// <returns>返回一个datatable数据集</returns>
        public static dataset exceltodataset(string filepath, bool isfirstlinecolumnname)
        {
            dataset dataset = new dataset();
            int startrow = 0;
            try
            {
                using (filestream fs = file.openread(filepath))
                {
                    iworkbook workbook = null;
                    // 如果是2007+的excel版本
                    if (filepath.indexof(".xlsx") > 0)
                    {
                        workbook = new xssfworkbook(fs);
                    }
                    // 如果是2003-的excel版本
                    else if (filepath.indexof(".xls") > 0)
                    {
                        workbook = new hssfworkbook(fs);
                    }
                    if (workbook != null)
                    {
                        //循环读取excel的每个sheet,每个sheet页都转换为一个datatable,并放在dataset中
                        for (int p = 0; p < workbook.numberofsheets; p++)
                        {
                            isheet sheet = workbook.getsheetat(p);
                            datatable datatable = new datatable();
                            datatable.tablename = sheet.sheetname;
                            if (sheet != null)
                            {
                                int rowcount = sheet.lastrownum;//获取总行数
                                if (rowcount > 0)
                                {
                                    irow firstrow = sheet.getrow(0);//获取第一行
                                    int cellcount = firstrow.lastcellnum;//获取总列数

                                    //构建datatable的列
                                    if (isfirstlinecolumnname)
                                    {
                                        startrow = 1;//如果第一行是列名,则从第二行开始读取
                                        for (int i = firstrow.firstcellnum; i < cellcount; ++i)
                                        {
                                            icell cell = firstrow.getcell(i);
                                            if (cell != null)
                                            {
                                                if (cell.stringcellvalue != null)
                                                {
                                                    datacolumn column = new datacolumn(cell.stringcellvalue);
                                                    datatable.columns.add(column);
                                                }
                                            }
                                        }
                                    }
                                    else
                                    {
                                        for (int i = firstrow.firstcellnum; i < cellcount; ++i)
                                        {
                                            datacolumn column = new datacolumn("column" + (i + 1));
                                            datatable.columns.add(column);
                                        }
                                    }

                                    //填充行
                                    for (int i = startrow; i <= rowcount; ++i)
                                    {
                                        irow row = sheet.getrow(i);
                                        if (row == null) continue;

                                        datarow datarow = datatable.newrow();
                                        for (int j = row.firstcellnum; j < cellcount; ++j)
                                        {
                                            icell cell = row.getcell(j);
                                            if (cell == null)
                                            {
                                                datarow[j] = "";
                                            }
                                            else
                                            {
                                                //celltype(unknown = -1,numeric = 0,string = 1,formula = 2,blank = 3,boolean = 4,error = 5,)
                                                switch (cell.celltype)
                                                {
                                                    case celltype.blank:
                                                        datarow[j] = "";
                                                        break;
                                                    case celltype.numeric:
                                                        short format = cell.cellstyle.dataformat;
                                                        //对时间格式(2015.12.5、2015/12/5、2015-12-5等)的处理
                                                        if (format == 14 || format == 31 || format == 57 || format == 58)
                                                            datarow[j] = cell.datecellvalue;
                                                        else
                                                            datarow[j] = cell.numericcellvalue;
                                                        break;
                                                    case celltype.string:
                                                        datarow[j] = cell.stringcellvalue;
                                                        break;
                                                }
                                            }
                                        }
                                        datatable.rows.add(datarow);
                                    }
                                }
                            }
                            dataset.tables.add(datatable);
                        }

                    }
                }
                return dataset;
            }
            catch (exception)
            {
                return null;
            }
        }    

 

3.将dataset(datatable)导出为一个excel文件


 

  代码解释:我们可以将要导出的datatable都放入一个dataset中,将dataset导出为excel文件,方法参数outpath用来传入导出excel文件的路径,路径可以加excel的扩展名(.xls或.xlsx),也可以不加,不加默认导出excel文件扩展名为.xls。  

        /// <summary>
        /// 将datatable(dataset)导出到execl文档
        /// </summary>
        /// <param name="dataset">传入一个dataset</param>
        /// <param name="outpath">导出路径(可以不加扩展名,不加默认为.xls)</param>
        /// <returns>返回一个bool类型的值,表示是否导出成功</returns>
        /// true表示导出成功,flase表示导出失败
        public static bool datatabletoexcel(dataset dataset, string outpath)
        {
            bool result = false;
            try
            {
                if (dataset == null || dataset.tables == null || dataset.tables.count == 0 || string.isnullorempty(outpath))
                    throw new exception("输入的dataset或路径异常");
                int sheetindex = 0;
                //根据输出路径的扩展名判断workbook的实例类型
                iworkbook workbook = null;
                string pathextensionname = outpath.trim().substring(outpath.length - 5);
                if (pathextensionname.contains(".xlsx"))
                {
                    workbook = new xssfworkbook();
                }
                else if(pathextensionname.contains(".xls"))
                {
                    workbook = new hssfworkbook();
                }
                else
                {
                    outpath = outpath.trim() + ".xls";
                    workbook = new hssfworkbook();
                }
                //将dataset导出为excel
                foreach (datatable dt in dataset.tables)
                {
                    sheetindex++;
                    if (dt != null && dt.rows.count > 0)
                    {
                        isheet sheet = workbook.createsheet(string.isnullorempty(dt.tablename) ? ("sheet" + sheetindex) : dt.tablename);//创建一个名称为sheet0的表
                        int rowcount = dt.rows.count;//行数
                        int columncount = dt.columns.count;//列数

                        //设置列头
                        irow row = sheet.createrow(0);//excel第一行设为列头
                        for (int c = 0; c < columncount; c++)
                        {
                            icell cell = row.createcell(c);
                            cell.setcellvalue(dt.columns[c].columnname);
                        }

                        //设置每行每列的单元格,
                        for (int i = 0; i < rowcount; i++)
                        {
                            row = sheet.createrow(i + 1);
                            for (int j = 0; j < columncount; j++)
                            {
                                icell cell = row.createcell(j);//excel第二行开始写入数据
                                cell.setcellvalue(dt.rows[i][j].tostring());
                            }
                        }
                    }
                }
                //向outpath输出数据
                using (filestream fs = file.openwrite(outpath))
                {
                    workbook.write(fs);//向打开的这个xls文件中写入数据
                    result = true;
                }
                return result;
            }
            catch (exception ex)
            {
                return false;
            }
        }
    }

 

4.上面两个方法的使用方法 


 

  将上面两个方法都定义在excelhelper类中,使用如下代码使用:

        dataset set = excelhelper.exceltodatatable("test.xlsx", true);//excel导入
        bool b = excelhelper.datatabletoexcel(set, "test2.xlsx");//导出excel

 

《【C#常用方法】2.DataTable(或DataSet)与Excel文件之间的导出与导入(使用NPOI).doc》

下载本文的Word格式文档,以方便收藏与打印。