6、比较Excel中的数据

第5篇的方法是直接打开EXCEL进行操作,此种方法比较容易理解,但缺点就是代码执行起来比较缓慢。所以才有接下来的第6篇。此篇是用读取数据库的方式来读取EXCEL中的数据,然后将数据读取到DATATABLE中进行比较。因为DATATBLE是在内存中的,所以比较过程中读取数据的速度相对来说是快上不少。其实本来可以在一开始就将数据全部读入DATATBLE中然后进行后续的插入一列、排序、比较、恢复原序等等操作。但是因为个人比较懒吧也就没有去实现了。这里有一个地方需要注意:在使用COM控件直接从EXCEL中读取数据时上标是从1开始的,而1表示的位置是列名那一行。但是在DATATBLE中上标是从0开始的,并且此处已经数据第一行的开始了。(说的又不对和不当的地方,希望有大神指正!!!)下面附上代码。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Excel = Microsoft.Office.Interop.Excel.Application;
using System.Threading;
using System.Diagnostics;
using System.Reflection;
using System.Data;
using System.Data.OleDb;
using System.Windows.Forms;
using Microsoft.Office.Interop.Excel;


namespace UI
{
    class OleCompare
    {
        #region 连接Excel
        public static DataSet LoadDataFromExcel(string filePath, Excel excel)
		 
        {
            try
            {
                Worksheet wSheet =  excel.Workbooks[1].Worksheets[1];
                excel.DisplayAlerts = false;
               // MessageBox.Show(wSheet.Name);

                string strConn;
                strConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + filePath + ";Extended Properties='Excel 8.0;HDR=False;IMEX=1'";
                OleDbConnection OleConn = new OleDbConnection(strConn);
                OleConn.Open();
                String sql = "SELECT * FROM  ["+wSheet.Name+"$]";//可是更改Sheet名称,比如sheet2,等等   

                OleDbDataAdapter OleDaExcel = new OleDbDataAdapter(sql, OleConn);
                DataSet oleDsExcel = new DataSet();
                OleDaExcel.Fill(oleDsExcel,"Sheet1");
                OleConn.Close();
                return oleDsExcel;
            }
            catch (Exception err)
            {
                MessageBox.Show("数据绑定Excel失败!失败原因:" + err.Message);
                return null;
            }
        }
        #endregion

        #region 插入一列并排序
        public Excel AddColumns(string str, Excel excel)
        {
            int i = 2;
            //excel进程实例化
            excel.Workbooks.Open(str);    //打开excel文件
            Workbook workBook = excel.Workbooks[1];
            Worksheet workSheet = workBook.Worksheets[1];
            workBook.ActiveSheet.Columns[1].Insert();      //获取活动页,插入一列      
            workSheet.Cells[1, 1] = "NO";  //在第一行第一列的位置插入“NO”

            //控制加入的NO数
            //progressBar1.Maximum = Convert.ToInt32(excel.ActiveSheet.Cells.SpecialCells(XlCellType.xlCellTypeLastCell).Row);
            int iRow = workBook.ActiveSheet.Cells.SpecialCells(XlCellType.xlCellTypeLastCell).Row;  //文件工作页中的数据行数
            while (i <= iRow)
            {
                workSheet.Cells[i, 1] = i - 1;    //为单元格赋值
                i++;
                //xtraTabPage2.Refresh();
                //progressBar1.Value = i / 2;
            }

            //为指定的列排序
            workSheet.Columns.Sort(workSheet.get_Range("B2:B65536", Type.Missing), XlSortOrder.xlAscending,
                workSheet.get_Range("C2:C65536", Type.Missing), Type.Missing, XlSortOrder.xlAscending, workSheet.get_Range("G2:G65536", Type.Missing),
                XlSortOrder.xlAscending, XlYesNoGuess.xlYes, Type.Missing, Type.Missing, XlSortOrientation.xlSortColumns,
                XlSortMethod.xlPinYin, XlSortDataOption.xlSortNormal, XlSortDataOption.xlSortNormal, XlSortDataOption.xlSortNormal);
            return excel;
        }
        #endregion

