diff --git a/ProjectFuel/ProjectFuel.csproj b/ProjectFuel/ProjectFuel.csproj index bd47c9e..9182619 100644 --- a/ProjectFuel/ProjectFuel.csproj +++ b/ProjectFuel/ProjectFuel.csproj @@ -10,6 +10,7 @@ + diff --git a/ProjectFuel/Reports/DocReport.cs b/ProjectFuel/Reports/DocReport.cs new file mode 100644 index 0000000..effaee4 --- /dev/null +++ b/ProjectFuel/Reports/DocReport.cs @@ -0,0 +1,113 @@ +using Microsoft.Extensions.Logging; +using ProjectFuel.Repositories; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ProjectFuel.Reports; + +public class DocReport +{ + private readonly ICarRepository _carRepository; + private readonly IDriverRepository _driverRepository; + private readonly IFuelRepository _fuelRepository; + private readonly IRouteRepository _routeRepository; + private readonly ILogger _logger; + + public DocReport(ICarRepository carRepository, IDriverRepository driverRepository, IFuelRepository fuelRepository, IRouteRepository routeRepository, ILogger logger) + { + _carRepository = carRepository ?? throw new ArgumentNullException(nameof(carRepository)); + _driverRepository = driverRepository ?? throw new ArgumentNullException(nameof(driverRepository)); + _fuelRepository = fuelRepository ?? throw new ArgumentNullException(nameof(fuelRepository)); + _routeRepository = routeRepository ?? throw new ArgumentNullException(nameof(routeRepository)); + _logger = logger ?? throw new ArgumentNullException(nameof(logger)); + } + + public bool CreateDoc(string filePath, bool includeCars, bool includeDrivers, bool includeFuels, bool includeRoutes) + { + try + { + var builder = new WordBuilder(filePath).AddHeader("Документ со справочниками"); + + if (includeCars) + { + int[] carColumnWidths = new int[] { 2400, 2400, 1200, 1200, 1200 }; + builder.AddParagraph("Автомобили").AddTable(carColumnWidths, GetCars()); + } + + if (includeDrivers) + { + int[] driverColumnWidths = new int[] { 2400, 2400, 1200 }; + builder.AddParagraph("Водители").AddTable(driverColumnWidths, GetDrivers()); + } + + if (includeFuels) + { + int[] fuelColumnWidths = new int[] { 2400, 1200, 1200 }; + builder.AddParagraph("Топливо").AddTable(fuelColumnWidths, GetFuels()); + } + + if (includeRoutes) + { + int[] routeColumnWidths = new int[] { 2400, 2400, 1200 }; + builder.AddParagraph("Маршруты").AddTable(routeColumnWidths, GetRoutes()); + } + + builder.Build(); + + return true; + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка при формировании документа"); + return false; + } + } + + private List GetCars() + { + var list = new List(); + list.Add(new string[] { "Марка машины", "Модель машины", "Тип машины", "Водительская категория", "Расход топлива" }); + list.AddRange(_carRepository + .ReadCars() + .Select(x => new string[] { x.Car_Mark, x.Car_Model, x.Car_Type.ToString(), x.License.ToString(), x.Consumption_Rate.ToString() })); + return list; + } + + + + private List GetDrivers() + { + var list = new List(); + list.Add(new string[] { "Имя водителя", "Фамилия водителя", "Водительская категория" }); + list.AddRange(_driverRepository + .ReadDrivers() + .Select(x => new string[] { x.Firstname, x.Secondname, x.Driver_License.ToString() })); + + return list; + } + + private List GetFuels() + { + var list = new List(); + list.Add(new string[] { "Тип топлива", "Цена за литр", "Количество" }); + list.AddRange(_fuelRepository + .ReadFuels() + .Select(x => new string[] { x.Fuel_Type.ToString(), x.Price_Per_Liter.ToString(), x.Amount.ToString() })); + + return list; + } + + private List GetRoutes() + { + var list = new List(); + list.Add(new string[] { "Начальная точка", "Конечная точка", "Длина" }); + list.AddRange(_routeRepository + .ReadRoutes() + .Select(x => new string[] { x.Start_Point, x.End_Point, x.Route_Length.ToString() })); + + return list; + } +} diff --git a/ProjectFuel/Reports/WordBuilder.cs b/ProjectFuel/Reports/WordBuilder.cs new file mode 100644 index 0000000..979998f --- /dev/null +++ b/ProjectFuel/Reports/WordBuilder.cs @@ -0,0 +1,91 @@ +using DocumentFormat.OpenXml.Packaging; +using DocumentFormat.OpenXml.Wordprocessing; +using DocumentFormat.OpenXml; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ProjectFuel.Reports; + +internal class WordBuilder +{ + private readonly string _filePath; + private readonly Document _document; + private readonly Body _body; + public WordBuilder(string filePath) + { + if (string.IsNullOrWhiteSpace(filePath)) + { + throw new ArgumentNullException(nameof(filePath)); + } + if (File.Exists(filePath)) + { + File.Delete(filePath); + } + _filePath = filePath; + _document = new Document(); + _body = _document.AppendChild(new Body()); + } + public WordBuilder AddHeader(string header) + { + var paragraph = _body.AppendChild(new Paragraph()); + var run = paragraph.AppendChild(new Run()); + run.PrependChild(new RunProperties()); + run.RunProperties.AddChild(new Bold()); + run.AppendChild(new Text(header)); + return this; + } + public WordBuilder AddParagraph(string text) + { + var paragraph = _body.AppendChild(new Paragraph()); + var run = paragraph.AppendChild(new Run()); + run.AppendChild(new Text(text)); + return this; + } + + public WordBuilder AddTable(int[] widths, List data) + { + if (widths == null || widths.Length == 0) + { + throw new ArgumentNullException(nameof(widths)); + } + if (data == null || data.Count == 0) + { + throw new ArgumentNullException(nameof(data)); + } + if (data.Any(x => x.Length != widths.Length)) + { + throw new InvalidOperationException("widths.Length != data.Length"); + } + var table = new Table(); + table.AppendChild(new TableProperties( + new TableBorders( + new TopBorder() { Val = new EnumValue(BorderValues.Single), Size = 12 }, + new BottomBorder() { Val = new EnumValue(BorderValues.Single), Size = 12 }, + new LeftBorder() { Val = new EnumValue(BorderValues.Single), Size = 12 }, + new RightBorder() { Val = new EnumValue(BorderValues.Single), Size = 12 }, + new InsideHorizontalBorder() { Val = new EnumValue(BorderValues.Single), Size = 12 }, + new InsideVerticalBorder() { Val = new EnumValue(BorderValues.Single), Size = 12 }))); + + // Заголовок + var tr = new TableRow(); + for (var j = 0; j < widths.Length; ++j) + { + tr.Append(new TableCell(new TableCellProperties(new TableCellWidth() { Width = widths[j].ToString() }), + new Paragraph(new Run(new RunProperties(new Bold()), new Text(data.First()[j]))))); + } + table.Append(tr); + // Данные + table.Append(data.Skip(1).Select(x => new TableRow(x.Select(y => new TableCell(new Paragraph(new Run(new Text(y)))))))); + _body.Append(table); + return this; + } + public void Build() + { + using var wordDocument = WordprocessingDocument.Create(_filePath, WordprocessingDocumentType.Document); + var mainPart = wordDocument.AddMainDocumentPart(); + mainPart.Document = _document; + } +}