C#利用NPOI实现跨Excel数据查找(备件筛选工具)

  备件筛选工具,软件试用链接:https://download.csdn.net/download/weixin_44834086/12404203

备件筛选工具试用链接:https://download.csdn.net/download/weixin_44834086/12404203
软件演示视频链接:https://www.bilibili.com/video/BV145411s7fu/
设备工程师最常见的一项工作就是备件清单梳理,每次当供应商提供一份元器件清单给我我们后,我们会先进行初步筛选,选出哪些是我们需要的,形成初步的备件清单,但这个清单不能直接提交给采购部,因为这个清单里可能存在库房里已经有的备件,这部分已经有的备件是不需要买的,我们必须把它们筛选出来删掉,才能提交给采购部购买。

怎样才能知道哪些备件是库房里已经有的呢?
你是不是会一个个的在库房台账Excel里按Ctrl+F查找?
或者你把初版备件清单复制到库房台账的Excel里,标记重复项?
当然,这是其中的两种方法,可是你有没有想过,这两种方法是不是就一定能达到我们的目的?
你想想下面这种情况:一个备件供应商提供的型号是“QSL-1/4-10”,但库房台账里的型号却是“QSL 1/4-10”,型号里只是多一个“-”,此时用上述的两种方法搜索是没有匹配的结果的,但实际上这两个型号是一样的,这时你会认为库房买有,结果买回来后发现库房有相同的备件,造成浪费。(别说了,说多了都是泪,库房里还有好多型号不同但东西是一样的的备件)。

这个事情没人管吗???!!!

于是我就开发这个备件筛选工具,就是为了解决上面这个问题,该工具可以设置搜索的相似精度,备件型号里的特殊字符都会过滤掉,把可能相同的备件全部筛选出来,给设备工程师判断这些备件是否一样提供一个参考,避免备件的重复购买。

如有bug欢迎提出,谢谢。
软件界面如下所示:在这里插入图片描述
如下图所示,设置搜索的相似精度为85%,软件完成搜索后会将搜索结果显示在窗体下方的DateGridView中,文件1中的哪一行,与文件2中的哪一行有相似的备件,设备工程师可以两个型号进行对比确认备件是否相同。
在这里插入图片描述
程序主要有以下功能:
1、字符串处理(过滤字符串中的特殊字符);
2、引用了两种字符串相似度的算法,并取两种算法算出的较大结果作为筛选的结果(可以避免漏选);
3、生成结果清单(使用NPOI创建Excel文件,并将DateGridView中的数据写入Excel文件);
4、生成备件清单(复制一份文件1,再使用NPOI将筛选出来的行删掉)

主要代码如下:

using System;
using System.Linq;
using System.Windows.Forms;
using F23.StringSimilarity;
using NP = NPOI.XSSF.UserModel;
using System.IO;
using System.Threading;
using NPOI.HSSF.UserModel;
using System.Drawing;
using Excel = Microsoft.Office.Interop.Excel;
using System.Reflection;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using System.Collections;

