c# 进行EXCEL表格合成

项目目的:实现AB两个表格的数据合成,将B表和A表相同的数据合成,然后将B表格中有的数据A表格中没有的数据搬移到A表

功能介绍:实现动态的数据整合,数据搬移,极大的提高数据对比的准确度和效率

例如下列表格样式

表A:

编号 型号 数量
101 A 10
110 B 11
120 C 12
119 D 13
表B:

编号 型号 数量
119 D 30
110 B 13
120 C 12
130 F 15

表C:

编号 型号 数量
101 A 10
110 B 24
120 C 24
119 D 43
130 F

15

三个表格基本展示了本次实现的功能:表C为最终表格,其合成了AB表中的相同数据,并将B表的数据叠加到新的表格中,将AB全部数据全部合成

本次实现功能拓展性强,可以方便的适应各种形式的表格合成,详细代码参见如下链接,本篇就大概讲述一下基本的实现方法和思路。

扫描二维码关注公众号,回复: 9605393 查看本文章

以下是一段基本excel操作代码主要着重讲述对excel的操作,包括单元格数据的获取,数据的叠加,数据的搬移以及一些解决思路

(1)获取单元格的内容

 
 
using Microsoft.Office.Interop.Excel;
using System;
//using Microsoft.Offic
using System.IO;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;

using System.Data;
using System.Configuration;
using Microsoft.Office.Core;
using System.Web;

namespace csgui
{
    class ExcelCopyer
    {
        public const String SHEET_NAME_MAIN = "BOM";//(主MAINBOM)主表格

        public const String SHEET_NAME_DISTRIBUTION = "BOM";//(DESTBOM)目标表格

        public const String FLAG_DEST_SHEET = "标记"; // 主表格,Sheet页数据标识

        //public const String FLAG_DISTRIBUTION_SHEET = "DESTBOM"; // 次表格 Sheet页数据标示

        public delegate void UpdateExcelProgress(int detal);

        /*进行sheet的查找,找出指定名称的sheet表格*/
        /*dst  MAIN表格所在路径 out_path DEST表格所在路径 */
        public static int copy(String[] from, String main_path, out String dest_path, UpdateExcelProgress uep, int progressSum)
        {
         
            Application app = new Application();
            Workbooks wbs = app.Workbooks;
            _Workbook Main = null;
            String ex = "";
            _Worksheet mainSheet = null; // 声明主BOM
            _Worksheet datasheet = null;  //声明DESTBOM
            float sheet_average = 10f; // 假设每个Excel有10个sheet
            float eachSheetAverageProgress = progressSum / (from.Length * sheet_average); // 平均每个Sheet页的进度

            try
            {
                Main = wbs.Open(main_path);  //MAIN表格所在路径
                // 在目标sheet中匹配相应的Sheet页(两个sheet页查找,完成基本的数据分析)

                foreach (_Worksheet sheet in Main.Worksheets)
                {
                    if (SHEET_NAME_MAIN.Equals(sheet.Name))
                    {
                        mainSheet = sheet;
                        String mainname = mainSheet.Cells[1, 1].Text;
                        String mainname2 = mainSheet.Cells[2, 1].Text;
                    }
                }

               // Console.WriteLine("main sheet: " + mainSheet == null ? "null" : mainSheet.ToString());
                //与上面的合并就可以实现两个sheet表的同步合并检测
                /*  + " , distribution sheet: " + distributionSheet == null ? "null" : distributionSheet.ToString());*/
                //_Workbook dstWb = wbs.Add(dst);
                _Workbook Dest = null;
                //设置MAINBOM和DESTBOM的索引起点
                int  mainRowStart = 8;
               foreach (String path in from)

                {
                    try
                    {
                        Dest = wbs.Open(path);//DEST目标表格所在路径
                        foreach (_Worksheet sheet1 in Dest.Worksheets)
                        {
                            if (SHEET_NAME_DISTRIBUTION.Equals(sheet1.Name))
                            {
                                datasheet = sheet1;
                                //进行第二部的数据确定                       
                                String s2 = datasheet.Cells[1, 1].Text;
                                if (FLAG_DEST_SHEET.Equals(s2))
                                {
                                    // 是MAINBOM
                                    //mainRowStart = addMainSheeCell(mainSheet, mainRowStart, sheet);
                                    addMainSheeCell(datasheet, mainRowStart, mainSheet);
                                }
                                else
                                {
                                    return 1;
                                }
                            }
                            //uep(average);
                        }
                  
                        Dest.Close();
                    }
                    //异常处理函数,当数据读到空的时候直接关闭当下的EXCEL表
                    catch (Exception e)
                    {
                        if (Dest == null)
                        {
                           Dest.Close();
                        }
                        ex += ex + "\r\n" + e.Message;
                        continue;
                    }


                }

                //wb.Worksheets.Copy(Missing.Value, dstWb.Worksheets[dstWb.Worksheets.Count]);
            }
            catch (Exception e)
            {
                if (Main == null)
                {
                    Main.Close();
                }

                app.Quit();
                System.Runtime.InteropServices.Marshal.ReleaseComObject(app);
                app = null;
                dest_path = ex + "\r\n" + e.Message;
                return -1;
            }
            finally
            {
                dest_path = ex;
            }


            String name = main_path;
            String suffix = ".xlsx";
            int idx = main_path.LastIndexOf('.');
            if (idx > 0)
            {
                name = main_path.Substring(0, idx);
                suffix = main_path.Substring(idx, main_path.Length - idx);
            }

            String newName = "";
            for (int i = 1; i <= int.MaxValue; ++i)
            {
                newName = name + i + suffix;
                if (!File.Exists(newName))
                {
                    break;
                }

            }

            dest_path = newName;
            app.AlertBeforeOverwriting = false;
            app.DisplayAlerts = false;
            if ("导入进度表".Equals(Main.Worksheets.get_Item(1).Name))
            {
                Main.Worksheets.get_Item(1).Delete();
            }

            Main.SaveAs(newName);
            Main.Close();

            app.Quit();
            System.Runtime.InteropServices.Marshal.ReleaseComObject(app);
            app = null;
            return 0;
        }
        
