diff --git a/ConsoleApp1/ConsoleApp1.csproj b/ConsoleApp1/ConsoleApp1.csproj index 392da02e..42fc49a5 100644 --- a/ConsoleApp1/ConsoleApp1.csproj +++ b/ConsoleApp1/ConsoleApp1.csproj @@ -7,7 +7,7 @@ - + diff --git a/ConsoleApp1/Program.cs b/ConsoleApp1/Program.cs index 05546ee7..03daec69 100644 --- a/ConsoleApp1/Program.cs +++ b/ConsoleApp1/Program.cs @@ -1,55 +1,123 @@ -using AsbCloudApp.Data; -using AsbCloudDb.Model; -using AsbCloudInfrastructure.Services; -using AsbCloudInfrastructure.Services.Cache; -using DocumentFormat.OpenXml; -using DocumentFormat.OpenXml.Packaging; -using DocumentFormat.OpenXml.Spreadsheet; -//using AsbSaubReport; +//using AsbSaubReport; //using AutoMapper; -using Microsoft.EntityFrameworkCore; using System; +using System.IO; +using System.Collections.Generic; +using System.Linq; +using ClosedXML.Excel; namespace ConsoleApp1 { + //var options = new DbContextOptionsBuilder() + // .UseNpgsql("Host=localhost;Database=postgres;Username=postgres;Password=q;Persist Security Info=True") + // .Options; + //var context = new AsbCloudDbContext(options); + + class Program { + private static void RemovePicturesFromSheet(IXLWorksheet sheet) + { + var picsNames = new List(); + + foreach (var p in sheet.Pictures) + picsNames.Add(p.Name); + + var filteredPics = picsNames.Distinct(); + + foreach (var n in filteredPics) + sheet.Pictures.Delete(n); + } + + private static IXLRange GetCellsRange(IXLWorksheet sheet) + { + var firstTableCell = sheet.FirstCellUsed(); + var lastTableCell = sheet.LastCellUsed(); + var rngData = sheet.Range(firstTableCell.Address, lastTableCell.Address); + + return rngData; + } static void Main(/*string[] args*/) { - - //var options = new DbContextOptionsBuilder() - // .UseNpgsql("Host=localhost;Database=postgres;Username=postgres;Password=q;Persist Security Info=True") - // .Options; - //var context = new AsbCloudDbContext(options); - - var fileNames = new string[] { @"d:\temp\1\book1.xlsx", @"d:\temp\1\book2.xlsx" }; - - using var spreadsheetDocument = SpreadsheetDocument.Create(@"d:\temp\1\b.xlsx", SpreadsheetDocumentType.Workbook); - // Add a WorkbookPart and Workbook objects. - WorkbookPart workbookpart = spreadsheetDocument.AddWorkbookPart(); - workbookpart.Workbook = new Workbook(); - - // Add a WorksheetPart to the WorkbookPart. - WorksheetPart worksheetPart = workbookpart.AddNewPart(); - worksheetPart.Worksheet = new Worksheet(new SheetData()); - - // Add Sheets to the Workbook. - Sheets sheets = spreadsheetDocument.WorkbookPart.Workbook. - AppendChild(new Sheets()); - - // Append a new worksheet and associate it with the workbook. - Sheet sheet = new Sheet() + var sourceExcelPaths = new List { - Id = spreadsheetDocument.WorkbookPart. - GetIdOfPart(worksheetPart), - SheetId = 1, - Name = "mySheetNameISHere!" + //@"D:\excels\excel1.xlsx", + //@"D:\excels\excel2.xlsx" + //@"D:\excels\e1.xlsx", + @"D:\excels\e2.xlsx", + @"D:\excels\e3.xlsx", + @"D:\excels\e4.XLSX", + @"D:\excels\e5.XLSX", + @"D:\excels\e6.XLSX" }; - sheets.Append(sheet); - spreadsheetDocument.Save(); - spreadsheetDocument.Close(); + const string resultExcelPath = @"D:\excels\result.xlsx"; + + using var resultExcelFile = new XLWorkbook(); + + const int maxAllowedColumns = 256; + + foreach(var sourceExcelPath in sourceExcelPaths) + { + using var sourceExcelFile = new XLWorkbook(sourceExcelPath); + + foreach (var sheet in sourceExcelFile.Worksheets) + { + // Если в файле очень много колонок и многие из них пустые - + // предлагаем удалить их вручную или пытаемся копировать + // ячейки попорядку (не красиво). Красиво не получится. + if (sheet.Columns().Count() > maxAllowedColumns && + sheet.Columns().Count() / sheet.ColumnsUsed().Count() > 5) + { + Console.WriteLine($"В файле {Path.GetFileName(sourceExcelPath)} " + + $"{sheet.Columns().Count() - sheet.ColumnsUsed().Count()} пустых колонок " + + $"без записей. \n Если продолжить выполнение, форматирование выходного" + + $"листа может быть нарушено. \n Для сохранения структуры документа " + + $"рекомендуется прервать выполнение и удалить неиспользуемые колонки. \n" + + $" Продолжить выполнение? (y/n)"); + + var res = Console.ReadLine(); + + if (res != "y") + return; + + var rngData = GetCellsRange(sheet); + + RemovePicturesFromSheet(sheet); + + var wsCopy = resultExcelFile.Worksheets.Add(sheet.Name); + wsCopy.Cell(1, 1).Value = rngData; + + GC.Collect(); + } + // Если колонок в файле немного, но среди них также есть пустые - + // проще удалить ненужные колонки и скопировать лист красиво. + 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(); + } + } + } + + resultExcelFile.SaveAs(resultExcelPath); Console.WriteLine("Done. Press any key to quit."); Console.ReadKey();