namespace 备件筛选工具
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            Control.CheckForIllegalCrossThreadCalls = false;//程序加载时取消跨线程操作的访问                                            
            X = this.Width;//获取窗体的宽度
            Y = this.Height;//获取窗体的高度
            setTag(this);//调用方法
        }


        NPOI.SS.UserModel.ISheet sht1;//声明一个sheet  sht1
        NPOI.SS.UserModel.ISheet sht2;//声明一个sheet  sht2
        string FilePath1 = "";//声明字符串变量 文件1路径
        string FilePath2 = "";//声明字符串变量 文件2路径
        string fileName1 = "";
        string fileName2 = "";
        ArrayList matchRow = new ArrayList();




        //选择文件1
        private void Btn_Select1_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd1 = new OpenFileDialog();
            ofd1.InitialDirectory = @"C:\Users\28463\Desktop";//定义打开文件对话框的初始目录
            ofd1.Title = "请选择要筛选的文件";//定义打开文件对话框的名称
            ofd1.Filter = "所有文件|*.xls;*.xlsx";//过滤只显示Excel文件
            ofd1.ShowDialog(); //弹出打开文件对话框
            fileName1 = System.IO.Path.GetFileName(ofd1.FileName);//将文件1的名称赋值给文本框fileName
            text_FilePath1.Text = fileName1;//将文件1的名称赋值给文本框text_FilePath1.Text
            FilePath1 = ofd1.FileName;//将文件1的路径赋值给FilePath1
        }


        //选择文件2
        private void Btn_Select2_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd2 = new OpenFileDialog();
            ofd2.InitialDirectory = @"C:\Users\28463\Desktop";//定义打开文件对话框的初始目录
            ofd2.Title = "请选择要筛选的文件";//定义打开文件对话框的名称
            ofd2.Filter = "所有文件|*.xls;*.xlsx";//过滤只显示Excel文件
            ofd2.ShowDialog();//弹出打开文件对话框
            fileName2 = System.IO.Path.GetFileName(ofd2.FileName);//将文件2的名称赋值给文本框fileName
            text_FilePath2.Text = fileName2;//将文件2的名称赋值给文本框text_FilePath2.Text            
            FilePath2 = ofd2.FileName;//将文件2的路径赋值给FilePath1           
        }

        private void OpenFile1_Click(object sender, EventArgs e)
        {
            try
            {
                System.Diagnostics.Process.Start(FilePath1);
            }

            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString() + "\r\n" + "请检查是否选择文件!", "错误提示"); //抛出异常信息
            }
        }
        private void OpenFile2_Click(object sender, EventArgs e)
        {
            try
            {
                System.Diagnostics.Process.Start(FilePath2);
            }

            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString() + "\r\n" + "请检查是否选择文件!", "错误提示"); //抛出异常信息
            }
        }

        #region 过滤掉字符串中的特殊字符
        /// <summary>
        /// 过滤掉字符串中的特殊字符
        /// </summary>
        /// <param name="str">需要过滤字符串</param>
        /// <returns>过滤之后的字符串</returns>
        public static string ReplaceSymbol(string str)
        {
            if (str == String.Empty)
                return String.Empty;
            //半角符号
            str = str.Replace("'", "");
            str = str.Replace("·", "");
            str = str.Replace(".", "");
            str = str.Replace(",", "");
            str = str.Replace(";", "");
            str = str.Replace(",", "");
            str = str.Replace("?", "");
            str = str.Replace("-", "");
            str = str.Replace("_", "");
            str = str.Replace("/", "");
            str = str.Replace("(", "(");
            str = str.Replace(")", ")");
            str = str.Replace("\\", "");
            //全角符号
            str = str.Replace(";", "");
            str = str.Replace(",", "");
            str = str.Replace("?", "");
            str = str.Replace("——", "");
            str = str.Replace("、", "");
            str = str.Replace("(", "");
            str = str.Replace(")", "");
            str = str.Replace("。", "");

            return str;
        }
        #endregion

        #region 利用Levenshtein方法计算两个字符串的相似率
        /// <summary>
        /// 利用Levenshtein方法计算两个字符串的相似率
        /// </summary>
        /// <param name="str1">字符串1</param>
        /// <param name="str2">字符串2</param>
        /// <returns>相似率</returns>
        private double Similarity1(string str1, string str2)
        {
            str1 = ReplaceSymbol(str1).ToLower();//将字符串str1中的特殊符号去掉,并把字母变成小写
            str2 = ReplaceSymbol(str2).ToLower();//将字符串str2中的特殊符号去掉,并把字母变成小写
            double maxlen = str1.Length > str2.Length ? str1.Length : str2.Length;//取两个字符串长度中的较大的值,赋值给maxlen
            var le = new Levenshtein();//实例化一个名称为le的Levenshtein对象,用于求从一个字符串变换到另一个字符串所需要的最短距离(步骤)
            double SimilarityRate = (1 - le.Distance(str1, str2) / maxlen);//计算相似率,其中le.Distance(str1,str2)为两个字符串转换的最短路径(步骤)
            return SimilarityRate;//返回相似率
        }


        #endregion

        #region 计算字符串相似度
        /// <summary>
        /// 获取两个字符串的相似度
        /// </summary>
        /// <param name=”str1”>第一个字符串</param>
        /// <param name=”str2”>第二个字符串</param>
        /// <returns></returns>
        private double Similarity2(string str1, string str2)
        {
            str1 = ReplaceSymbol(str1).ToLower();
            str2 = ReplaceSymbol(str2).ToLower();
            double Kq = 2;
            double Kr = 1;
            double Ks = 1;

            char[] ss = str1.ToCharArray();
            char[] st = str2.ToCharArray();

            //获取交集数量
            int q = ss.Intersect(st).Count();
            int s = ss.Length - q;
            int r = st.Length - q;

            return Kq * q / (Kq * q + Kr * r + Ks * s);
        }
        #endregion

        private bool IsContain(string str1, string str2)
        {

            str1 = ReplaceSymbol(str1).ToLower();
            str2 = ReplaceSymbol(str2).ToLower();
            return str2.Contains(str1);
        }

        private void Btn_SearchSimilarity_Click(object sender, EventArgs e)
        {
            flag_SearchStop = false;
            btn_Stop.Focus();
            matchRow.Clear();//清空集合matchRow中的数据
            dataGridView1.Rows.Clear();//清除dataGridView1表格数据
            btn_SearchContain.Enabled = false;
            SearchSimilarity();//调用“搜索相似”方法
            btn_SearchContain.Enabled = true;

        }

        private void Btn_SearchContain_Click(object sender, EventArgs e)
        {
            flag_SearchStop = false;
            btn_Stop.Focus();
            matchRow.Clear();//清空集合matchRow中的数据
            dataGridView1.Rows.Clear();//清除dataGridView1表格数据
            btn_SearchSimilarity.Enabled = false;
            SearchContain();//调用“搜索包含”方法
            btn_SearchSimilarity.Enabled = true;
        }

        /// <summary>
        /// 根据不同格式的Excel获取sheet(因为xlsx格式的Excel和xls格式的Excel获取sheet的方式不一样)
        /// </summary>
        /// <param name="FilePath">文件路径</param>
        /// <param name="fileName">文件名</param>
        /// <returns></returns>
        private NPOI.SS.UserModel.ISheet GetSheet(string FilePath, string fileName, int sheetIndex)
        {
            FileStream fs = new FileStream(FilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);//必须要选择flieShare方式为ReadWrite,这样就可以在文件被打开的时候读取文件信息。
            if ((fileName.Split('.')[fileName.Split('.').Length - 1]).ToLower() == "xlsx")//判断文件1的文件名最后一个.后的字符串是否为xlsx
            {
                NP.XSSFWorkbook wk = new NP.XSSFWorkbook(fs);//实例化一个.xlsx格式的工作簿
                NPOI.SS.UserModel.ISheet sht = wk.GetSheetAt(sheetIndex);//根据“选择sheet”下拉列表框,获取工作表
                return sht;
            }
            else //((fileName1.Split('.')[fileName1.Split('.').Length - 1]).ToLower() == "xls")//判断文件1的文件名最后一个.后的字符串是否为xls
            {
                HSSFWorkbook wk = new HSSFWorkbook(fs);//实例化一个.xls格式的工作簿
                NPOI.SS.UserModel.ISheet sht = wk.GetSheetAt(sheetIndex);//根据“选择sheet”下拉列表框,获取工作表
                return sht;
            }
        }

        bool flag_SearchStop = false;

        private void SearchSimilarity()
        {
            try
            {
                sht1 = GetSheet(FilePath1, fileName1, comboBox_sheet1.SelectedIndex);
                sht2 = GetSheet(FilePath2, fileName2, comboBox_sheet2.SelectedIndex);
                int rowsCount1 = sht1.LastRowNum;//获取工作表sht1的有效行数
                int rowsCount2 = sht2.LastRowNum;//获取工作表sht2的有效行数
                int listNumber = Convert.ToInt32(comboBox_list1.SelectedIndex);//根据“选择列:”下拉列表框的选择索引号,获取列                
                progressBar1.Visible = true;//显示进度条
                progressBar1.Maximum = rowsCount1;//设置进度条的最大值为sht1的行数+1
                lbl_ProgressbarValue.Visible = true;//显示进度条百分比


                for (int i = Convert.ToInt32(comboBox_Row1.Text) - 1; i <= rowsCount1; i++)//i为sht1的行数索引
                {

                    progressBar1.Value = i;//定义进度条的值为i
                    lbl_ProgressbarValue.Text = (i * 100 / progressBar1.Maximum).ToString() + "%";//将进度条百分比赋值给文本框
                    Application.DoEvents();//重点,必须加上,否则窗体会假死
                    if (progressBar1.Value == progressBar1.Maximum)
                    {

                        MessageBox.Show("搜索完成,搜到" + (dataGridView1.Rows.Count - 1).ToString() + "个结果!", "搜索结果提示");
                        progressBar1.Value = 0;//将进度条数据置零
                        progressBar1.Visible = false;//隐藏进度条
                        lbl_ProgressbarValue.Visible = false;//隐藏进度条百分比 
                        btn_SaveSearchResult.Enabled = true;//搜索完成后使能“保存搜索结果”按钮
                        btn_CreateResultExcel.Enabled = true;//搜索完成后使能“生成备件清单”按钮
                    }
                    if (!flag_SearchStop)
                    {
                        if (sht1.GetRow(i).GetCell(listNumber) != null)//如果sht1第i行第listNumber列不为空
                        {
                            string str1 = GetCellValue(sht1, i, listNumber);
                            if (str1 == "")
                            {
                                continue;//如果读取的sht1第i行,第listNumber列单元格的字符串的值为空,则跳出当前循环,进入下一循环
                            }

                            else      //如果读取的sht1第i行,第listNumber列单元格的字符串的值不为空,则继续按下述循环判断sht2中的数据
                            {
                                for (int j = Convert.ToInt32(comboBox_Row2.Text) - 1; j <= rowsCount2; j++)//j为sht2的行数索引
                                {
                                    if (sht2.GetRow(j) != null)
                                    {
                                        if (comboBox_list2.Text == "搜索全部列")
                                        {
                                            for (int k = sht2.GetRow(j).FirstCellNum; k <= sht2.GetRow(j).LastCellNum; k++)//K为sht2的列数索引(或单元格索引)
                                            {
                                                if (sht2.GetRow(j).GetCell(k) != null)      //如果sht2的第j行,第k列的单元格数据不为空
                                                {
                                                    string str2 = GetCellValue(sht2, j, k);
                                                    if (str2 == "")
                                                    {
                                                        continue;//如果读取的sht2第j行,第k列单元格的字符串的值为空,则跳出当前循环,进入下一循环
                                                    }
                                                    else         //如果读取的sht2第j行,第k列单元格的字符串的值不为空,执行如下比较字符串相似度的语句
                                                    {
                                                        double Simi = Similarity1(str1, str2) > Similarity2(str1, str2) ? Similarity1(str1, str2) : Similarity2(str1, str2);
                                                        if (Simi >= Convert.ToDouble(comboBox_accuracy.Text) / 100)
                                                        {
                                                            WriteToDateGridView(i, j, str1, str2);  //调用 WriteToDateGridView函数,将搜索结果显示到dateGridView里 
                                                            ListAdd(i);//将匹配的行数存入集合中
                                                        }
                                                    }
                                                }
                                                else
                                                {
                                                    continue;//如果sht1第i行第listNumber列为空,则跳出当前循环,进入下一循环;
                                                }
                                            }
                                        }
                                        else   //如果sheet2选择了列,则不搜索全部列,只搜索选择的列,可以大大减少搜索次数,提高搜索速度
                                        {
                                            if (sht2.GetRow(j).GetCell(comboBox_list2.SelectedIndex - 1) != null)      //如果sht2的第j行,第k列的单元格数据不为空
                                            {
                                                string str2 = GetCellValue(sht2, j, comboBox_list2.SelectedIndex - 1);
                                                if (str2 == "")
                                                {
                                                    continue;//如果读取的sht2第j行,第k列单元格的字符串的值为空,则跳出当前循环,进入下一循环
                                                }
                                                else         //如果读取的sht2第j行,第k列单元格的字符串的值不为空,执行如下比较字符串相似度的语句
                                                {
                                                    double Simi = Similarity1(str1, str2) > Similarity2(str1, str2) ? Similarity1(str1, str2) : Similarity2(str1, str2);
                                                    if (Simi >= Convert.ToDouble(comboBox_accuracy.Text) / 100)
                                                    {
                                                        WriteToDateGridView(i, j, str1, str2); //调用 WriteToDateGridView函数,将搜索结果显示到dateGridView里
                                                        ListAdd(i);//将匹配的行数存入集合中
                                                    }
                                                }
                                            }
                                            else
                                            {
                                                continue;//如果sht1第i行第listNumber列为空,则跳出当前循环,进入下一循环;
                                            }
                                        }

                                    }
                                    else
                                    {
                                        continue;
                                    }

                                }
                            }
                        }
                        else
                        {
                            continue;
                        }
                    }
                    else
                    {
                        break;
                    }


                }
            }

            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString() + "\r\n" + "1.请检查是否选择文件!" + "\r\n" + "2.请检查文件的sheet和列是否选择正确!", "错误提示"); //抛出异常信息
            }
        }

        private void SearchContain()
        {
            try
            {
                sht1 = GetSheet(FilePath1, fileName1, comboBox_sheet1.SelectedIndex);
                sht2 = GetSheet(FilePath2, fileName2, comboBox_sheet2.SelectedIndex);
                int rowsCount1 = sht1.LastRowNum;//获取工作表sht1的有效行数
                int rowsCount2 = sht2.LastRowNum;//获取工作表sht2的有效行数
                int listNumber = Convert.ToInt32(comboBox_list1.SelectedIndex);//根据“选择列:”下拉列表框的选择索引号,获取列                
                progressBar1.Visible = true;//显示进度条
                progressBar1.Maximum = rowsCount1;//设置进度条的最大值为sht1的行数+1
                lbl_ProgressbarValue.Visible = true;//显示进度条百分比


                for (int i = Convert.ToInt32(comboBox_Row1.Text) - 1; i <= rowsCount1; i++)//i为sht1的行数索引
                {
                    progressBar1.Value = i;//定义进度条的值为i
                    lbl_ProgressbarValue.Text = (i * 100 / progressBar1.Maximum).ToString() + "%";//将进度条百分比赋值给文本框
                    Application.DoEvents();//重点,必须加上,否则窗体会假死
                    if (progressBar1.Value == progressBar1.Maximum)
                    {
                        MessageBox.Show("搜索完成,搜到" + (dataGridView1.Rows.Count - 1).ToString() + "个结果!", "搜索结果提示");
                        progressBar1.Value = 0;//将进度条数据置零
                        progressBar1.Visible = false;//隐藏进度条
                        lbl_ProgressbarValue.Visible = false;//隐藏进度条百分比                        
                    }
                    if (!flag_SearchStop)
                    {
                        if (sht1.GetRow(i).GetCell(listNumber) != null)//如果sht1第i行第listNumber列不为空
                        {
                            string str1 = GetCellValue(sht1, i, listNumber);
                            if (str1 == "")
                            {
                                continue;//如果读取的sht1第i行,第listNumber列单元格的字符串的值为空,则跳出当前循环,进入下一循环
                            }

                            else      //如果读取的sht1第i行,第listNumber列单元格的字符串的值不为空,则继续按下述循环判断sht2中的数据
                            {
                                for (int j = Convert.ToInt32(comboBox_Row2.Text) - 1; j <= rowsCount2; j++)//j为sht2的行数索引
                                {
                                    if (sht2.GetRow(j) != null)
                                    {
                                        if (comboBox_list2.Text == "搜索全部列")
                                        {
                                            for (int k = sht2.GetRow(j).FirstCellNum; k <= sht2.GetRow(j).LastCellNum; k++)//K为sht2的列数索引(或单元格索引)
                                            {
                                                if (sht2.GetRow(j).GetCell(k) != null)      //如果sht2的第j行,第k列的单元格数据不为空
                                                {
                                                    string str2 = GetCellValue(sht2, j, k);
                                                    if (str2 == "")
                                                    {
                                                        continue;//如果读取的sht2第j行,第k列单元格的字符串的值为空,则跳出当前循环,进入下一循环
                                                    }
                                                    else         //如果读取的sht2第j行,第k列单元格的字符串的值不为空,执行如下比较字符串相似度的语句
                                                    {

                                                        if (IsContain(str1, str2))
                                                        {
                                                            WriteToDateGridView(i, j, str1, str2);  //调用 WriteToDateGridView函数,将搜索结果显示到dateGridView里 
                                                            ListAdd(i);//将匹配的行数存入集合中
                                                        }
                                                    }
                                                }
                                                else
                                                {
                                                    continue;//如果sht1第i行第listNumber列为空,则跳出当前循环,进入下一循环;
                                                }
                                            }
                                        }
                                        else    //如果sheet2选择了列,则不搜索全部列,只搜索选择的列,可以大大减少搜索次数,提高搜索速度
                                        {
                                            if (sht2.GetRow(j).GetCell(comboBox_list2.SelectedIndex - 1) != null)      //如果sht2的第j行,第k列的单元格数据不为空
                                            {
                                                string str2 = GetCellValue(sht2, j, comboBox_list2.SelectedIndex - 1);
                                                if (str2 == "")
                                                {
                                                    continue;//如果读取的sht2第j行,第k列单元格的字符串的值为空,则跳出当前循环,进入下一循环
                                                }
                                                else         //如果读取的sht2第j行,第k列单元格的字符串的值不为空,执行如下比较字符串相似度的语句
                                                {

                                                    if (IsContain(str1, str2))
                                                    {
                                                        WriteToDateGridView(i, j, str1, str2); //调用 WriteToDateGridView函数,将搜索结果显示到dateGridView里 
                                                        ListAdd(i);//将匹配的行数存入集合中
                                                    }
                                                }
                                            }
                                            else
                                            {
                                                continue;//如果sht1第i行第listNumber列为空,则跳出当前循环,进入下一循环;
                                            }
                                        }

                                    }
                                    else
                                    {
                                        continue;
                                    }

                                }
                            }
                        }
                        else
                        {
                            continue;
                        }
                    }
                    else
                    {
                        break;
                    }
                }
            }

            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString() + "\r\n" + "1.请检查是否选择文件!" + "\r\n" + "2.请检查文件的sheet和列是否选择正确!", "错误提示"); //抛出异常信息
            }
        }
        private void Btn_Clear_Click(object sender, EventArgs e)
        {
            dataGridView1.Rows.Clear();//清除dataGridView1表格数据
            matchRow.Clear();//清空集合matchRow中的数据
            progressBar1.Value = 0;//将进度条数据置零
            progressBar1.Visible = false;//隐藏进度条
            lbl_ProgressbarValue.Visible = false;//隐藏进度条百分比
            btn_SaveSearchResult.Enabled = false;//让“保存搜索结果”按钮无效
            btn_CreateResultExcel.Enabled = false;//让“生成备件清单”按钮无效
            //button1.Visible = true;
        }

        /// <summary>
        /// 将搜索结果显示到dateGridView里
        /// </summary>
        /// <param name="i">str1所在的行数</param>
        /// <param name="j">str1所在的行数</param>
        /// <param name="str1">sheet1中的字符串</param>
        /// <param name="str2">sheet2中的字符串</param>
        private void WriteToDateGridView(int i, int j, string str1, string str2)
        {
            int index = this.dataGridView1.Rows.Add();
            this.dataGridView1.Rows[index].Cells[0].Value = (index + 1).ToString();
            this.dataGridView1.Rows[index].Cells[1].Value = "第" + (i + 1).ToString() + "行";
            this.dataGridView1.Rows[index].Cells[2].Value = str1;
            this.dataGridView1.Rows[index].Cells[3].Value = "第" + (j + 1).ToString() + "行";
            this.dataGridView1.Rows[index].Cells[4].Value = str2;
        }

        private string GetCellValue(NPOI.SS.UserModel.ISheet sht, int i, int j)
        {
            string str = "";//声明字符串变量str2
            string cell_Type = sht.GetRow(i).GetCell(j).CellType.ToString();//获取sht2第j行,第k列单元格的数据格式,并赋值给字符串变量cell_Type2 
            switch (cell_Type)    //根据单元格里的数据格式读取数据的值;
            {
                case "String":
                    str = sht.GetRow(i).GetCell(j).StringCellValue;//按字符串格式读取单元格数据的值
                    break;
                case "Numeric":
                    str = sht.GetRow(i).GetCell(j).NumericCellValue.ToString();//按数值格式读取单元格数据的值
                    break;
            }
            return str;
        }


        private void Btn_SaveSearchResult_Click(object sender, EventArgs e)
        {
            SaveFileDialog saveFileDialog = new SaveFileDialog();
            saveFileDialog.Filter = "Excel files (*.xls)|*.xls";
            saveFileDialog.FilterIndex = 0;
            saveFileDialog.RestoreDirectory = true;
            saveFileDialog.CreatePrompt = true;
            saveFileDialog.Title = "导出Excel文件到";

            DateTime now = DateTime.Now;
            saveFileDialog.FileName = "搜索结果" + "-" + DateTime.Now.ToLongDateString().ToString() + "-" + now.Hour.ToString().PadLeft(2, '0') + "时" + now.Minute.ToString().PadLeft(2, '0') + "分" + now.Second.ToString().PadLeft(2, '0') + "秒";
            saveFileDialog.ShowDialog();

            this.dataGridView1.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
            this.dataGridView1.MultiSelect = false;

            Stream myStream = saveFileDialog.OpenFile();
            StreamWriter sw = new StreamWriter(myStream, System.Text.Encoding.GetEncoding("gb2312"));
            string str = "";
            try
            {
                //写标题     
                for (int i = 0; i < this.dataGridView1.ColumnCount; i++)
                {
                    if (i > 0)
                    {
                        str += "\t";
                    }
                    str += this.dataGridView1.Columns[i].HeaderText;
                }
                sw.WriteLine(str);
                //写内容   
                for (int j = 0; j < this.dataGridView1.Rows.Count; j++)
                {
                    string tempStr = "";
                    for (int k = 0; k < this.dataGridView1.Columns.Count; k++)
                    {
                        if (k > 0)
                        {
                            tempStr += "\t";
                        }
                        if (this.dataGridView1.Rows[j].Cells[k].Value != null)
                        {
                            tempStr += this.dataGridView1.Rows[j].Cells[k].Value.ToString();
                        }
                        else
                        {
                            continue;
                        }

                    }
                    sw.WriteLine(tempStr);
                }
                sw.Close();
                myStream.Close();
                if (File.Exists("搜索结果" + "-" + DateTime.Now.ToLongDateString().ToString() + "-" + now.Hour.ToString().PadLeft(2, '0') + ":" + now.Minute.ToString().PadLeft(2, '0') + ":" + now.Second.ToString().PadLeft(2, '0')))
                {
                    MessageBox.Show("搜索结果保存成功!保存路径与原文件路径相同!", "保存提示");
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
            finally
            {
                sw.Close();
                myStream.Close();
            }
        }

        /// <summary>
        /// “生产备件清单”按钮的的单击事件,根据匹配成功的行数,删除匹配成功的行数,生成备件清单(匹配成功的表示库房已经有这个备件,则该备件不需要采购,所以将其删除后,剩下的即为备件清单)
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Btn_CreateResultExcel_Click(object sender, EventArgs e)
        {
        string ResultPath = System.IO.Path.GetDirectoryName(FilePath1) +"\\"+ "备件清单" + "-" + DateTime.Now.ToLongDateString().ToString()+".xlsx";//指定存储的路径           
            File.Copy(FilePath1, ResultPath, true);//三个参数分别是源文件路径,存储路径,若存储路径有相同文件是否替换
            int deleteTimes = 0;//记录删除行的次数,因为没删除一行,需要删除的行数索引就变了(减少了1)
            for (int i = 0; i <= matchRow.Count-1; i++)
            {
                DeleteRows(ResultPath, (Int32)matchRow[i]+1-deleteTimes);
                deleteTimes++;
            }
            //生成成功提示。
            if (File.Exists(ResultPath))
            {
                MessageBox.Show("备件清单生成成功!保存路径与原文件路径相同!", "保存提示");
            }
            else
            {
                MessageBox.Show("备件清单生成失败!", "保存提示");
            }
        }

        /// <summary>
        /// 删除Excel文件中的特定行(上移并覆盖)
        /// </summary>
        /// <param name="FilePath">需要删除的Excel文件全路径</param>
        /// <param name="rowIndex">需要删除的行数索引</param>
        private void DeleteRows(string FilePath, int rowIndex)//(Excel.Worksheet sheet, int rowIndex)
        {
            FileStream fs = new FileStream(FilePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);//必须要选择flieShare方式为ReadWrite,这样就可以在文件被打开的时候读取文件信息。
            NP.XSSFWorkbook wk = new NP.XSSFWorkbook(fs);//实例化一个.xlsx格式的工作簿
            NPOI.SS.UserModel.ISheet sht = wk.GetSheetAt(comboBox_sheet1.SelectedIndex);//根据“选择sheet”下拉列表框,获取工作表           
            sht.ShiftRows(rowIndex, sht.LastRowNum, -1);//将从第rowIndex行到最后一行的数据向上移动一行,即将rowIndex-1行删除了
            FileStream file = new FileStream(FilePath, FileMode.Create);//实例化一个FileStream文件
            wk.Write(file);//将file文件流写入wk工作簿
            file.Close();//关闭文件流
        }

        /// <summary>
        /// 判断matchRow里是否存在当前行索引号(因为文件1中的某一行可能搜索出多个相似结果,经过判断后可以避免重复存入相同的行数到matchRow中,导致生成备件清单时删除错误)
        /// </summary>
        /// <param name="i">当前行索引号</param>
        private void ListAdd(int i)
        {
            if (!matchRow.Contains(i))//判断集合matchRow中是否包含i
            {
                matchRow.Add(i);//如果不包含,则将i添加到matchRow中
            }
            else
            {
                return;//如果包含,则返回
            }
        }

        private void Located()//(string filePath,)
        {
            string excelName = FilePath1;//你的excel文件的位置
            string sheetName = "sheet1";//你的sheet的名字
            string strStart = "A100";//起始单元格
            string strEnd = "B200";//结束单元格
            object missing = Type.Missing;
            Excel.Application excel = new Excel.Application();
            Excel.Workbook book = excel.Workbooks.Open(excelName, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing, missing);
            Excel.Worksheet sheet = (Excel.Worksheet)book.Worksheets[sheetName];
            excel.Application.Goto(sheet.Range[strStart, strEnd], true);
            excel.Visible = true;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            this.Resize += new EventHandler(Form1_Resize);
            X = this.Width;
            Y = this.Height;
            setTag(this);
            Form1_Resize(new object(), new EventArgs());
        }
        //***控制控件大小及文字大小开始***//
        private float X;
        private float Y;
        private void setTag(Control cons)
        {
            foreach (Control con in cons.Controls)
            {
                con.Tag = con.Width + ":" + con.Height + ":" + con.Left + ":" + con.Top + ":" + con.Font.Size;
                if (con.Controls.Count > 0)
                    setTag(con);
            }
        }
        private void setControls(float newx, float newy, Control cons)
        {
            foreach (Control con in cons.Controls)
            {
                string[] mytag = con.Tag.ToString().Split(new char[] { ':' });
                float a = Convert.ToSingle(mytag[0]) * newx;
                con.Width = (int)a;
                a = Convert.ToSingle(mytag[1]) * newy;
                con.Height = (int)(a);
                a = Convert.ToSingle(mytag[2]) * newx;
                con.Left = (int)(a);
                a = Convert.ToSingle(mytag[3]) * newy;
                con.Top = (int)(a);
                Single currentSize = Convert.ToSingle(mytag[4]) * Math.Min(newx, newy);
                con.Font = new Font(con.Font.Name, currentSize, con.Font.Style, con.Font.Unit);
                if (con.Controls.Count > 0)
                {
                    setControls(newx, newy, con);
                }
            }
        }
        void Form1_Resize(object sender, EventArgs e)
        {
            float newx = (this.Width) / X;
            float newy = this.Height / Y;
            setControls(newx, newy, this);
            //this.Text = "窗体尺寸:" + this.Width.ToString() + " " + this.Height.ToString();
        }
        //***控制控件大小及文字大小结束***//


        private void Button1_Click(object sender, EventArgs e)
        {
            Located();            
        }

        private void DataGridView1_DoubleClick(object sender, EventArgs e)
        {
            //Located();
        }

        private void Btn_Help_Click(object sender, EventArgs e)
        {
            using (Form_Help dlg = new Form_Help()) //Form_Help是窗口类名,确保访问;后面的是构造函数
            {
                dlg.ShowDialog();
            }
        }

        private void Btn_Stop_Click(object sender, EventArgs e)
        {
            flag_SearchStop = true;
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值