From e64555709fa9560450cfce890bacf96ca2d122d5 Mon Sep 17 00:00:00 2001 From: mara-1 <147929076+mara-1@users.noreply.github.com> Date: Fri, 13 Dec 2024 02:05:06 +0400 Subject: [PATCH] =?UTF-8?q?=D0=BF=D0=B5=D1=80=D0=B2=D1=8B=D0=B9=20=D1=88?= =?UTF-8?q?=D0=B0=D0=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Forms/FormDirectoryReport.Designer.cs | 99 ++++++++++++++ .../Forms/FormDirectoryReport.cs | 62 +++++++++ .../Forms/FormDirectoryReport.resx | 120 +++++++++++++++++ .../ProjectHorseRacingOrg.csproj | 1 + ProjectHorseRacingOrg/Reports/DocReport.cs | 89 ++++++++++++ ProjectHorseRacingOrg/Reports/WordBuilder.cs | 127 ++++++++++++++++++ 6 files changed, 498 insertions(+) create mode 100644 ProjectHorseRacingOrg/Forms/FormDirectoryReport.Designer.cs create mode 100644 ProjectHorseRacingOrg/Forms/FormDirectoryReport.cs create mode 100644 ProjectHorseRacingOrg/Forms/FormDirectoryReport.resx create mode 100644 ProjectHorseRacingOrg/Reports/DocReport.cs create mode 100644 ProjectHorseRacingOrg/Reports/WordBuilder.cs diff --git a/ProjectHorseRacingOrg/Forms/FormDirectoryReport.Designer.cs b/ProjectHorseRacingOrg/Forms/FormDirectoryReport.Designer.cs new file mode 100644 index 0000000..8e48340 --- /dev/null +++ b/ProjectHorseRacingOrg/Forms/FormDirectoryReport.Designer.cs @@ -0,0 +1,99 @@ +namespace ProjectHorseRacingOrg.Forms +{ + partial class FormDirectoryReport + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + checkBoxHorses = new CheckBox(); + checkBoxJockeys = new CheckBox(); + checkBoxRaces = new CheckBox(); + buttonBuild = new Button(); + SuspendLayout(); + // + // checkBoxHorses + // + checkBoxHorses.AutoSize = true; + checkBoxHorses.Location = new Point(39, 33); + checkBoxHorses.Name = "checkBoxHorses"; + checkBoxHorses.Size = new Size(87, 24); + checkBoxHorses.TabIndex = 0; + checkBoxHorses.Text = "Лошади"; + checkBoxHorses.UseVisualStyleBackColor = true; + // + // checkBoxJockeys + // + checkBoxJockeys.AutoSize = true; + checkBoxJockeys.Location = new Point(39, 87); + checkBoxJockeys.Name = "checkBoxJockeys"; + checkBoxJockeys.Size = new Size(77, 24); + checkBoxJockeys.TabIndex = 1; + checkBoxJockeys.Text = "Жокеи"; + checkBoxJockeys.UseVisualStyleBackColor = true; + // + // checkBoxRaces + // + checkBoxRaces.AutoSize = true; + checkBoxRaces.Location = new Point(39, 147); + checkBoxRaces.Name = "checkBoxRaces"; + checkBoxRaces.Size = new Size(134, 24); + checkBoxRaces.TabIndex = 2; + checkBoxRaces.Text = "Соревнование"; + checkBoxRaces.UseVisualStyleBackColor = true; + // + // buttonBuild + // + buttonBuild.Location = new Point(212, 84); + buttonBuild.Name = "buttonBuild"; + buttonBuild.Size = new Size(132, 29); + buttonBuild.TabIndex = 3; + buttonBuild.Text = "Сформировать"; + buttonBuild.UseVisualStyleBackColor = true; + buttonBuild.Click += ButtonBuild_Click; + // + // FormDirectoryReport + // + AutoScaleDimensions = new SizeF(8F, 20F); + AutoScaleMode = AutoScaleMode.Font; + ClientSize = new Size(412, 228); + Controls.Add(buttonBuild); + Controls.Add(checkBoxRaces); + Controls.Add(checkBoxJockeys); + Controls.Add(checkBoxHorses); + Name = "FormDirectoryReport"; + Text = "FormDirectoryReport"; + ResumeLayout(false); + PerformLayout(); + } + + #endregion + + private CheckBox checkBoxHorses; + private CheckBox checkBoxJockeys; + private CheckBox checkBoxRaces; + private Button buttonBuild; + } +} \ No newline at end of file diff --git a/ProjectHorseRacingOrg/Forms/FormDirectoryReport.cs b/ProjectHorseRacingOrg/Forms/FormDirectoryReport.cs new file mode 100644 index 0000000..a8b4e18 --- /dev/null +++ b/ProjectHorseRacingOrg/Forms/FormDirectoryReport.cs @@ -0,0 +1,62 @@ +using ProjectHorseRacingOrg.Reports; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using Unity; + +namespace ProjectHorseRacingOrg.Forms +{ + public partial class FormDirectoryReport : Form + { + private readonly IUnityContainer _container; + public FormDirectoryReport(IUnityContainer container) + { + InitializeComponent(); + _container = container ?? + throw new ArgumentNullException(nameof(container)); + } + private void ButtonBuild_Click(object sender, EventArgs e) + { + try + { + if (!checkBoxHorses.Checked && !checkBoxJockeys.Checked && !checkBoxRaces.Checked) + { + throw new Exception("Не выбран ни один справочник для выгрузки"); + } + var sfd = new SaveFileDialog() + { + Filter = "Docx Files | *.docx" + }; + if (sfd.ShowDialog() != DialogResult.OK) + { + throw new Exception("Не выбран файла для отчета"); + } + if + (_container.Resolve().CreateDoc(sfd.FileName, checkBoxHorses.Checked, + checkBoxJockeys.Checked, checkBoxRaces.Checked)) + { + MessageBox.Show("Документ сформирован", + "Формирование документа", + MessageBoxButtons.OK, + MessageBoxIcon.Information); + } + else + { + MessageBox.Show("Возникли ошибки при формировании документа.Подробности в логах", + "Формирование документа", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + } + catch (Exception ex) + { + MessageBox.Show(ex.Message, "Ошибка при создании отчета", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + + } +} diff --git a/ProjectHorseRacingOrg/Forms/FormDirectoryReport.resx b/ProjectHorseRacingOrg/Forms/FormDirectoryReport.resx new file mode 100644 index 0000000..8b2ff64 --- /dev/null +++ b/ProjectHorseRacingOrg/Forms/FormDirectoryReport.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/ProjectHorseRacingOrg/ProjectHorseRacingOrg.csproj b/ProjectHorseRacingOrg/ProjectHorseRacingOrg.csproj index 9f5aed5..b341f02 100644 --- a/ProjectHorseRacingOrg/ProjectHorseRacingOrg.csproj +++ b/ProjectHorseRacingOrg/ProjectHorseRacingOrg.csproj @@ -10,6 +10,7 @@ + diff --git a/ProjectHorseRacingOrg/Reports/DocReport.cs b/ProjectHorseRacingOrg/Reports/DocReport.cs new file mode 100644 index 0000000..c808491 --- /dev/null +++ b/ProjectHorseRacingOrg/Reports/DocReport.cs @@ -0,0 +1,89 @@ +using Microsoft.Extensions.Logging; +using ProjectHorseRacingOrg.Repositories; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ProjectHorseRacingOrg.Reports; + +internal class DocReport +{ + private readonly IHorseRepository _horseRepository; + private readonly IJockeyRepository _jockeyRepository; + private readonly IRaceRepository _raceRepository; + + private readonly ILogger _logger; + public DocReport(IHorseRepository horseRepository, IJockeyRepository jockeyRepository, + IRaceRepository raceRepository, ILogger logger) + { + _horseRepository = horseRepository ?? throw new ArgumentNullException(nameof(horseRepository)); + + _jockeyRepository = jockeyRepository ?? throw new ArgumentNullException(nameof(jockeyRepository)); + + _raceRepository = raceRepository ?? throw new ArgumentNullException(nameof(raceRepository)); + + _logger = logger ?? throw new ArgumentNullException(nameof(logger)); + } + public bool CreateDoc(string filePath, bool includeHorses, bool + includeJockeys, bool includeRaces) + { + try + { + var builder = new WordBuilder(filePath) + .AddHeader("Документ со справочниками"); + if (includeHorses) + { + builder.AddParagraph("Лошади") + .AddTable([2400, 2400, 1200, 1200], + GetHorses()); + } + if (includeJockeys) + { + builder.AddParagraph("Жокеи") + .AddTable([2400, 2400, 2400], GetJockeys()); + } + if (includeRaces) + { + builder.AddParagraph("Соревнование") + .AddTable([2400, 2400, 2400], GetRaces()); + } + builder.Build(); + return true; + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка при формировании документа"); + return false; + } + } + private List GetHorses() + { + return [ + ["Вид лошади", "Имя лошади", "Вес", "Возраст"], + .. _horseRepository + .ReadHorses() + .Select(x => new string[] { x.HorseSpecies, x.HorseNickName, x.Weight.ToString(), x.Age.ToString() }), + ]; + } + private List GetJockeys() + { + return [ + ["Имя", "Фамилия", "Титул"], + .. _jockeyRepository + .ReadJockeys() + .Select(x => new string[] { x.FirstName, x.LastName, x.JockeyTitle.ToString() }), + ]; + } + + private List GetRaces() + { + return [ + ["Тип соревнований", "Название", "Описание"], + .. _raceRepository + .ReadRaces() + .Select(x => new string[] { x.RaceType.ToString(), x.Name, x.Description }), + ]; + } +} diff --git a/ProjectHorseRacingOrg/Reports/WordBuilder.cs b/ProjectHorseRacingOrg/Reports/WordBuilder.cs new file mode 100644 index 0000000..4e0ec96 --- /dev/null +++ b/ProjectHorseRacingOrg/Reports/WordBuilder.cs @@ -0,0 +1,127 @@ +using DocumentFormat.OpenXml; +using DocumentFormat.OpenXml.Packaging; +using DocumentFormat.OpenXml.Wordprocessing; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + + +namespace ProjectHorseRacingOrg.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; + } + +}