【C#常用方法】2.DataTable(或DataSet)与Excel文件之间的导出与导入(使用NPOI)
程序员文章站
2023-11-08 17:20:16
DataTable与Excel之间的互导 1.项目添加NPOI的引用 NPOI项目简介: NPOI是一个开源的C#读写Excel、WORD等微软OLE2组件文档的项目,特点是可以在没有安装Office的情况下对Word或Excel文档进行读写操作。并且对老版本Office(2003-)与新版本Off ......
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