操作excel的C#小程式
阿新 • • 發佈:2018-12-16
<寫在前面的話>
其實這邊文章應該是第一篇想發的,但是有事兒拖著就慢慢忘了(/笑哭),正好看到了草稿,就進來補一下,放上程式碼備用。
希望自己能夠將自己平時經歷的內容進行整理,堅持撰寫部落格,且行且珍惜,且行且努力!
<留給自己的Flag,希望自己能夠堅持!!!>
回到本文的主題,本人目前只會使用C#語言,沒有很本質的學習過C#和.net等等這些內容,本文主要從應用層面上,通過利用NPOI,和winform,形成了一個視覺化的計算工具,至少為以後操作Excel、Word等office系列的文件留個底。
現在傳上程式碼,以後有機會再補充或者修改了。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using NPOI.XSSF.UserModel; using NPOI.XSSF.Util; using System.IO; namespace ExcelHelper.Helpers { class ExcelHandler { #region ------------------------單例模式,構造功能函式-------------------------- private static ExcelHandler eh; private ExcelHandler() { } public static ExcelHandler GetInstance() { if(eh==null) { eh=new ExcelHandler(); return eh; } else return eh; } #endregion public delegate void changeLogHandler(string s); public event changeLogHandler changeLog; public delegate void refreshSheetList(); public event refreshSheetList refreshSheet; private XSSFWorkbook excelBook; private XSSFSheet currentSheet; public List<string> sheetNames=new List<string>(); private string bookPath; private int sheetCount; public int rowCount=0; public int columnCount=0; private Dictionary<string, double> restTimeCount = new Dictionary<string, double>(); public bool isExcelBookExist { get { return excelBook == null; } } public void OpenExcel(string path) { bookPath = path; excelBook = new XSSFWorkbook(bookPath); sheetCount = excelBook.Count; GetSheetNames(); if (changeLog != null) changeLog("成功開啟工作簿,工作簿中共包含" + sheetCount + "個工作表"); } private void GetSheetNames() { sheetNames.Clear(); for (int i = 0; i < sheetCount; i++) { string sheetname = excelBook.GetSheetName(i); sheetNames.Add(sheetname); } if (changeLog != null) changeLog("成功獲取全部工作表名"); } public void SaveExcel() { using(FileStream fs=new FileStream(bookPath+".edit.xlsx",FileMode.Create)) { excelBook.Write(fs); fs.Close(); } if (changeLog != null) changeLog("成功儲存工作簿"); } public void BackupExcel() { try { System.IO.File.Copy(bookPath, bookPath + ".backup"); } catch (Exception ex) { changeLog("檔案已備份\r\n"+ex.ToString()); } if (changeLog != null) changeLog("成功備份工作簿"); } /// <summary> /// 開啟工作表,並獲取工作表的行列數量 /// </summary> /// <param name="name"></param> public void OpenSheet(string name) { try { currentSheet = (XSSFSheet)excelBook.GetSheet(name); rowCount = currentSheet.LastRowNum + 1; columnCount = GetSheetColumn(currentSheet) + 1; if (changeLog != null) changeLog("成功開啟工作表" + name); } catch(Exception e) { columnCount = -1; changeLog(e.ToString()); return; } } public int GetSheetColumn(XSSFSheet sheet) { int rowCount = sheet.LastRowNum+1; int tmpColumnCount=-1; for (int i = 0; i < rowCount; i++) { if (currentSheet.GetRow(i).LastCellNum > tmpColumnCount) tmpColumnCount = currentSheet.GetRow(i).LastCellNum; } return tmpColumnCount; } public int GetColumn(int row) { try { if (row > rowCount) row = rowCount; int r = currentSheet.GetRow(row).LastCellNum; return r; } catch (Exception e) { changeLog(e.ToString()); return -1; } } public string GetCellValue(int row, int column) { try { if (row > rowCount) row = rowCount; if (column <= currentSheet.GetRow(row).LastCellNum) return currentSheet.GetRow(row).GetCell(column).ToString(); else return ""; } catch (Exception e) { changeLog(e.ToString()); return ""; } } public byte[] GetCellColor(int row, int column) { try { if (row > rowCount) row = rowCount; if (column <= currentSheet.GetRow(row).LastCellNum && currentSheet.GetRow(row).GetCell(column).CellStyle.FillForegroundColorColor != null) return currentSheet.GetRow(row).GetCell(column).CellStyle.FillForegroundColorColor.RGB; else return null; } catch (Exception e) { changeLog(e.ToString()); return null; } } public void RebuildTotalSheet() { XSSFSheet sht = (XSSFSheet)excelBook.CreateSheet("Total"); sheetNames.Add("Total"); sheetCount++; refreshSheet(); int sheetRowCount = 0; for (int i = 0; i < sheetCount - 1; i++) { XSSFSheet tmpSheet = (XSSFSheet)excelBook.GetSheetAt(i); for (int j = 0; j <= tmpSheet.LastRowNum; j++) { try { if (tmpSheet.GetRow(j).GetCell(0).StringCellValue == "姓名") continue; XSSFRow row = (XSSFRow)sht.CreateRow(sheetRowCount); for (int k = 0; k < tmpSheet.GetRow(j).LastCellNum-1; k++)//排除最後一列午休時間 { XSSFCell tc = (XSSFCell)tmpSheet.GetRow(j).GetCell(k); if (tc != null) { XSSFCell cell = (XSSFCell)row.CreateCell(k); cell.SetCellValue(tc.ToString()); cell.CellStyle = tmpSheet.GetRow(j).GetCell(k).CellStyle; } } sheetRowCount++; if (!restTimeCount.ContainsKey(row.GetCell(0).ToString())) { restTimeCount.Add(row.GetCell(0).ToString(), double.Parse(tmpSheet.GetRow(j).GetCell(tmpSheet.GetRow(j).LastCellNum - 1).ToString())); } else { restTimeCount[row.GetCell(0).ToString()] += double.Parse(tmpSheet.GetRow(j).GetCell(tmpSheet.GetRow(j).LastCellNum - 1).ToString()); } } catch (Exception ex) { continue; } } } changeLog("整合表格成功"); } public void CalculateWorkTime() { XSSFSheet tmpSheet=(XSSFSheet)excelBook.CloneSheet(sheetCount-1); sheetCount++; sheetNames.Add(excelBook.GetSheetName(excelBook.GetSheetIndex(tmpSheet))); refreshSheet(); for (int i = 0; i <= tmpSheet.LastRowNum; i++) { try { XSSFRow row=(XSSFRow)tmpSheet.GetRow(i); for (int j = 1; j < row.LastCellNum; j++) { XSSFCell cell = (XSSFCell)row.GetCell(j); if (cell != null && (cell.StringCellValue.Contains(':') || cell.StringCellValue.Contains(':'))) { string[] s = cell.StringCellValue.Split(new char[] { ':', ':', '-', '—',' '}, StringSplitOptions.RemoveEmptyEntries); if (s.Length > 4) cell.SetCellValue("ErrorValue"); else { int value = int.Parse(s[2]) * 60 + int.Parse(s[3]) - (int.Parse(s[0]) * 60 + int.Parse(s[1])); cell.SetCellValue(value); } } } } catch (Exception ex) { continue; } } changeLog("工時計算完畢"); } public void StatisticalWorkTime() { List<summaryStruct> sum = new List<summaryStruct>(); XSSFSheet tmpSheet = (XSSFSheet)excelBook.GetSheetAt(sheetCount-1); for (int i = 0; i <= tmpSheet.LastRowNum; i++) { try { XSSFRow row = (XSSFRow)tmpSheet.GetRow(i); summaryStruct ms = new summaryStruct(); ms.name = row.GetCell(0).StringCellValue; for (int j = 1; j < row.LastCellNum-1; j++) { XSSFCell cell = (XSSFCell)row.GetCell(j); if (cell != null) { int intValue; if (!int.TryParse(cell.ToString(), out intValue)) continue; if (cell.CellStyle.FillForegroundColorColor != null) ms.ColoredTime += intValue; else ms.nonColorTime += intValue; } } sum.Add(ms); } catch (Exception ex) { continue; } } Dictionary<string, summaryStruct> dic = new Dictionary<string, summaryStruct>(); foreach (summaryStruct tsum in sum) { if (!dic.ContainsKey(tsum.name)) dic.Add(tsum.name, tsum); else { dic[tsum.name].ColoredTime += tsum.ColoredTime; dic[tsum.name].nonColorTime += tsum.nonColorTime; } if (restTimeCount.ContainsKey(tsum.name)) { dic[tsum.name].RestTime = restTimeCount[tsum.name]*60; } } //計算午休時間 tmpSheet = (XSSFSheet)excelBook.CreateSheet("Summary"); sheetCount++; sheetNames.Add("Summary"); refreshSheet(); tmpSheet.CreateRow(0).CreateCell(0).SetCellValue("姓名"); tmpSheet.GetRow(0).CreateCell(1).SetCellValue("著色單元格統計"); tmpSheet.GetRow(0).CreateCell(2).SetCellValue("未著色單元格統計"); tmpSheet.GetRow(0).CreateCell(3).SetCellValue("午休統計"); string[] str=new string[dic.Count]; dic.Keys.CopyTo(str,0); for (int i = 0; i < dic.Count; i++) { tmpSheet.CreateRow(i + 1).CreateCell(0).SetCellValue(dic[str[i]].name); tmpSheet.GetRow(i + 1).CreateCell(1).SetCellValue(dic[str[i]].ColoredTime); tmpSheet.GetRow(i + 1).CreateCell(2).SetCellValue(dic[str[i]].nonColorTime); tmpSheet.GetRow(i + 1).CreateCell(3).SetCellValue(dic[str[i]].RestTime); } changeLog("工時彙總完畢"); } public void CalculatePayment(double coloredPay, double nonColoredPay) { XSSFSheet tmpSheet = (XSSFSheet)excelBook.CloneSheet(sheetCount - 1); sheetCount++; sheetNames.Add(excelBook.GetSheetName(excelBook.GetSheetIndex(tmpSheet))); refreshSheet(); tmpSheet.GetRow(0).CreateCell(4).SetCellValue("總計"); for (int i = 1; i <= tmpSheet.LastRowNum; i++) { double sum=0,tmpValue=0; try { XSSFRow row = (XSSFRow)tmpSheet.GetRow(i); XSSFCell cell = (XSSFCell)tmpSheet.GetRow(i).GetCell(1); tmpValue=cell.NumericCellValue * coloredPay; sum+=tmpValue; cell.SetCellValue(tmpValue); cell = (XSSFCell)tmpSheet.GetRow(i).GetCell(2); tmpValue=cell.NumericCellValue * nonColoredPay; sum += tmpValue; cell.SetCellValue(tmpValue); cell = (XSSFCell)tmpSheet.GetRow(i).GetCell(3); tmpValue = cell.NumericCellValue * nonColoredPay; sum -= tmpValue; cell.SetCellValue(-tmpValue); tmpSheet.GetRow(i).CreateCell(4).SetCellValue(sum); } catch (Exception ex) { continue; } } changeLog("工資計算完畢"); } } public class summaryStruct { public string name=""; public int nonColorTime=0; public int ColoredTime=0; public double RestTime = 0; } }
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using ExcelHelper.Helpers; using System.IO; namespace ExcelHelper { public partial class Form1 : Form { private string s = System.Environment.SpecialFolder.DesktopDirectory.ToString(); public Form1() { InitializeComponent(); ExcelHandler.GetInstance().changeLog += ShowLog; ExcelHandler.GetInstance().refreshSheet += RefreshSheetList; } private void OpenExcel_Click(object sender, EventArgs e) { OpenFileDialog ofd = new OpenFileDialog(); ofd.Filter = "Excel2007工作表|*.xlsx"; ofd.InitialDirectory = s; ofd.SupportMultiDottedExtensions = false; ofd.Multiselect = false; ofd.CheckFileExists = true; DialogResult dr = ofd.ShowDialog(); if (dr == DialogResult.OK) ExcelHandler.GetInstance().OpenExcel(ofd.FileName); else return; RefreshSheetList(); SheetList.SelectedIndex = 0; //備份 ExcelHandler.GetInstance().BackupExcel(); button1.Enabled = true; button3.Enabled = true; button2.Enabled = false; button4.Enabled = false; button5.Enabled = false; } private void SheetList_SelectedIndexChanged(object sender, EventArgs e) { ExcelHandler.GetInstance().OpenSheet(SheetList.SelectedItem.ToString()); AddColumn(ExcelHandler.GetInstance().columnCount); for (int i = 0; i < ExcelHandler.GetInstance().rowCount; i++) { ListViewItem lvi=new ListViewItem(); lvi.UseItemStyleForSubItems = false; lvi.BackColor = Color.Transparent; lvi.Text = i + 1+""; for (int j = 0; j < ExcelHandler.GetInstance().GetColumn(i); j++) { string s=ExcelHandler.GetInstance().GetCellValue(i,j); if (s != null) { ListViewItem.ListViewSubItem sub = new ListViewItem.ListViewSubItem(); sub.Text = s; byte[] color=ExcelHandler.GetInstance().GetCellColor(i,j); if (color != null) { sub.BackColor = Color.Yellow; } lvi.SubItems.Add(sub); } else lvi.SubItems.Add(""); } sheetDetail.Items.Add(lvi); } sheetDetail.Refresh(); } private void AddColumn(int columnCount) { sheetDetail.Clear(); if (columnCount == -1) return; for (int i = 0; i < columnCount; i++) { if (i == 0) sheetDetail.Columns.Add(""); else sheetDetail.Columns.Add(((char)(i + 64)).ToString()); } } private void ShowLog(string s) { this.HistoryTextBox.AppendText(DateTime.Now.Hour + ":" + DateTime.Now.Minute + ":" + DateTime.Now.Second + " : " + s + "\r\n"); } private void RefreshSheetList() { SheetList.Items.Clear(); //重新整理表格列表 for (int i = 0; i < ExcelHandler.GetInstance().sheetNames.Count; i++) { SheetList.Items.Add(ExcelHandler.GetInstance().sheetNames[i]); } SheetList.SelectedIndex = 0; } private void button1_Click(object sender, EventArgs e) { ExcelHandler.GetInstance().RebuildTotalSheet(); SheetList.SelectedIndex = SheetList.Items.Count - 1; button2.Enabled = true; button1.Enabled = false; } private void button3_Click(object sender, EventArgs e) { ExcelHandler.GetInstance().SaveExcel(); } private void button2_Click(object sender, EventArgs e) { ExcelHandler.GetInstance().CalculateWorkTime(); SheetList.SelectedIndex = SheetList.Items.Count - 1; button4.Enabled = true; button2.Enabled = false; } private void button4_Click(object sender, EventArgs e) { ExcelHandler.GetInstance().StatisticalWorkTime(); SheetList.SelectedIndex = SheetList.Items.Count - 1; button4.Enabled = false; button5.Enabled = true; } private void button5_Click(object sender, EventArgs e) { double coloredPay,nonColoredPay; if (!double.TryParse(coloredPayTB.Text, out coloredPay)) { MessageBox.Show("請輸入著色單元格工資並重試"); return; } if (!double.TryParse(nonColoredPayTB.Text, out nonColoredPay)) { MessageBox.Show("請輸入未著色單元格工資並重試"); return; } ExcelHandler.GetInstance().CalculatePayment(coloredPay/60,nonColoredPay/60); SheetList.SelectedIndex = SheetList.Items.Count - 1; button5.Enabled = false; } } }