1. 程式人生 > >操作excel的C#小程式

操作excel的C#小程式

<寫在前面的話>

        其實這邊文章應該是第一篇想發的,但是有事兒拖著就慢慢忘了(/笑哭),正好看到了草稿,就進來補一下,放上程式碼備用。

        希望自己能夠將自己平時經歷的內容進行整理,堅持撰寫部落格,且行且珍惜,且行且努力!

<留給自己的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;
        }


    }
}