diff --git a/ProjectHorseRacing/ProjectHorseRacing/Forms/FormDirectoryReport.Designer.cs b/ProjectHorseRacing/ProjectHorseRacing/Forms/FormDirectoryReport.Designer.cs new file mode 100644 index 0000000..5472e15 --- /dev/null +++ b/ProjectHorseRacing/ProjectHorseRacing/Forms/FormDirectoryReport.Designer.cs @@ -0,0 +1,100 @@ +namespace ProjectHorseRacing.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() + { + ButtonBuild = new Button(); + checkBoxHorses = new CheckBox(); + checkBoxJockeys = new CheckBox(); + checkBoxRace = new CheckBox(); + SuspendLayout(); + // + // ButtonBuild + // + ButtonBuild.Location = new Point(204, 72); + ButtonBuild.Name = "ButtonBuild"; + ButtonBuild.Size = new Size(140, 30); + ButtonBuild.TabIndex = 7; + ButtonBuild.Text = "Сформировать"; + ButtonBuild.UseVisualStyleBackColor = true; + ButtonBuild.Click += ButtonBuild_Click; + // + // checkBoxHorses + // + checkBoxHorses.AutoSize = true; + checkBoxHorses.Location = new Point(32, 126); + checkBoxHorses.Name = "checkBoxHorses"; + checkBoxHorses.Size = new Size(87, 24); + checkBoxHorses.TabIndex = 6; + checkBoxHorses.Text = "Лошади"; + checkBoxHorses.UseVisualStyleBackColor = true; + // + // checkBoxJockeys + // + checkBoxJockeys.AutoSize = true; + checkBoxJockeys.Location = new Point(32, 76); + checkBoxJockeys.Name = "checkBoxJockeys"; + checkBoxJockeys.Size = new Size(77, 24); + checkBoxJockeys.TabIndex = 5; + checkBoxJockeys.Text = "Жокеи"; + checkBoxJockeys.UseVisualStyleBackColor = true; + // + // checkBoxRace + // + checkBoxRace.AutoSize = true; + checkBoxRace.Location = new Point(32, 25); + checkBoxRace.Name = "checkBoxRace"; + checkBoxRace.Size = new Size(79, 24); + checkBoxRace.TabIndex = 4; + checkBoxRace.Text = "Скачки"; + checkBoxRace.UseVisualStyleBackColor = true; + // + // FormDirectoryReport + // + AutoScaleDimensions = new SizeF(8F, 20F); + AutoScaleMode = AutoScaleMode.Font; + ClientSize = new Size(376, 175); + Controls.Add(ButtonBuild); + Controls.Add(checkBoxHorses); + Controls.Add(checkBoxJockeys); + Controls.Add(checkBoxRace); + Name = "FormDirectoryReport"; + StartPosition = FormStartPosition.CenterParent; + Text = "Выгрузка справочников"; + ResumeLayout(false); + PerformLayout(); + } + + #endregion + + private Button ButtonBuild; + private CheckBox checkBoxHorses; + private CheckBox checkBoxJockeys; + private CheckBox checkBoxRace; + } +} \ No newline at end of file diff --git a/ProjectHorseRacing/ProjectHorseRacing/Forms/FormDirectoryReport.cs b/ProjectHorseRacing/ProjectHorseRacing/Forms/FormDirectoryReport.cs new file mode 100644 index 0000000..81f2c23 --- /dev/null +++ b/ProjectHorseRacing/ProjectHorseRacing/Forms/FormDirectoryReport.cs @@ -0,0 +1,63 @@ +using ProjectHorseRacing.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 ProjectHorseRacing.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 (!checkBoxRace.Checked && !checkBoxJockeys.Checked && !checkBoxHorses.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, checkBoxRace.Checked, checkBoxJockeys.Checked, checkBoxHorses.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); + } + } + + private void checkBoxRace_CheckedChanged(object sender, EventArgs e) + { + + } + } +} \ No newline at end of file diff --git a/ProjectHorseRacing/ProjectHorseRacing/Forms/FormDirectoryReport.resx b/ProjectHorseRacing/ProjectHorseRacing/Forms/FormDirectoryReport.resx new file mode 100644 index 0000000..af32865 --- /dev/null +++ b/ProjectHorseRacing/ProjectHorseRacing/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/ProjectHorseRacing/ProjectHorseRacing/ProjectHorseRacing.csproj b/ProjectHorseRacing/ProjectHorseRacing/ProjectHorseRacing.csproj index b94bfad..3cd7071 100644 --- a/ProjectHorseRacing/ProjectHorseRacing/ProjectHorseRacing.csproj +++ b/ProjectHorseRacing/ProjectHorseRacing/ProjectHorseRacing.csproj @@ -10,11 +10,13 @@ + + diff --git a/ProjectHorseRacing/ProjectHorseRacing/Reports/DocReport.cs b/ProjectHorseRacing/ProjectHorseRacing/Reports/DocReport.cs new file mode 100644 index 0000000..f717ffa --- /dev/null +++ b/ProjectHorseRacing/ProjectHorseRacing/Reports/DocReport.cs @@ -0,0 +1,102 @@ +using Microsoft.Extensions.Logging; +using ProjectHorseRacing.Repositories; +using ProjectHorseRacing.Repositories.Implementation; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ProjectHorseRacing.Reports; + +internal class DocReport +{ + private readonly IRaceRepository _raceRepository; + private readonly IJockeyRepository _jockeyRepository; + private readonly IHorseRepository _horseRepository; + + private readonly ILogger _logger; + + public DocReport(IRaceRepository raceRepository, IJockeyRepository jockeyRepository, + IHorseRepository horseRepository, ILogger logger) + { + _raceRepository = raceRepository ?? + throw new ArgumentNullException(nameof(raceRepository)); + _jockeyRepository = jockeyRepository ?? + throw new ArgumentNullException(nameof(jockeyRepository)); + _horseRepository = horseRepository ?? + throw new ArgumentNullException(nameof(horseRepository)); + _logger = logger ?? + throw new ArgumentNullException(nameof(logger)); + } + + public bool CreateDoc(string filePath, bool includeRaces, bool includeJockeys, bool includeHorses) + { + try + { + var builder = new WordBuilder(filePath) + .AddHeader("Документ со справочниками"); + + if (includeRaces) + { + builder.AddParagraph("Скачки") + .AddTable([2400, 2400], GetRaces()); + } + + if (includeJockeys) + { + builder.AddParagraph("Жокеи") + .AddTable([2400, 1200, 2400, 2400], GetJockeys()); + } + + if (includeHorses) + { + builder.AddParagraph("Лошади") + .AddTable([2400, 1200, 2400, 2400], GetHorses()); + } + builder.Build(); + return true; + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка при формировании документа"); + return false; + } + } + + private List GetRaces() + { + return [ + ["Дата", "Место проведения"], + .. _raceRepository + .ReadRaces().Select + (x => new string[] { x.DateTime.ToString(), x.RacePlaceEvent.ToString() }), + ]; + } + + private List GetJockeys() + { + return [ + ["Имя", "Фамилия", "Возраст", "Рейтинг"], + .. _jockeyRepository + .ReadJockeys().Select + (x => new string[] { x.FirstName, x.LastName, x.Age.ToString(), + x.Rating.ToString() }), + ]; + } + + private List GetHorses() + { + return [ + ["Кличка", "Пол", "Возраст", "Характер"], + .. _horseRepository + .ReadHorses().Select + (x => new string[] { x.Nickname, x.HorseGender.ToString(), x.AgeHorse.ToString(), + x.HorseCharacters.ToString() }), + ]; + } + + + + +} diff --git a/ProjectHorseRacing/ProjectHorseRacing/Reports/WordBuilder.cs b/ProjectHorseRacing/ProjectHorseRacing/Reports/WordBuilder.cs new file mode 100644 index 0000000..4f87aa6 --- /dev/null +++ b/ProjectHorseRacing/ProjectHorseRacing/Reports/WordBuilder.cs @@ -0,0 +1,109 @@ +using DocumentFormat.OpenXml.Drawing.Charts; +using DocumentFormat.OpenXml; +using DocumentFormat.OpenXml.Wordprocessing; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using DocumentFormat.OpenXml.Packaging; + +namespace ProjectHorseRacing.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()); + + var runProperties = new RunProperties(); + runProperties.AppendChild(new Bold()); + run.RunProperties = runProperties; + + 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; + } +}