Example #1
0
        public static ExcelSheetDiff Diff(ExcelSheet src, ExcelSheet dst, ExcelSheetDiffConfig config)
        {
            var srcColumns      = src.CreateColumns();
            var dstColumns      = dst.CreateColumns();
            var columnStatusMap = CreateColumnStatusMap(srcColumns, dstColumns, config);

            var option = new DiffOption <ExcelRow>();

            option.EqualityComparer =
                new RowComparer(new HashSet <int>(columnStatusMap.Where(i => i.Value != ExcelColumnStatus.None).Select(i => i.Key)));

            foreach (var row in src.Rows.Values)
            {
                var shifted = new List <ExcelCell>();
                var index   = 0;
                var queue   = new Queue <ExcelCell>(row.Cells);
                while (queue.Any())
                {
                    if (columnStatusMap[index] == ExcelColumnStatus.Inserted)
                    {
                        shifted.Add(new ExcelCell(string.Empty, 0, 0));
                    }
                    else
                    {
                        shifted.Add(queue.Dequeue());
                    }

                    index++;
                }

                row.UpdateCells(shifted);
            }

            foreach (var row in dst.Rows.Values)
            {
                var shifted = new List <ExcelCell>();
                var index   = 0;
                var queue   = new Queue <ExcelCell>(row.Cells);
                while (queue.Any())
                {
                    if (columnStatusMap[index] == ExcelColumnStatus.Deleted)
                    {
                        shifted.Add(new ExcelCell(string.Empty, 0, 0));
                    }
                    else
                    {
                        shifted.Add(queue.Dequeue());
                    }

                    index++;
                }

                row.UpdateCells(shifted);
            }

            var r = DiffUtil.Diff(src.Rows.Values, dst.Rows.Values, option);

            r = DiffUtil.Order(r, DiffOrderType.LazyDeleteFirst);
            var resultArray = DiffUtil.OptimizeCaseDeletedFirst(r).ToArray();

            if (resultArray.Length > 10000)
            {
                var count   = 0;
                var indices = Enumerable.Range(0, 100).ToList();
                foreach (var result in resultArray)
                {
                    if (result.Status != DiffStatus.Equal)
                    {
                        indices.AddRange(Enumerable.Range(Math.Max(0, count - 100), 200));
                    }

                    count++;
                }
                indices     = indices.Distinct().ToList();
                resultArray = indices.Where(i => i < resultArray.Length).Select(i => resultArray[i]).ToArray();
            }

            var sheetDiff = new ExcelSheetDiff();

            DiffCells(resultArray, sheetDiff, columnStatusMap);

            return(sheetDiff);
        }
Example #2
0
        private static Dictionary <int, ExcelColumnStatus> CreateColumnStatusMap(
            IEnumerable <ExcelColumn> srcColumns, IEnumerable <ExcelColumn> dstColumns, ExcelSheetDiffConfig config)
        {
            var option = new DiffOption <ExcelColumn>();

            if (config.SrcHeaderIndex >= 0)
            {
                option.EqualityComparer = new HeaderComparer();
                foreach (var sc in srcColumns)
                {
                    sc.HeaderIndex = config.SrcHeaderIndex;
                }
            }

            if (config.DstHeaderIndex >= 0)
            {
                foreach (var dc in dstColumns)
                {
                    dc.HeaderIndex = config.DstHeaderIndex;
                }
            }

            var results = DiffUtil.Diff(srcColumns, dstColumns, option);

            results = DiffUtil.Order(results, DiffOrderType.LazyDeleteFirst);
            results = DiffUtil.OptimizeCaseDeletedFirst(results);
            var ret         = new Dictionary <int, ExcelColumnStatus>();
            var columnIndex = 0;

            foreach (var result in results)
            {
                var status = ExcelColumnStatus.None;
                if (result.Status == DiffStatus.Deleted)
                {
                    status = ExcelColumnStatus.Deleted;
                }
                else if (result.Status == DiffStatus.Inserted)
                {
                    status = ExcelColumnStatus.Inserted;
                }

                ret.Add(columnIndex, status);
                columnIndex++;
            }

            return(ret);
        }