        //对dasheet[n,13]数据循环处理
         public static  int   addOtherSheetCell(int num, _Worksheet  datasheet_2)
        {
            String result = "0";
            for (int i = 8; i <=num; i++)
            {
                datasheet_2.Cells[i, 13] = result;    
                         
            }
            return 0;
        }
        //将和main相同的数据进行更改
        public static void change_datasheet( int num1,_Worksheet  datasheet_3)
        {
            String result1 = "1";
            datasheet_3.Cells[num1, 13] = result1;
            changeCell(datasheet_3.Cells[num1, 13]);
        }
        //将二者差异化数据加载到最终表格中
        public static void addTomainbom(int datasheet_num2, int mainsheet_num2, int[] s2, _Worksheet mainsheet_2, _Worksheet datasheet_4, int M)
        {
            _Worksheet mainsheet = null;
            _Worksheet datasheet = null;
            mainsheet = mainsheet_2;
            datasheet = datasheet_4;
            List<int> strList = new List<int>();
            //两个lists实现数据从一个list中剔除不需要的数据,然后转换为新的数组
            List<int> pass = new List<int>(s2);

            int[] sum3 = new int[datasheet_num2 - 8];

            //将datasheet个行生成一个新的list
            for (int num = 8; num <= datasheet_num2; num++)
            {
                strList.Add(num);
            }

            //逆序去除制定的相同项目
            var expectedList = strList.Except(pass);


            int[] M3 = new int[datasheet_num2 - 8];
            M3 = expectedList.ToArray();
            for (int num3 = 0; num3 <= M3.Length - 1; num3++)
            {
                int m = M3[num3];
                for (int index = 1; index <= 10; index++)
                {
                    mainsheet.Cells[mainsheet_num2+1, index] = datasheet.Cells[m, index].Text;
                    
                }
                mainsheet_num2++;
            }
        
             
        }
        //设置单元格属性
        /*函数功能:数据合并
          实现思想:数据索引->数据替换->数据记录->数据叠加
          实现步骤:框架(可以索引,替换)->数据叠加(生成有效表格)->数据进行有效的排序(最终结果)
          */