        #region 比较
        public void Compare(string txtSource, string txtAim)
        {
            Excel xlsSource = new Excel();
            Excel xlsAim = new Excel();
            xlsSource = AddColumns(txtSource, xlsSource);
            xlsAim = AddColumns(txtAim, xlsAim);
            DataSet ds = LoadDataFromExcel(txtSource, xlsSource);
            System.Data.DataTable dtSource = ds.Tables["Sheet1"];
            ds = LoadDataFromExcel(txtAim, xlsAim);
            System.Data.DataTable dtAim = ds.Tables["Sheet1"];
            //获取当前活动页
            Worksheet wsSource = xlsSource.Workbooks[1].Worksheets[1];
            Worksheet wsAim = xlsAim.Workbooks[1].Worksheets[1];

            int sRow = dtSource.Rows.Count;
            int aRow = dtAim.Rows.Count;          

            //取最大列
            int maxCol = dtSource.Columns.Count;
            int nextR = 0;  // 指示表2中的当前比较位置
            int i = nextR;
            //表1与表2相比
            string strSource, strAim; //排列序号

            while (i <= sRow && nextR < aRow)
            {
                //取排列序号
                strSource = dtSource.Rows[i]["カタログNo"].ToString() + dtSource.Rows[i]["セクションNo1"].ToString() + dtSource.Rows[i]["品名コード"].ToString();
                strAim = dtAim.Rows[nextR]["カタログNo"].ToString() + dtAim.Rows[nextR]["セクションNo1"].ToString() + dtAim.Rows[nextR]["品名コード"].ToString();

                if (strSource.CompareTo(strAim) == 0)    //两表中的排列序号存在且相等
                {
                    //相等的条件下比较内容
                    int p = nextR;
                    string strSourceRow, strAimRow;    //当前比较位置的数据内容
                    while (strSource.CompareTo(strAim) == 0)  //序号相等
                    {
                        //读取i 行中的数据
                        strSourceRow = dtSource.Rows[i]["セクションNo2"].ToString()+ dtSource.Rows[i]["セクションNo3"].ToString() + dtSource.Rows[i]["分割No"].ToString()
                            + dtSource.Rows[i]["品名"].ToString() + dtSource.Rows[i]["部品番号"].ToString() + dtSource.Rows[i]["員数"].ToString()
                            + dtSource.Rows[i]["外色/内色"].ToString() + dtSource.Rows[i]["互換記号"].ToString() + dtSource.Rows[i]["部品番号  ( ) 付"].ToString()
                            + dtSource.Rows[i]["適用記述"].ToString() + dtSource.Rows[i]["切替コード"].ToString();
                        //读取p行中的数据
                        strAimRow = dtAim.Rows[p]["セクションNo2"].ToString() + dtAim.Rows[p]["セクションNo3"].ToString() + dtAim.Rows[p]["分割No"].ToString()
                            + dtAim.Rows[p]["品名"].ToString() + dtAim.Rows[p]["部品番号"].ToString() + dtAim.Rows[p]["員数"].ToString()
                            + dtAim.Rows[p]["外色/内色"].ToString() + dtAim.Rows[p]["互換記号"].ToString() + dtAim.Rows[p]["部品番号  ( ) 付"].ToString()
                            + dtAim.Rows[p]["適用記述"].ToString() + dtAim.Rows[p]["切替コード"].ToString();
                        
                        // 将取得的单行数据进行相比
                        if (strSourceRow != strAimRow)     //数据值不相同
                        {
                            
                            //改变该行的字体颜色,因DataTable中的数据下标是从0开始的,所以必须在excel中要加上偏移量
                            xlsAim.Range[xlsAim.Cells[p+2, 1], xlsAim.Cells[p+2, maxCol]].Font.ColorIndex = 3;
                            p++;
                            //获取下一行的排列序号
                            strAim = dtAim.Rows[p]["カタログNo"].ToString() + dtAim.Rows[p]["セクションNo1"].ToString() + dtAim.Rows[p]["品名コード"].ToString();
                        }
                        else
                        {
                            xlsAim.Range[xlsAim.Cells[p+2, 1], xlsAim.Cells[p+2, maxCol]].Font.ColorIndex = 1;
                            i++;    //表1中下一条数据的读取位置
                            nextR = p + 1;  //表2中下一条数据的读取位置
                            break;
                        }
                    }
                    if (strSource.CompareTo(strAim) != 0)
                    {
                        wsSource.Range[wsSource.Cells[i+2, 1], wsSource.Cells[i+2, maxCol]].Font.ColorIndex = 3;
                        i++;
                        nextR++;
                    }
                }
                else if ((strSource.CompareTo(strAim)) > 0)  // 表1大于表2,则将表2中对应的行标识出
                {
                    wsAim.Range[wsAim.Cells[nextR+2, 1], wsAim.Cells[nextR+2, maxCol]].Font.ColorIndex = 5;
                    nextR++;
                }
                else if ((strSource.CompareTo(strAim)) < 0)                //表1小于表2,则将表1中的对应的行标识出
                {
                    wsSource.Range[wsSource.Cells[i+2, 1], wsSource.Cells[i+2, maxCol]].Font.ColorIndex = 5;
                    i++;
                }
            }
            ReSort(xlsSource);
            ReSort(xlsAim);
            KillProcess(xlsSource.Name);
            KillProcess(xlsAim.Name);
        }
        #endregion

        #region 恢复排序
        private void ReSort(Excel excel)
        {
            //两张表恢复本来顺序
           Worksheet ws = excel.Workbooks[1].Worksheets[1];
            ws.Columns.Sort(ws.get_Range("A1:A65536", Type.Missing), XlSortOrder.xlAscending,
                Type.Missing, Type.Missing, XlSortOrder.xlAscending, Type.Missing,
                XlSortOrder.xlAscending, XlYesNoGuess.xlYes, Type.Missing, Type.Missing, XlSortOrientation.xlSortColumns,
                XlSortMethod.xlPinYin, XlSortDataOption.xlSortNormal, XlSortDataOption.xlSortNormal, XlSortDataOption.xlSortNormal);

            //删除增加的序号列
            ws.get_Range("A1:A65536").Delete(Type.Missing);
            //保存并退出
            excel.DisplayAlerts = false;   //禁止弹出保存对话框
            excel.Workbooks[1].Save();
            excel.Workbooks.Close();
            excel.Application.Quit();
        }
        #endregion
        #region 杀死进程
        public void KillProcess(string processName)
        {
            //获得进程对象,以用来操作
            System.Diagnostics.Process myproc = new System.Diagnostics.Process();
            //得到所有打开的进程 
            try
            {
                //获得需要杀死的进程名
                foreach (Process thisproc in Process.GetProcessesByName(processName))
                {
                    //立即杀死进程
                    thisproc.Kill();
                }
            }
            catch (Exception Exc)
            {
                throw new Exception("", Exc);
            }
        }
        #endregion
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值