diff --git a/ConsoleApp1/Program.cs b/ConsoleApp1/Program.cs index 03daec69..b270c901 100644 --- a/ConsoleApp1/Program.cs +++ b/ConsoleApp1/Program.cs @@ -5,6 +5,7 @@ using System.IO; using System.Collections.Generic; using System.Linq; using ClosedXML.Excel; +using ClosedXML.Excel.Drawings; namespace ConsoleApp1 { @@ -13,17 +14,40 @@ namespace ConsoleApp1 // .Options; //var context = new AsbCloudDbContext(options); + class ImageInfo + { + public int Id { get; set; } + public byte[] Data { get; set; } + public int Height { get; set; } + public int Width { get; set; } + public IXLAddress TopLeftCellAddress { get; set; } + public int Left { get; set; } + public int Top { get; set; } + } class Program { + private static IXLWorksheet CopyImagesToAnotherSheet(IEnumerable imagesInfos, + IXLWorksheet resultSheet) + { + foreach (var image in imagesInfos) + { + var stream = new MemoryStream(); + stream.Write(image.Data, 0, image.Data.Length); + + resultSheet.AddPicture(stream) + .WithPlacement(XLPicturePlacement.Move) + .WithSize(image.Width, image.Height) + .MoveTo(resultSheet.Cell(image.TopLeftCellAddress), + image.Left, image.Top); + } + + return resultSheet; + } + private static void RemovePicturesFromSheet(IXLWorksheet sheet) { - var picsNames = new List(); - - foreach (var p in sheet.Pictures) - picsNames.Add(p.Name); - - var filteredPics = picsNames.Distinct(); + var filteredPics = sheet.Pictures.Select(p => p.Name).Distinct().ToList(); foreach (var n in filteredPics) sheet.Pictures.Delete(n); @@ -54,65 +78,55 @@ namespace ConsoleApp1 const string resultExcelPath = @"D:\excels\result.xlsx"; - using var resultExcelFile = new XLWorkbook(); + using var resultExcelFile = new XLWorkbook(XLEventTracking.Disabled); const int maxAllowedColumns = 256; foreach(var sourceExcelPath in sourceExcelPaths) { - using var sourceExcelFile = new XLWorkbook(sourceExcelPath); + using var sourceExcelFile = new XLWorkbook(sourceExcelPath, XLEventTracking.Disabled); + + Console.WriteLine($"Добавляется файл {Path.GetFileName(sourceExcelPath)}"); foreach (var sheet in sourceExcelFile.Worksheets) { - // Если в файле очень много колонок и многие из них пустые - - // предлагаем удалить их вручную или пытаемся копировать - // ячейки попорядку (не красиво). Красиво не получится. - if (sheet.Columns().Count() > maxAllowedColumns && - sheet.Columns().Count() / sheet.ColumnsUsed().Count() > 5) + var imagesInfos = sheet.Pictures.Select(p => new ImageInfo { - Console.WriteLine($"В файле {Path.GetFileName(sourceExcelPath)} " + - $"{sheet.Columns().Count() - sheet.ColumnsUsed().Count()} пустых колонок " + - $"без записей. \n Если продолжить выполнение, форматирование выходного" + - $"листа может быть нарушено. \n Для сохранения структуры документа " + - $"рекомендуется прервать выполнение и удалить неиспользуемые колонки. \n" + - $" Продолжить выполнение? (y/n)"); + Id = p.Id, + Data = p.ImageStream.GetBuffer(), + Height = p.Height, + Width = p.Width, + TopLeftCellAddress = p.TopLeftCell.Address, + Left = p.Left, + Top = p.Top + }).ToList(); - var res = Console.ReadLine(); - - if (res != "y") - return; + if (sheet.Columns().Count() > maxAllowedColumns) + { + var resultSheet = resultExcelFile.Worksheets.Add(sheet.Name); var rngData = GetCellsRange(sheet); - RemovePicturesFromSheet(sheet); + rngData.CopyTo(resultSheet.Cell(1, 1)); - var wsCopy = resultExcelFile.Worksheets.Add(sheet.Name); - wsCopy.Cell(1, 1).Value = rngData; + var lastRowWithData = rngData.LastRowUsed().RangeAddress + .LastAddress.RowNumber; - GC.Collect(); + for (int i = 1; i < lastRowWithData; i++) + { + resultSheet.Row(i).Height = sheet.Row(i).Height; + resultSheet.Column(i).Width = sheet.Column(i).Width; + } + + CopyImagesToAnotherSheet(imagesInfos, resultSheet); } - // Если колонок в файле немного, но среди них также есть пустые - - // проще удалить ненужные колонки и скопировать лист красиво. - else if (sheet.Columns().Count() < maxAllowedColumns && - sheet.Columns().Count() / sheet.ColumnsUsed().Count() > 2) - { - RemovePicturesFromSheet(sheet); - - var columnsToDelete = sheet.Columns().Skip(sheet.ColumnsUsed().Count()); - - foreach (var d in columnsToDelete) - d.Delete(); - - sheet.CopyTo(resultExcelFile, sheet.Name); - GC.Collect(); - } - // Если по колонкам все хорошо, копируем лист красиво. else { RemovePicturesFromSheet(sheet); - sheet.CopyTo(resultExcelFile, sheet.Name); - GC.Collect(); + var resultSheet = sheet.CopyTo(resultExcelFile, sheet.Name); + + CopyImagesToAnotherSheet(imagesInfos, resultSheet); } } }