1. 程式人生 > 其它 >C#匯入匯出操作Excel

C#匯入匯出操作Excel

操作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部落格