先說下需求:這是一個導入話單標記後並導出的功能
1. 選擇excel文件
2. 定義字段
日期 時間 對方號碼 通話時長 呼叫類型
3. 點擊datagridview 標題 出現下拉菜單 顯示定義的字段
4. 標記定義字段列
5. 保存定義字段數據 到 datatable
6 導出datatable
按照需求一步一步來,先設計界面,需要一個DataGridView和兩個Button,一個導入,一個導出,我加了個Label和TextBox來提示文件路徑。
先在類裡面定義幾個全局變量,下面的代碼中會用到。
1 int colIndex;//點擊的單元格列索引 2 int rowIndex;//點擊的單元格行索引 3 Dictionary<int, string> dic = new Dictionary<int, string>();//存放excel標題 4 List<string> list = new List<string>(); //存放標記後的標題 5 DataTable dt;//導入的table 6 string filename = "";//Excel文件名 View Code這是個導入的方法,雙擊導入按鈕,在事件裡添加如下代碼:
1 private void btnImport_Click(object sender, EventArgs e) 2 { 3 OpenFileDialog ofd = new OpenFileDialog(); 4 ofd.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop); 5 ofd.Filter = "Excel Files(*.xls)|*.xls"; 6 if (ofd.ShowDialog() != DialogResult.OK) 7 { return; } 8 filename = ofd.FileName; 9 textBox1.Text = ofd.FileName; 10 dt = ExcelToDataTable(filename); 11 dataGridView1.DataSource = dt;//ExcelToDataTable(ofd.FileName); 12 13 int ColCount = dataGridView1.Columns.Count; 14 //將Excel所有標題存入dic中 15 for (int i = 0; i < ColCount; i++) 16 { 17 dic.Add(i, dataGridView1.Columns[i].HeaderText); 18 } 19 } 導入預覽為了方便我將測試的Excel文檔放到桌面,Excel的標題我存到了字典裡,下面會用到。
到這裡基本實現了第一步,點擊導入按鈕,選中excel文件,顯示在datagridview上預覽。
點擊datagridview的標題,彈出下拉菜單,顯示定義的字段。因此添加一個ContextMenuStrip控件,將字段一個個添加進去。
要求點擊標題彈出下拉菜單,我用到了datagridview的CellCilck事件,這個事件裡代碼非常簡單,只要彈出contexmenustrip就行了,然後加一個對是否為標題行的判斷。
View Code首先是點擊datagridview一列的標題,然後選中一個菜單,這一列的標題要變成e.itemClicked,並且標記這一列,所以我寫了一個標記的方法表示標記後操作和樣式。
1 private void Mark(string item) 2 { 3 dt.Columns[colIndex].ColumnName = item; 4 dataGridView1.Columns[colIndex].HeaderText = item; 5 dataGridView1.Columns[colIndex].DefaultCellStyle.BackColor = Color.LightSteelBlue; 6 dataGridView1.EnableHeadersVisualStyles = false; 7 dataGridView1.Columns[colIndex].HeaderCell.Style.BackColor = Color.LightSlateGray; 8 } Mark因為涉及到匹配的問題,例如日期格式的列無法標記成“呼叫類型”,“通話時間”等,所以加了一些正則判斷,正則表達式以前從沒用過,也是網上現學的,寫得比較差。
又寫了一個判斷後的方法:
1 private void MatchItem(string match, string str, string item) 2 { 3 Match m = Regex.Match(match, str); 4 if (m.Success) 5 { 6 Mark(item); 7 //如果該列已標記,則不添加item到list 8 foreach (var i in list) 9 { 10 if (item == i) 11 return; 12 } 13 list.Add(item); 14 } 15 else 16 { 17 contextMenuStrip1.Hide(); 18 MessageBox.Show("該列不為" + item + "!"); 19 } 20 } 判斷格式至於contextmenustrip_itemClicked事件裡只要在每個case裡調用MatchItem方法就可以了。
1 private void contextMenuStrip1_ItemClicked(object sender, ToolStripItemClickedEventArgs e) 2 { 3 //dt = ExcelToDataTable(filename); 4 //獲取想要標記的的標題 5 string item = e.ClickedItem.Text; 6 //獲取用於判斷的內容 7 var BeMatch = dataGridView1.Rows[rowIndex + 1].Cells[colIndex].Value.ToString(); 8 //當前列在table是否已經存在 9 int i = 0; 10 foreach (DataColumn dataCol in dt.Columns) 11 { 12 if (i != colIndex && dataCol.ColumnName == item) 13 { 14 contextMenuStrip1.Hide(); 15 var index = i + 1; 16 MessageBox.Show("該表第" + index + "列為" + dataCol.ColumnName + ",無法標記"); 17 return; 18 } 19 i++; 20 } 21 22 switch (item) 23 { 24 case "呼叫類型": 25 { 26 string strType = @"[\u4e00-\u9fbb]"; 27 MatchItem(BeMatch, strType, item); 28 } 29 break; 30 case "對方號碼": 31 { 32 string strNum = @"0?[1]+[358]+\d{9}"; 33 MatchItem(BeMatch, strNum, item); 34 } 35 break; 36 case "日期": 37 { 38 string strDate = @"^2\d{7}$"; 39 MatchItem(BeMatch, strDate, item); 40 } 41 break; 42 case "時間": 43 { 44 string strTime = @"^[0-2]\d{1}[0-5]\d{1}[0-5]\d{1}$"; 45 MatchItem(BeMatch, strTime, item); 46 } 47 break; 48 case "通話時長": 49 { 50 string strOften = @"\d"; 51 MatchItem(BeMatch, strOften, item); 52 } 53 break; 54 case "取消設置": 55 { 56 //遍歷原標題,獲取取消設置的列,移出dt 57 foreach (var kv in dic) 58 { 59 if (kv.Key == colIndex) 60 { 61 list.Remove(dataGridView1.Columns[colIndex].HeaderText); 62 //list.Insert(colIndex,kv.Value); 63 item = kv.Value; 64 dt.Columns[colIndex].ColumnName = item; 65 } 66 } 67 //還原標題和樣式 68 dataGridView1.Columns[colIndex].DefaultCellStyle.BackColor = Color.White; 69 dataGridView1.Columns[colIndex].HeaderCell.Style.BackColor = DefaultBackColor; 70 } 71 break; 72 } 73 } 標記列做完運行的效果是這樣的:
到這裡基本結束了,運行後沒什麼大問題,可能有的bug還沒有測出來。第一次寫博客,寫的不好大家見諒,歡迎提出各種意見和建議。謝謝支持!