C#匯入匯出操作Excel
阿新 • • 發佈:2021-09-07
操作Excel有兩種方式,一種是IO流的模式操作Excel,優點速度快,跟硬碟讀寫資料一樣,缺點不能設定Excel格式,而想設定Excel格式就得用到元件了。
1 #region 匯出Excel 2 /// <summary> 3 /// 將資料集中的資料匯出到EXCEL檔案 4 /// </summary> 5 /// <param name="dataSet">輸入資料集</param> 6 /// <param name="isShowExcle">是否顯示該EXCEL檔案</param> 7 /// <returns></returns> 8 public bool DataSetToExcelThree(DataSet dataSet, bool isShowExcle, string keyword) 9 { 10 DataTable dataTable = dataSet.Tables[0]; 11 int rowNumber = dataTable.Rows.Count;//不包括欄位名 12 int columnNumber = dataTable.Columns.Count;13 int colIndex = 0; 14 15 if (rowNumber == 0) 16 { 17 MessageBox.Show("沒有任何資料可以匯入到Excel檔案!"); 18 return false; 19 } 20 21 //建立Excel物件 22 Microsoft.Office.Interop.Excel.Application excel = new Microsoft.Office.Interop.Excel.Application();23 //excel.Application.Workbooks.Add(true); 24 Microsoft.Office.Interop.Excel.Workbook workbook = excel.Workbooks.Add(Microsoft.Office.Interop.Excel.XlWBATemplate.xlWBATWorksheet); 25 Microsoft.Office.Interop.Excel.Worksheet worksheet = (Microsoft.Office.Interop.Excel.Worksheet)workbook.Worksheets[1]; 26 excel.Visible = isShowExcle; 27 //Microsoft.Office.Interop.Excel.Worksheet worksheet = (Microsoft.Office.Interop.Excel.Worksheet)excel.Worksheets[1]; 28 Microsoft.Office.Interop.Excel.Range range; 29 30 //生成欄位名稱 31 foreach (DataColumn col in dataTable.Columns) 32 { 33 colIndex++; 34 excel.Cells[1, colIndex] = col.ColumnName; 35 } 36 37 object[,] objData = new object[rowNumber, columnNumber]; 38 39 for (int r = 0; r < rowNumber; r++) 40 { 41 for (int c = 0; c < columnNumber; c++) 42 { 43 objData[r, c] = dataTable.Rows[r][c]; 44 } 45 //Application.DoEvents(); 46 } 47 // 寫入Excel 48 range = worksheet.Range[worksheet.Cells[2, 1], worksheet.Cells[rowNumber + 1, columnNumber]]; 49 range.Value2 = objData; 50 51 string fileName = @"E:\ExcelFile\" + keyword + "_" + DateTime.Now.ToString("G").Replace(" ", "_").Replace(@"/", "_").Replace(":", "") + ".xlsx"; 52 53 workbook.SaveAs(fileName, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Microsoft.Office.Interop.Excel.XlSaveAsAccessMode.xlNoChange, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value); 54 try 55 { 56 workbook.Saved = true; 57 excel.UserControl = false; 58 //excelapp.Quit(); 59 } 60 catch (Exception exception) 61 { 62 MessageBox.Show(exception.Message); 63 } 64 finally 65 { 66 workbook.Close(Microsoft.Office.Interop.Excel.XlSaveAction.xlSaveChanges, Missing.Value, Missing.Value); 67 excel.Quit(); 68 } 69 70 if (isShowExcle) 71 { 72 System.Diagnostics.Process.Start(fileName); 73 } 74 return true; 75 } 76 #endregion
匯入Excel批量更新到資料庫中
1 private async void ImportBtn_Click(object sender, EventArgs e) 2 { 3 OpenFileDialog openFileDialog = new OpenFileDialog(); 4 openFileDialog.Filter = "Files|*.xls;*.xlsx"; //設定開啟檔案的字尾型別 5 openFileDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyComputer);//開啟我的電腦資料夾 6 string fileType = ".xls,.xlsx"; 7 8 if (openFileDialog.ShowDialog() == DialogResult.OK) 9 { 10 string filePathAndName = openFileDialog.FileName;//檔案路徑以及檔名 11 string fileName = System.IO.Path.GetFileName(filePathAndName); //獲取檔名和副檔名 12 string fileEx = System.IO.Path.GetExtension(fileName);//獲取檔案的副檔名 13 if (fileType.Contains(fileEx)) 14 { 15 DataSet myDataSet = new DataSet(); 16 try 17 { 18 //連線字串 其中 "HDR=yes;"是說Excel檔案的第一行是列名而不是資料,"HDR=No;"正好與前面的相反。 19 // 其中 "IMEX=1 "如果列中的資料型別不一致,使用"IMEX=1"可必免資料型別衝突。 20 string strConn = "Provider=Microsoft.Ace.OleDb.12.0;" + "data source=" + filePathAndName + ";Extended Properties='Excel 12.0; HDR=Yes; IMEX=1'"; //此連線可以操作.xls與.xlsx檔案 21 OleDbConnection conn = new OleDbConnection(strConn); 22 conn.Open(); 23 //返回Excel的架構,包括各個sheet表的名稱,型別,建立時間和修改時間等 24 DataTable dtSheetName = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[] { null, null, null, "Table" }); 25 //包含excel中表名的字串陣列 26 string[] strTableNames = new string[dtSheetName.Rows.Count]; 27 for (int i = 0; i < dtSheetName.Rows.Count; i++) 28 { 29 strTableNames[i] = dtSheetName.Rows[i]["TABLE_NAME"].ToString(); 30 } 31 OleDbDataAdapter myCommand = null; 32 DataTable dt = new DataTable(); 33 //從指定的表名查詢資料,這裡選擇第一個 34 string strExcel = "select * from [" + strTableNames[0] + "]"; 35 myCommand = new OleDbDataAdapter(strExcel, strConn); 36 myCommand.Fill(myDataSet, "ExcelInfo"); 37 DataTable table = myDataSet.Tables["ExcelInfo"].DefaultView.ToTable(); 38 //遍歷DataTable更新到資料庫中; 39 var upn = new UnitPrn(); 40 for (int i = 0; i < table.Rows.Count; i++) 41 { 42 int a; 43 bool b = int.TryParse(table.Rows[i][0].ToString(),out a); 44 if(b) 45 upn.id = a; 46 upn.EnScopeName = table.Rows[i][1].ToString(); 47 upn.ChScopeName = table.Rows[i][2].ToString(); 48 upn.ScopeMarket = table.Rows[i][3].ToString(); 49 upn.ChScopeMarket = table.Rows[i][4].ToString(); 50 upn.cestcode = table.Rows[i][5].ToString(); 51 upn.EnEstateName = table.Rows[i][6].ToString(); 52 upn.EnPhaseName = table.Rows[i][7].ToString(); 53 upn.EnAddress = table.Rows[i][8].ToString(); 54 upn.ChEstateName = table.Rows[i][9].ToString(); 55 upn.ChPhaseName = table.Rows[i][10].ToString(); 56 upn.ChAddress = table.Rows[i][11].ToString(); 57 upn.cblgcode = table.Rows[i][12].ToString(); 58 upn.EnBuildingName = table.Rows[i][13].ToString(); 59 upn.ChBuildingName = table.Rows[i][14].ToString(); 60 upn.cuntcode = table.Rows[i][15].ToString(); 61 upn.Flat = table.Rows[i][16].ToString(); 62 upn.Floor = table.Rows[i][17].ToString(); 63 upn.FlatCn = table.Rows[i][18].ToString(); 64 upn.FloorCn = table.Rows[i][19].ToString(); 65 upn.EnStreetName = table.Rows[i][20].ToString(); 66 upn.EnRoadName = table.Rows[i][21].ToString(); 67 upn.ChRoadNameCn = table.Rows[i][22].ToString(); 68 upn.PRN = table.Rows[i][23].ToString(); 69 upn.Assessment = table.Rows[i][24].ToString(); 70 upn.ContractAddr = table.Rows[i][25].ToString(); 71 await DbServices.UpdateDbAllAsync(upn); 72 } 73 } 74 catch (Exception ex) 75 { 76 MessageBox.Show("" + ex.Message, "提示", MessageBoxButtons.OK, MessageBoxIcon.Information); 77 throw; 78 } 79 } 80 else 81 MessageBox.Show("檔案型別不對", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information); 82 } 83 84 //phase2 to do.. 85 }
更新資料這裡用的是Dapper
public static async Task<int> UpdateDbAllAsync(UnitPrn unitPrn) { string sql = $@"update {AppSetting.TableName} set EnScopeName =@EnScopeName ,ChScopeName=@ChScopeName ,ScopeMarket=@ScopeMarket ,ChScopeMarket=@ChScopeMarket ,cestcode=@cestcode ,EnEstateName=@EnEstateName ,EnPhaseName=@EnPhaseName ,EnAddress=@EnAddress ,ChEstateName=@ChEstateName ,ChPhaseName=@ChPhaseName ,ChAddress=@ChAddress ,cblgcode=@cblgcode ,EnBuildingName=@EnBuildingName ,ChBuildingName=@ChBuildingName ,cuntcode=@cuntcode ,Flat=@Flat ,Floor=@Floor ,FlatCn=@FlatCn ,FloorCn=@FloorCn ,EnStreetName=@EnStreetName ,ChStreetName=@ChStreetName ,EnRoadName=@EnRoadName ,ChRoadNameCn=@ChRoadNameCn ,PRN=@PRN ,Assessment=@Assessment ,ContractAddr=@ContractAddr where id =@id"; using (var conn = new SqlConnection(AppSetting.ConnStr)) { return await conn.ExecuteAsync(sql, unitPrn); } }
這裡匯出到Excel中的輸入的是DataSet,資料庫操作用的是Dapper,Dapper返回結果沒有DataSet的這裡需要中轉一次,原生的ado.net可以返回DataSet,不用他的原因是Dapper中封裝好了非同步的方法。
Dapper查詢:
1 public static async Task<IEnumerable<UnitPrn>> SearchSameBldgAsync(UnitPrn unitPrn) 2 { 3 string sql = $@"SELECT [id] 4 ,[EnScopeName] 5 ,[ChScopeName] 6 ,[ScopeMarket] 7 ,[ChScopeMarket] 8 ,[cestcode] 9 ,[EnEstateName] 10 ,[EnPhaseName] 11 ,[EnAddress] 12 ,[ChEstateName] 13 ,[ChPhaseName] 14 ,[ChAddress] 15 ,[cblgcode] 16 ,[EnBuildingName] 17 ,[ChBuildingName] 18 ,[cuntcode] 19 ,[Flat] 20 ,[Floor] 21 ,[FlatCn] 22 ,[FloorCn] 23 ,[EnStreetName] 24 ,[ChStreetName] 25 ,[EnRoadName] 26 ,[ChRoadNameCn] 27 ,[PRN] 28 ,[Assessment] 29 ,[ContractAddr] 30 FROM {AppSetting.TableName} where cblgcode = @cblgcode"; 31 using (var conn = new SqlConnection(AppSetting.ConnStr)) 32 { 33 return await conn.QueryAsync<UnitPrn>(sql, unitPrn); 34 } 35 }
查詢結果IEnumberable轉List
var list = new List<UnitPrn>(Result_Ienumberable);
List轉DataSet
實現:
DataSet result = ConvertToDataSet<UnitPrn>(list);
定義:
1 #region List<T>轉DataSet 2 public static DataSet ConvertToDataSet<T>(List<T> list) 3 { 4 try 5 { 6 if (list == null || list.Count <= 0) 7 { 8 return null; 9 } 10 11 DataSet ds = new DataSet(); 12 DataTable dt = new DataTable(typeof(T).Name); 13 DataColumn column; 14 DataRow row; 15 16 System.Reflection.PropertyInfo[] myPropertyInfo = typeof(T).GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance); 17 18 foreach (T t in list) 19 { 20 if (t == null) 21 { 22 continue; 23 } 24 25 row = dt.NewRow(); 26 27 for (int i = 0, j = myPropertyInfo.Length; i < j; i++) 28 { 29 System.Reflection.PropertyInfo pi = myPropertyInfo[i]; 30 31 string name = pi.Name; 32 33 if (dt.Columns[name] == null) 34 { 35 column = new DataColumn(name, pi.PropertyType); 36 dt.Columns.Add(column); 37 } 38 39 row[name] = pi.GetValue(t, null); 40 } 41 42 dt.Rows.Add(row); 43 } 44 ds.Tables.Add(dt); 45 return ds; 46 } 47 catch (Exception er) 48 { 49 throw er; 50 } 51 } 52 #endregion
整體呼叫:
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); //生成Excel DataSetToExcelThree(result, true, "Bldg");
本來已經完成任務了,但是老大說要用npoi元件,瞭解了一下npoi優勢還是可以的,等改好了再寫一篇npoi吧!
文章來自:
C#將資料集DataSet中的資料匯出到EXCEL檔案的幾種方法 - qanholas - 部落格園 (cnblogs.com)
C# 中List<T>與DataSet之間的轉換 - easten - 部落格園 (cnblogs.com)
(4條訊息) .Net C# 如何讀取Excel資料內容寫入資料庫並通過DataGridView控制元件動態重新整理顯示_IMZhangZiF的部落格-CSDN部落格