diff --git a/ProjectHotel/ProjectHotel/Forms/FormDirectoryReport.Designer.cs b/ProjectHotel/ProjectHotel/Forms/FormDirectoryReport.Designer.cs new file mode 100644 index 0000000..16a353a --- /dev/null +++ b/ProjectHotel/ProjectHotel/Forms/FormDirectoryReport.Designer.cs @@ -0,0 +1,100 @@ +namespace ProjectHotel.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() + { + checkBoxAthletes = new CheckBox(); + checkBoxRooms = new CheckBox(); + checkBoxHotels = new CheckBox(); + buttonBuild = new Button(); + SuspendLayout(); + // + // checkBoxAthletes + // + checkBoxAthletes.AutoSize = true; + checkBoxAthletes.Location = new Point(12, 12); + checkBoxAthletes.Name = "checkBoxAthletes"; + checkBoxAthletes.Size = new Size(97, 19); + checkBoxAthletes.TabIndex = 0; + checkBoxAthletes.Text = "Спортсмены"; + checkBoxAthletes.UseVisualStyleBackColor = true; + // + // checkBoxRooms + // + checkBoxRooms.AutoSize = true; + checkBoxRooms.Location = new Point(12, 67); + checkBoxRooms.Name = "checkBoxRooms"; + checkBoxRooms.Size = new Size(76, 19); + checkBoxRooms.TabIndex = 1; + checkBoxRooms.Text = "Комнаты"; + checkBoxRooms.UseVisualStyleBackColor = true; + // + // checkBoxHotels + // + checkBoxHotels.AutoSize = true; + checkBoxHotels.Location = new Point(12, 123); + checkBoxHotels.Name = "checkBoxHotels"; + checkBoxHotels.Size = new Size(87, 19); + checkBoxHotels.TabIndex = 2; + checkBoxHotels.Text = "Гостиницы"; + checkBoxHotels.UseVisualStyleBackColor = true; + // + // buttonBuild + // + buttonBuild.Location = new Point(194, 67); + buttonBuild.Name = "buttonBuild"; + buttonBuild.Size = new Size(97, 24); + buttonBuild.TabIndex = 3; + buttonBuild.Text = "сформировать"; + buttonBuild.UseVisualStyleBackColor = true; + buttonBuild.Click += ButtonBuild_Click; + // + // FormDirectoryReport + // + AutoScaleDimensions = new SizeF(7F, 15F); + AutoScaleMode = AutoScaleMode.Font; + ClientSize = new Size(357, 216); + Controls.Add(buttonBuild); + Controls.Add(checkBoxHotels); + Controls.Add(checkBoxRooms); + Controls.Add(checkBoxAthletes); + Name = "FormDirectoryReport"; + StartPosition = FormStartPosition.CenterParent; + Text = "Выгрузка справочников"; + ResumeLayout(false); + PerformLayout(); + } + + #endregion + + private CheckBox checkBoxAthletes; + private CheckBox checkBoxRooms; + private CheckBox checkBoxHotels; + private Button buttonBuild; + } +} \ No newline at end of file diff --git a/ProjectHotel/ProjectHotel/Forms/FormDirectoryReport.cs b/ProjectHotel/ProjectHotel/Forms/FormDirectoryReport.cs new file mode 100644 index 0000000..355032f --- /dev/null +++ b/ProjectHotel/ProjectHotel/Forms/FormDirectoryReport.cs @@ -0,0 +1,62 @@ +using ProjectHotel.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 ProjectHotel.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 (!checkBoxAthletes.Checked && + !checkBoxRooms.Checked && !checkBoxHotels.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, checkBoxAthletes.Checked, + checkBoxRooms.Checked, checkBoxHotels.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); + } + } +} \ No newline at end of file diff --git a/ProjectHotel/ProjectHotel/Forms/FormDirectoryReport.resx b/ProjectHotel/ProjectHotel/Forms/FormDirectoryReport.resx new file mode 100644 index 0000000..af32865 --- /dev/null +++ b/ProjectHotel/ProjectHotel/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/ProjectHotel/ProjectHotel/Forms/FormHotelForAthletes.Designer.cs b/ProjectHotel/ProjectHotel/Forms/FormHotelForAthletes.Designer.cs index d08df32..5418fb0 100644 --- a/ProjectHotel/ProjectHotel/Forms/FormHotelForAthletes.Designer.cs +++ b/ProjectHotel/ProjectHotel/Forms/FormHotelForAthletes.Designer.cs @@ -37,6 +37,7 @@ PlacingAthleteToolStripMenuItem = new ToolStripMenuItem(); CleaningRoomToolStripMenuItem = new ToolStripMenuItem(); ReportsToolStripMenuItem = new ToolStripMenuItem(); + DirectoryReportToolStripMenuItem = new ToolStripMenuItem(); menuStrip1.SuspendLayout(); SuspendLayout(); // @@ -59,21 +60,21 @@ // RoomsToolStripMenuItem // RoomsToolStripMenuItem.Name = "RoomsToolStripMenuItem"; - RoomsToolStripMenuItem.Size = new Size(180, 22); + RoomsToolStripMenuItem.Size = new Size(145, 22); RoomsToolStripMenuItem.Text = "Комнаты"; RoomsToolStripMenuItem.Click += RoomsToolStripMenuItem_Click; // // HotelsToolStripMenuItem // HotelsToolStripMenuItem.Name = "HotelsToolStripMenuItem"; - HotelsToolStripMenuItem.Size = new Size(180, 22); + HotelsToolStripMenuItem.Size = new Size(145, 22); HotelsToolStripMenuItem.Text = "Отелели"; HotelsToolStripMenuItem.Click += HotelsToolStripMenuItem_Click; // // AthletesToolStripMenuItem // AthletesToolStripMenuItem.Name = "AthletesToolStripMenuItem"; - AthletesToolStripMenuItem.Size = new Size(180, 22); + AthletesToolStripMenuItem.Size = new Size(145, 22); AthletesToolStripMenuItem.Text = "Спортсмены"; AthletesToolStripMenuItem.Click += AthletesToolStripMenuItem_Click; // @@ -100,10 +101,19 @@ // // ReportsToolStripMenuItem // + ReportsToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { DirectoryReportToolStripMenuItem }); ReportsToolStripMenuItem.Name = "ReportsToolStripMenuItem"; ReportsToolStripMenuItem.Size = new Size(60, 20); ReportsToolStripMenuItem.Text = "Отчеты"; // + // DirectoryReportToolStripMenuItem + // + DirectoryReportToolStripMenuItem.Name = "DirectoryReportToolStripMenuItem"; + DirectoryReportToolStripMenuItem.ShortcutKeys = Keys.Control | Keys.W; + DirectoryReportToolStripMenuItem.Size = new Size(280, 22); + DirectoryReportToolStripMenuItem.Text = "Документ со справочниками"; + DirectoryReportToolStripMenuItem.Click += DirectoryReportToolStripMenuItem_Click; + // // FormHotelForAthletes // AutoScaleDimensions = new SizeF(7F, 15F); @@ -133,5 +143,6 @@ private ToolStripMenuItem PlacingAthleteToolStripMenuItem; private ToolStripMenuItem ReportsToolStripMenuItem; private ToolStripMenuItem CleaningRoomToolStripMenuItem; + private ToolStripMenuItem DirectoryReportToolStripMenuItem; } } diff --git a/ProjectHotel/ProjectHotel/Forms/FormHotelForAthletes.cs b/ProjectHotel/ProjectHotel/Forms/FormHotelForAthletes.cs index 0e3a985..9870ea2 100644 --- a/ProjectHotel/ProjectHotel/Forms/FormHotelForAthletes.cs +++ b/ProjectHotel/ProjectHotel/Forms/FormHotelForAthletes.cs @@ -80,4 +80,17 @@ public partial class FormHotelForAthletes : Form MessageBoxButtons.OK, MessageBoxIcon.Error); } } + + private void DirectoryReportToolStripMenuItem_Click(object sender, EventArgs e) + { + try + { + _container.Resolve().ShowDialog(); + } + catch (Exception ex) + { + MessageBox.Show(ex.Message, " ", + MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } } diff --git a/ProjectHotel/ProjectHotel/ProjectHotel.csproj b/ProjectHotel/ProjectHotel/ProjectHotel.csproj index 3f5e845..13b3b6a 100644 --- a/ProjectHotel/ProjectHotel/ProjectHotel.csproj +++ b/ProjectHotel/ProjectHotel/ProjectHotel.csproj @@ -25,11 +25,13 @@ + + diff --git a/ProjectHotel/ProjectHotel/Reports/DocReport.cs b/ProjectHotel/ProjectHotel/Reports/DocReport.cs new file mode 100644 index 0000000..d70e5d8 --- /dev/null +++ b/ProjectHotel/ProjectHotel/Reports/DocReport.cs @@ -0,0 +1,83 @@ +using Microsoft.Extensions.Logging; +using ProjectHotel.Repositories; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ProjectHotel.Reports; + +internal class DocReport +{ + private readonly IAthleteRepository _athleteRepository; + private readonly IRoomRepository _roomRepository; + private readonly IHotelRepository _hotelRepository; + private readonly ILogger _logger; + public DocReport(IAthleteRepository athleteRepository, IRoomRepository roomRepository, IHotelRepository hotelRepository, ILogger logger) + { + _athleteRepository = athleteRepository ?? throw new ArgumentNullException(nameof(athleteRepository)); + _roomRepository = roomRepository ?? throw new ArgumentNullException(nameof(roomRepository)); + _hotelRepository = hotelRepository ?? throw new ArgumentNullException(nameof(hotelRepository)); + _logger = logger ?? throw new ArgumentNullException(nameof(logger)); + } + public bool CreateDoc(string filePath, bool includeAthletes, bool includeRooms, bool includeHotels) + { + try + { + var builder = new WordBuilder(filePath) + .AddHeader("Документ со справочниками"); + if (includeAthletes) + { + builder.AddParagraph("Спортсмены") + .AddTable([2400, 2400, 2400, 1200, 1200], + GetAthletes()); + } + if (includeRooms) + { + builder.AddParagraph("Комнаты") + .AddTable([2400, 2400, 2400], GetRooms()); + } + if (includeHotels) + { + builder.AddParagraph("Гостиницы") + .AddTable([2400, 2400], GetHotels()); + } + builder.Build(); + return true; + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка при формировании документа"); + return false; + } + } + private List GetAthletes() + { + return [ + ["Имя", "Фамилия", "Отчество", "Вид/Виды спорта", "Разряд"], + .. _athleteRepository.ReadAthletes().Select(x => new string[] { x.FirstName, +x.LastName,x.FatherName, x.Sport.ToString(), x.AthleteClass.ToString() }), + ]; + } + private List GetRooms() + { + return [ + ["Отель", "Номер", "Вместимость"], + .. _roomRepository + .ReadRooms() + .Select(x => new string[] { x.HotelId.ToString(), x.Name, +x.Capacity.ToString() }), + ]; + } + private List GetHotels() + { + return [ + ["Название", "Адрес"], + .. _hotelRepository + .ReadHotels() + .Select(x => new string[] { x.Name, +x.Address}), + ]; + } +} diff --git a/ProjectHotel/ProjectHotel/Reports/WordBuilder.cs b/ProjectHotel/ProjectHotel/Reports/WordBuilder.cs new file mode 100644 index 0000000..48faf1e --- /dev/null +++ b/ProjectHotel/ProjectHotel/Reports/WordBuilder.cs @@ -0,0 +1,129 @@ +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 ProjectHotel.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 = run.AppendChild(new RunProperties()); + runProperties.AppendChild(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; + } +}