2023-11-21 15:10:22 +05:00
|
|
|
|
using AsbCloudApp.Data;
|
|
|
|
|
using AsbCloudApp.Repositories;
|
|
|
|
|
using AsbCloudApp.Services;
|
|
|
|
|
using ClosedXML.Excel;
|
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.IO;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Threading;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
|
|
|
|
namespace AsbCloudInfrastructure.Services.Trajectory
|
|
|
|
|
{
|
2023-11-22 17:30:30 +05:00
|
|
|
|
public abstract class TrajectoryImportService<T> where T : TrajectoryGeoDto
|
2023-11-21 15:10:22 +05:00
|
|
|
|
{
|
2023-11-22 17:30:30 +05:00
|
|
|
|
private readonly IWellService wellService;
|
2023-11-21 15:10:22 +05:00
|
|
|
|
|
2023-11-22 17:30:30 +05:00
|
|
|
|
private readonly ITrajectoryRepository<T> trajectoryService;
|
|
|
|
|
protected abstract void AddCoordinatesToRow(IXLRow row, T trajectory);
|
|
|
|
|
protected abstract T ParseRow(IXLRow row);
|
2023-11-21 15:10:22 +05:00
|
|
|
|
public abstract string templateFileName { get; set; }
|
|
|
|
|
public abstract string usingTemplateFile { get; set; }
|
|
|
|
|
public abstract string sheetNamePlannedTrajectory { get; set; }
|
|
|
|
|
public abstract int headerRowsCount { get; set; }
|
|
|
|
|
public abstract int ColumnWellboreDepth { get; set; }
|
|
|
|
|
public abstract int ColumnZenithAngle { get; set; }
|
|
|
|
|
public abstract int ColumnAzimuthGeo { get; set; }
|
|
|
|
|
public abstract int ColumnAzimuthMagnetic { get; set; }
|
|
|
|
|
public abstract int ColumnVerticalDepth { get; set; }
|
|
|
|
|
public abstract int ColumnRadius { get; set; }
|
|
|
|
|
public abstract int ColumnComment { get; set; }
|
|
|
|
|
|
|
|
|
|
public TrajectoryImportService(ITrajectoryRepository<T> trajectoryService, IWellService wellService)
|
|
|
|
|
{
|
|
|
|
|
this.trajectoryService = trajectoryService;
|
|
|
|
|
this.wellService = wellService;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public Stream GetTemplateFile()
|
|
|
|
|
{
|
|
|
|
|
var stream = System.Reflection.Assembly.GetExecutingAssembly()
|
|
|
|
|
.GetManifestResourceStream($"{usingTemplateFile}.{templateFileName}");
|
|
|
|
|
if (stream is null)
|
|
|
|
|
throw new Exception($"Область {usingTemplateFile} не содержит файла с названием {templateFileName}");
|
|
|
|
|
return stream;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public async Task<Stream> ExportAsync(int idWell, CancellationToken token)
|
|
|
|
|
{
|
2023-11-22 21:23:23 +05:00
|
|
|
|
var trajectorys = await trajectoryService.GetAsync(idWell, token);
|
|
|
|
|
return MakeExelFileStream(trajectorys);
|
2023-11-21 15:10:22 +05:00
|
|
|
|
}
|
|
|
|
|
|
2023-11-22 17:30:30 +05:00
|
|
|
|
private Stream MakeExelFileStream(IEnumerable<T> trajectories)
|
2023-11-21 15:10:22 +05:00
|
|
|
|
{
|
|
|
|
|
using Stream ecxelTemplateStream = GetTemplateFile();
|
|
|
|
|
using var workbook = new XLWorkbook(ecxelTemplateStream, XLEventTracking.Disabled);
|
2023-11-22 21:23:23 +05:00
|
|
|
|
AddTrajecoryToWorkbook(workbook, trajectories);
|
2023-11-21 15:10:22 +05:00
|
|
|
|
MemoryStream memoryStream = new MemoryStream();
|
|
|
|
|
workbook.SaveAs(memoryStream, new SaveOptions { });
|
|
|
|
|
memoryStream.Seek(0, SeekOrigin.Begin);
|
|
|
|
|
return memoryStream;
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-22 21:23:23 +05:00
|
|
|
|
private void AddTrajecoryToWorkbook(XLWorkbook workbook, IEnumerable<T> trajectories)
|
2023-11-21 15:10:22 +05:00
|
|
|
|
{
|
2023-11-22 17:30:30 +05:00
|
|
|
|
if (trajectories.Any())
|
2023-11-21 15:10:22 +05:00
|
|
|
|
{
|
|
|
|
|
var sheet = workbook.Worksheets.FirstOrDefault(ws => ws.Name == sheetNamePlannedTrajectory);
|
|
|
|
|
if (sheet is null)
|
|
|
|
|
throw new FileFormatException($"Лист с именем {sheetNamePlannedTrajectory} отсутствует, либо имеет некорректное название");
|
2023-11-22 17:30:30 +05:00
|
|
|
|
AddTrajecoryToSheet(sheet, trajectories);
|
2023-11-21 15:10:22 +05:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-22 17:30:30 +05:00
|
|
|
|
private void AddTrajecoryToSheet(IXLWorksheet sheet, IEnumerable<T> trajectories)
|
2023-11-21 15:10:22 +05:00
|
|
|
|
{
|
2023-11-22 17:30:30 +05:00
|
|
|
|
var rowList = trajectories.ToList();
|
2023-11-21 15:10:22 +05:00
|
|
|
|
for (int i = 0; i < rowList.Count; i++)
|
|
|
|
|
{
|
|
|
|
|
var row = sheet.Row(1 + i + headerRowsCount);
|
|
|
|
|
AddCoordinatesToRow(row, rowList[i]);
|
|
|
|
|
}
|
2023-11-22 17:30:30 +05:00
|
|
|
|
}
|
2023-11-21 15:10:22 +05:00
|
|
|
|
|
|
|
|
|
public async Task<string> GetFileNameAsync(int idWell, CancellationToken token)
|
|
|
|
|
{
|
|
|
|
|
var caption = await wellService.GetWellCaptionByIdAsync(idWell, token);
|
|
|
|
|
return string.Format("{0}_{1}", caption, templateFileName);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public async Task<IEnumerable<T>> ImportAsync(int idWell, int idUser, Stream stream, CancellationToken token)
|
|
|
|
|
{
|
|
|
|
|
using var workbook = new XLWorkbook(stream, XLEventTracking.Disabled);
|
|
|
|
|
var trajectoryRows = ParseFileStream(stream);
|
|
|
|
|
foreach (var row in trajectoryRows)
|
|
|
|
|
{
|
|
|
|
|
row.IdWell = idWell;
|
|
|
|
|
row.IdUser = idUser;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return trajectoryRows;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private IEnumerable<T> ParseFileStream(Stream stream)
|
|
|
|
|
{
|
|
|
|
|
using var workbook = new XLWorkbook(stream, XLEventTracking.Disabled);
|
|
|
|
|
return ParseWorkbook(workbook);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private IEnumerable<T> ParseWorkbook(IXLWorkbook workbook)
|
|
|
|
|
{
|
|
|
|
|
var sheetTrajectory = workbook.Worksheets.FirstOrDefault(ws => ws.Name == sheetNamePlannedTrajectory);
|
|
|
|
|
if (sheetTrajectory is null)
|
|
|
|
|
throw new FileFormatException($"Книга excel не содержит листа {sheetNamePlannedTrajectory}.");
|
|
|
|
|
var trajectoryRows = ParseSheet(sheetTrajectory);
|
|
|
|
|
return trajectoryRows;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private IEnumerable<T> ParseSheet(IXLWorksheet sheet)
|
|
|
|
|
{
|
|
|
|
|
if (sheet.RangeUsed().RangeAddress.LastAddress.ColumnNumber < 7)
|
|
|
|
|
throw new FileFormatException($"Лист {sheet.Name} содержит меньшее количество столбцов.");
|
|
|
|
|
|
|
|
|
|
var count = sheet.RowsUsed().Count() - headerRowsCount;
|
|
|
|
|
|
|
|
|
|
if (count > 1024)
|
|
|
|
|
throw new FileFormatException($"Лист {sheet.Name} содержит слишком большое количество строк.");
|
|
|
|
|
|
|
|
|
|
if (count <= 0)
|
|
|
|
|
throw new FileFormatException($"Лист {sheet.Name} некорректного формата либо пустой");
|
|
|
|
|
|
|
|
|
|
var trajectoryRows = new List<T>(count);
|
|
|
|
|
var parseErrors = new List<string>();
|
|
|
|
|
for (int i = 0; i < count; i++)
|
|
|
|
|
{
|
|
|
|
|
var row = sheet.Row(1 + i + headerRowsCount);
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
var trajectoryRow = ParseRow(row);
|
|
|
|
|
trajectoryRows.Add(trajectoryRow);
|
|
|
|
|
}
|
|
|
|
|
catch (FileFormatException ex)
|
|
|
|
|
{
|
|
|
|
|
parseErrors.Add(ex.Message);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (parseErrors.Any())
|
|
|
|
|
throw new FileFormatException(string.Join("\r\n", parseErrors));
|
|
|
|
|
|
|
|
|
|
return trajectoryRows;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|