using AsbCloudApp.Data; using AsbCloudApp.Services; using NPOI.SS.UserModel; using NPOI.XSSF.UserModel; using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; namespace AsbCloudInfrastructure.Services { public class DrillingProgramApacheService : IDrillingProgramApacheService { private readonly IFileService fileService; private readonly IWellService wellService; private const int idFileCategoryDrillingProgramItems = 13; private const int idFileCategoryDrillingProgram = 14; public DrillingProgramApacheService(IFileService fileService, IWellService wellService) { this.fileService = fileService; this.wellService = wellService; } public async Task GetAsync(int idWell, CancellationToken token = default) { var filesInfos = await fileService.GetInfosByCategoryAsync(idWell, idFileCategoryDrillingProgramItems, token) .ConfigureAwait(false); var well = await wellService.GetAsync(idWell, token) .ConfigureAwait(false); var resultFileName = $"Программа бурения {well.Cluster} {well.Caption}.xlsx"; var matchFiles = await fileService.GetInfosByCategoryAsync(idWell, idFileCategoryDrillingProgram, token) .ConfigureAwait(false); if (matchFiles is not null && matchFiles.Any()) { matchFiles = matchFiles.OrderByDescending(f => f.UploadDate); var matchFilesIterator = matchFiles.GetEnumerator(); matchFilesIterator.MoveNext(); var matchFile = matchFilesIterator.Current; while (matchFilesIterator.MoveNext()) await fileService.DeletedAsync(matchFilesIterator.Current.Id, token) .ConfigureAwait(false); if (filesInfos.All(f => f.UploadDate <= matchFile.UploadDate)) return matchFile; else await fileService.DeletedAsync(matchFile.Id, token) .ConfigureAwait(false); } var fileNames = filesInfos .Where(f => f.Name != resultFileName) .Select(f => fileService.GetUrl(f)); var stream = new MemoryStream(1024 * 1024); UniteExcelFiles(fileNames, stream); var buffer = stream.ToArray(); var fileStream = new MemoryStream(buffer); return await fileService.SaveAsync(idWell, null, idFileCategoryDrillingProgram, resultFileName, fileStream, token) .ConfigureAwait(false); } private static void UniteExcelFiles(IEnumerable excelFilesNames, Stream stream) { IWorkbook product = new XSSFWorkbook(); foreach (var excelFileName in excelFilesNames) { IWorkbook book = new XSSFWorkbook(new FileStream(excelFileName, FileMode.Open)); for (int i = 0; i < book.NumberOfSheets; i++) { ISheet sheet = book.GetSheetAt(i); try { sheet.CopyTo(product, sheet.SheetName, true, true); } catch { //what can't be done - can't be done. ignore it. } } } product.Write(stream); } } }