继上一篇文章中把操作office的组件换成别的组件,使用NPOI是在不用安装office的情况下也可以操作excel;
一、安装包:
二:导出Excel:
/// <summary> /// 导出到Excel文件中 /// </summary> /// <param name="dt">表格</param> /// <param name="fileType">文件类型</param> /// <param name="isShowExcle">是否打开文件</param> /// <returns></returns> public static bool DataTableToExcel(DataTable dt, String fileType, bool isShowExcle, string foldPath) { bool result = false; IWorkbook workbook = null; FileStream fs = null; IRow row = null; ISheet sheet = null; ICell cell = null; try { string filepath = foldPath + @"" + fileType + "_" + DateTime.Now.ToString("G").Replace(" ", "_").Replace(@"/", "_").Replace(":", "") + ".xlsx"; if (dt != null && dt.Rows.Count > 0) { //workbook = new HSSFWorkbook();//导出.xls workbook = new XSSFWorkbook();//导出.xlsx sheet = workbook.CreateSheet("Sheet0");//创建一个名称为Sheet0的表 int rowCount = dt.Rows.Count;//行数 int columnCount = dt.Columns.Count;//列数 //设置列头 row = sheet.CreateRow(0);//excel第一行设为列头 for (int c = 0; c < columnCount; c++) { 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++) { cell = row.CreateCell(j);//excel第二行开始写入数据 cell.SetCellValue(dt.Rows[i][j].ToString()); } } using (fs = File.OpenWrite(filepath)) { workbook.Write(fs);//向打开的这个xls文件中写入数据 result = true; } } if (isShowExcle) { System.Diagnostics.Process.Start(filepath); } return result; } catch (Exception ex) { if (fs != null) { fs.Close(); } return false; } }
这里用的是winform,所以在导出时也可以让用户自行选择导出文件保存路径:
数据库中查出来的数是List<T>类型,而这里是DataTable导出到Excel,所有需要转一下
#region List<T>转DataSet public static DataSet ConvertToDataSet<T>(List<T> list) { try { if (list == null || list.Count <= 0) { return null; } DataSet ds = new DataSet(); DataTable dt = new DataTable(typeof(T).Name); DataColumn column; DataRow row; System.Reflection.PropertyInfo[] myPropertyInfo = typeof(T).GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance); foreach (T t in list) { if (t == null) { continue; } row = dt.NewRow(); for (int i = 0, j = myPropertyInfo.Length; i < j; i++) { System.Reflection.PropertyInfo pi = myPropertyInfo[i]; string name = pi.Name; if (dt.Columns[name] == null) { column = new DataColumn(name, pi.PropertyType); dt.Columns.Add(column); } row[name] = pi.GetValue(t, null); } dt.Rows.Add(row); } ds.Tables.Add(dt); return ds; } catch (Exception er) { throw er; } } #endregion
DataSet result = ConvertToDataSet<T>(list);
var t = result.Tables[0];
定义:
/文件保存路径 FolderBrowserDialog dialog = new FolderBrowserDialog(); dialog.Description = "请选择要保存的文件路径"; string foldPath = string.Empty; if (dialog.ShowDialog() == DialogResult.OK) { foldPath = dialog.SelectedPath; } else { MessageBox.Show("未选择保存路径!"); return; } var UpN = new UnitPrn(); UpN.cblgcode = keyWordBldg; var Result_Ienumberable = await DbServices.SearchSameBldgAsync(UpN); var list = new List<UnitPrn>(Result_Ienumberable); DataSet result = ConvertToDataSet<UnitPrn>(list); var t = result.Tables[0]; //生成Excel Status.Text = "导出文件中.........."; if (DataTableToExcel(t, "Bldg", true, foldPath)) Status.Text = "成功导出文件!"; else { return; }
三:从Excel中读取数据
因为要读取Excel中的数据做批量修改,所以读取出来的数据用DataTable来接收:
定义:
/// <summary> /// 将excel导入到datatable 需直接定义.xlsx文件,不能用其他格式的文件改成.xlsx格式导入 /// </summary> /// <param name="filePath">excel路径</param> /// <param name="isColumnName">第一行是否是列名</param> /// <returns>返回datatable</returns> public static DataTable ExcelToDataTable(string filePath, bool isColumnName) { DataTable dataTable = null; FileStream fs = null; DataColumn column = null; DataRow dataRow = null; IWorkbook workbook = null; ISheet sheet = null; IRow row = null; ICell cell = null; int startRow = 0; try { using (fs = File.OpenRead(filePath)) { // 2007版本 if (filePath.IndexOf(".xlsx") > 0) workbook = new XSSFWorkbook(fs); // 2003版本 else if (filePath.IndexOf(".xls") > 0) workbook = new HSSFWorkbook(fs); if (workbook != null) { sheet = workbook.GetSheetAt(0);//读取第一个sheet,当然也可以循环读取每个sheet dataTable = new DataTable(); if (sheet != null) { int rowCount = sheet.LastRowNum;//总行数 if (rowCount > 0) { IRow firstRow = sheet.GetRow(0);//第一行 int cellCount = firstRow.LastCellNum;//列数 //构建datatable的列 if (isColumnName) { startRow = 1;//如果第一行是列名,则从第二行开始读取 for (int i = firstRow.FirstCellNum; i < cellCount; ++i) { cell = firstRow.GetCell(i); if (cell != null) { if (cell.StringCellValue != null) { column = new DataColumn(cell.StringCellValue); dataTable.Columns.Add(column); } } } } else { for (int i = firstRow.FirstCellNum; i < cellCount; ++i) { column = new DataColumn("column" + (i + 1)); dataTable.Columns.Add(column); } } //填充行 for (int i = startRow; i <= rowCount; ++i) { row = sheet.GetRow(i); if (row == null) continue; dataRow = dataTable.NewRow(); for (int j = row.FirstCellNum; j < cellCount; ++j) { 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); } } } } } return dataTable; } catch (Exception) { if (fs != null) { fs.Close(); } return null; } }
实现:
OpenFileDialog openFileDialog = new OpenFileDialog(); openFileDialog.Filter = "Files|*.xls;*.xlsx"; //设置打开文件的后缀类型 openFileDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyComputer);//打开我的电脑文件夹 if (openFileDialog.ShowDialog() == DialogResult.OK) { string filePathAndName = openFileDialog.FileName;//文件路径以及文件名 string fileName = System.IO.Path.GetFileName(filePathAndName); //获取文件名和扩展名 string fileEx = System.IO.Path.GetExtension(fileName);//获取文件的扩展名 //var table = ExcelToTable(filePathAndName); var table = ExcelToDataTable(filePathAndName, true); try { //遍历DataTable更新到数据库中; var upn = new UnitPrn(); for (int i = 0; i < table.Rows.Count; i++) { int a; bool b = int.TryParse(table.Rows[i][0].ToString(), out a); if (b) upn.id = a; else { MessageBox.Show("文件内容有误请重新检查再更改!"); return; } Status.Text = "导入文件更改中......"; upn.EnScopeName = table.Rows[i][1].ToString(); upn.ChScopeName = table.Rows[i][2].ToString(); upn.ScopeMarket = table.Rows[i][3].ToString(); upn.ChScopeMarket = table.Rows[i][4].ToString(); upn.cestcode = table.Rows[i][5].ToString(); upn.EnEstateName = table.Rows[i][6].ToString(); upn.EnPhaseName = table.Rows[i][7].ToString(); upn.EnAddress = table.Rows[i][8].ToString(); upn.ChEstateName = table.Rows[i][9].ToString(); upn.ChPhaseName = table.Rows[i][10].ToString(); upn.ChAddress = table.Rows[i][11].ToString(); upn.cblgcode = table.Rows[i][12].ToString(); upn.EnBuildingName = table.Rows[i][13].ToString(); upn.ChBuildingName = table.Rows[i][14].ToString(); upn.cuntcode = table.Rows[i][15].ToString(); upn.Flat = table.Rows[i][16].ToString(); upn.Floor = table.Rows[i][17].ToString(); upn.FlatCn = table.Rows[i][18].ToString(); upn.FloorCn = table.Rows[i][19].ToString(); upn.EnStreetName = table.Rows[i][20].ToString(); upn.ChStreetName = table.Rows[i][21].ToString(); upn.EnRoadName = table.Rows[i][22].ToString(); upn.ChRoadNameCn = table.Rows[i][23].ToString(); upn.PRN = table.Rows[i][24].ToString(); upn.Assessment = table.Rows[i][25].ToString(); upn.ContractAddr = table.Rows[i][26].ToString(); await DbServices.UpdateDbAllAsync(upn); } Status.Text = "执行修改成功"; } catch (Exception ex) { MessageBox.Show("" + ex.Message, "提示", MessageBoxButtons.OK, MessageBoxIcon.Information); } } else MessageBox.Show("文件类型不对", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
注意:读取Excel时要注意版本。xls和xlsx后缀名不能随意更改再导入,不然会报错