DD.WellWorkover.Cloud/AsbCloudInfrastructure/Services/DrillingProgram/DrillingProgramMaker.cs

134 lines
4.7 KiB
C#

using ClosedXML.Excel;
using ClosedXML.Excel.Drawings;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace AsbCloudInfrastructure.Services.DrillingProgram
{
internal class DrillingProgramMaker
{
private const int maxAllowedColumns = 256;
public static void UniteExcelFiles(IEnumerable<string> excelFilesNames, string resultExcelPath, IEnumerable<AsbCloudApp.Data.DrillingProgramPartDto> parts, AsbCloudApp.Data.WellDto well)
{
var resultExcelFile = new XLWorkbook(XLEventTracking.Disabled);
var titleSheet = resultExcelFile.AddWorksheet("Титульный лист");
var marks = parts.SelectMany(p => p.File!.FileMarks);
var titleSheetMaker = new TitleListSheet(marks, well);
titleSheetMaker.Draw(titleSheet);
var contentSheet = resultExcelFile.AddWorksheet("Содержание");
var contentListSheetMaker = new ContentListSheet(parts);
contentListSheetMaker.Draw(contentSheet);
var filteredFileNames = excelFilesNames.Distinct();
foreach (var excelFileName in filteredFileNames)
{
using var workbookSrc = new XLWorkbook(excelFileName, XLEventTracking.Disabled);
foreach (var sheet in workbookSrc.Worksheets)
{
if (sheet.Visibility == XLWorksheetVisibility.Visible)
CopySheet(resultExcelFile, sheet);
}
}
resultExcelFile.SaveAs(resultExcelPath,
new SaveOptions { EvaluateFormulasBeforeSaving = true });
}
private static void CopySheet(XLWorkbook workbookDst, IXLWorksheet sheetSrc)
{
var newSheetName = sheetSrc.Name;
var suffix = "";
int index = 1;
while (workbookDst.Worksheets.Contains(newSheetName))
{
newSheetName = sheetSrc.Name;
suffix = $"_{index++}";
if (newSheetName.Length + suffix.Length >= 31)
newSheetName = newSheetName[..(31 - suffix.Length)];
newSheetName += suffix;
}
var imagesInfos = sheetSrc.Pictures.Select(p => new ImageInfo
{
Id = p.Id,
Data = p.ImageStream.GetBuffer(),
Height = p.Height,
Width = p.Width,
TopLeftCellAddress = p.TopLeftCell.Address,
Left = p.Left,
Top = p.Top
}).ToList();
IXLWorksheet resultSheet;
if (sheetSrc.Columns().Count() > maxAllowedColumns)
{
resultSheet = workbookDst.Worksheets.Add(newSheetName);
var rngData = GetCellsRange(sheetSrc);
rngData.CopyTo(resultSheet.Cell(1, 1));
var lastRowWithData = rngData.LastRowUsed().RangeAddress
.LastAddress.RowNumber;
for (int i = 1; i < lastRowWithData; i++)
{
resultSheet.Row(i).Height = sheetSrc.Row(i).Height;
resultSheet.Column(i).Width = sheetSrc.Column(i).Width;
}
}
else
{
RemovePicturesFromSheet(sheetSrc);
resultSheet = sheetSrc.CopyTo(workbookDst, newSheetName);
}
CopyImagesToAnotherSheet(imagesInfos, resultSheet);
}
private static IXLWorksheet CopyImagesToAnotherSheet(IEnumerable<ImageInfo> 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 filteredPics = sheet.Pictures.Select(p => p.Name).Distinct().ToList();
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;
}
}
}