        private static int addMainSheeCell(_Worksheet dataSheet1, int disRowStart, _Worksheet  mainSheet1)
        {
            String code = null;
            String code1 = null;
            String standard = null;
            String numbers = null;  
            String standard1 = null;
            String numbers1 = null;
            int M = 0;
            int mainRowStart = disRowStart;
        
            //DESTBOM行列数据
            int dest_rows = dataSheet1.UsedRange.Rows.Count ;
            //MAINBOM行列数据
            int main_rows = mainSheet1.UsedRange.Rows.Count;

            int [] s1 = new int[dest_rows]; //定义字符数组,将相同的行数进行保存
            int rowIdx = 8;
            addOtherSheetCell(dest_rows,dataSheet1);

            //外部循环,检查mainbom的数据
            for (int Main = 1; Main <= main_rows - 7; Main++)
            {
                //进行Mainbom的内部循环,进行内部与外部的数据对比
                for (int Dest = 1; Dest <= dest_rows - 7; Dest++)
                {
                    //code = mainSheet1.Cells[mainRowStart, 1].Text;  // 产品名字
                    standard = mainSheet1.Cells[mainRowStart, 2].Text; // 产品规格
                    numbers = mainSheet1.Cells[mainRowStart, 10].Text;  // 产品数量   
                    int numbersDouble = int.Parse(numbers);

                    //code1 = dataSheet1.Cells[disRowStart, 1].Text;      // 产品名字
                    standard1 = dataSheet1.Cells[disRowStart, 2].Text;  // 产品规格
                    numbers1 = dataSheet1.Cells[disRowStart, 10].Text;   // 产品数量  
                    int numbersDouble1 = int.Parse(numbers1);


                    // if (string.Equals(code, code1) == true || string.Equals(standard, standard1) == true)//进行产品编号和产品规格的对比
                    if (string.Equals(standard, standard1) == true)//进行产品编号和产品规格的对比
                    {
                        // code = code1;
                        standard = standard1;
                        mainSheet1.Cells[mainRowStart, 10] = numbersDouble + numbersDouble1;
                        changeCell(mainSheet1.Cells[mainRowStart, 10]);//缺少数据的索引和合并,首先应该实现的是相同数据的叠加,为后者留下接口函数

                        s1[M] = disRowStart;
                        M++;
                        change_datasheet(disRowStart, dataSheet1); //改变相同的数据行
                        numbersDouble1 = 0;
                        numbersDouble = 0;
                        code1 = null;
                        standard1 = null;
                        numbers1 = null;

                    }
                    numbersDouble1 = 0;
                    numbersDouble = 0;
                    if (disRowStart < dest_rows)
                    {
                        disRowStart++;
                    }
                }
                if (mainRowStart < main_rows)
                {
                    rowIdx = rowIdx + 1;
                    mainRowStart++;
                    disRowStart = 8;
                    code = null;
                    standard = null;
                    numbers = null;
                }

                if (mainRowStart >= main_rows)
                {
                addTomainbom(dest_rows, main_rows, s1, mainSheet1, dataSheet1, M);
                }
            }

            return disRowStart;
        }

        private static void changeCell(Range range)//设置单元格数据的格式
        {
            // 所有文本居中
            range.HorizontalAlignment = Microsoft.Office.Interop.Excel.XlVAlign.xlVAlignCenter;
        }

        public static void openExcel(String path)
        {
            Application excel = new Application();
            excel.Visible = true;
            Workbook wb = excel.Application.Workbooks.Add(path);
           // wb.Close();
            //excel.Quit();
           // System.Runtime.InteropServices.Marshal.ReleaseComObject(excel);
        }

        /*
        static void Main(string[] args)
        {
            String s;
            copy(new String[] { "from1", "from2" }, "dst path", out s);
        }
        */
    }
}



发布了34 篇原创文章 · 获赞 16 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/xuxudeta/article/details/80445459