From 605599ba3abfe94487b0c2eeb2589a3aaf8a4a82 Mon Sep 17 00:00:00 2001 From: danila Date: Thu, 30 Jan 2025 21:04:17 +0400 Subject: [PATCH] =?UTF-8?q?=D1=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...eplenishment.cs => ShoesReplenishments.cs} | 10 +- ...ishment.cs => ShoesShoesReplenishments.cs} | 6 +- ShoeStore/ShoeStore/FormStorage.Designer.cs | 21 +- ShoeStore/ShoeStore/FormStorage.cs | 15 + .../Forms/FormDirectoryReport.Designer.cs | 100 +++++++ .../ShoeStore/Forms/FormDirectoryReport.cs | 73 +++++ .../ShoeStore/Forms/FormDirectoryReport.resx | 120 ++++++++ .../ShoeStore/Forms/FormShoesReplenishment.cs | 8 +- ShoeStore/ShoeStore/Reports/DocReport.cs | 84 ++++++ ShoeStore/ShoeStore/Reports/ExcelBuilder.cs | 258 ++++++++++++++++++ ShoeStore/ShoeStore/Reports/WordBuilder.cs | 102 +++++++ .../IShoesReplenishmentRepository.cs | 4 +- .../ShoesReplenishmentRepository.cs | 6 +- ShoeStore/ShoeStore/ShoeStore.csproj | 2 + 14 files changed, 787 insertions(+), 22 deletions(-) rename ShoeStore/ShoeStore/Entities/{ShoesReplenishment.cs => ShoesReplenishments.cs} (65%) rename ShoeStore/ShoeStore/Entities/{ShoesShoesReplenishment.cs => ShoesShoesReplenishments.cs} (71%) create mode 100644 ShoeStore/ShoeStore/Forms/FormDirectoryReport.Designer.cs create mode 100644 ShoeStore/ShoeStore/Forms/FormDirectoryReport.cs create mode 100644 ShoeStore/ShoeStore/Forms/FormDirectoryReport.resx create mode 100644 ShoeStore/ShoeStore/Reports/DocReport.cs create mode 100644 ShoeStore/ShoeStore/Reports/ExcelBuilder.cs create mode 100644 ShoeStore/ShoeStore/Reports/WordBuilder.cs diff --git a/ShoeStore/ShoeStore/Entities/ShoesReplenishment.cs b/ShoeStore/ShoeStore/Entities/ShoesReplenishments.cs similarity index 65% rename from ShoeStore/ShoeStore/Entities/ShoesReplenishment.cs rename to ShoeStore/ShoeStore/Entities/ShoesReplenishments.cs index 72fcc61..ed03fdb 100644 --- a/ShoeStore/ShoeStore/Entities/ShoesReplenishment.cs +++ b/ShoeStore/ShoeStore/Entities/ShoesReplenishments.cs @@ -6,20 +6,20 @@ using System.Threading.Tasks; namespace ShoeStore.Entities; -public class ShoesReplenishment +public class ShoesReplenishments { public int Id { get; private set; } public int FactorysId { get; private set; } public DateTime DateReceipt { get; private set; } - public IEnumerable ShoesShoesReplenishments + public IEnumerable ShoesShoesReplenishments { get; private set; } = []; - public static ShoesReplenishment CreateOpeartion(int id, int factoryId, - IEnumerable shoesShoesReplenishments) + public static ShoesReplenishments CreateOpeartion(int id, int factoryId, + IEnumerable shoesShoesReplenishments) { - return new ShoesReplenishment + return new ShoesReplenishments { Id = id, FactorysId = factoryId, diff --git a/ShoeStore/ShoeStore/Entities/ShoesShoesReplenishment.cs b/ShoeStore/ShoeStore/Entities/ShoesShoesReplenishments.cs similarity index 71% rename from ShoeStore/ShoeStore/Entities/ShoesShoesReplenishment.cs rename to ShoeStore/ShoeStore/Entities/ShoesShoesReplenishments.cs index 15f2b92..036f66d 100644 --- a/ShoeStore/ShoeStore/Entities/ShoesShoesReplenishment.cs +++ b/ShoeStore/ShoeStore/Entities/ShoesShoesReplenishments.cs @@ -6,15 +6,15 @@ using System.Threading.Tasks; namespace ShoeStore.Entities; -public class ShoesShoesReplenishment +public class ShoesShoesReplenishments { public int Id { get; private set; } public int ShoesId { get; private set; } public int Count { get; private set; } - public static ShoesShoesReplenishment CreateElement(int id, int shoesId, int + public static ShoesShoesReplenishments CreateElement(int id, int shoesId, int count) { - return new ShoesShoesReplenishment + return new ShoesShoesReplenishments { Id = id, ShoesId = shoesId, diff --git a/ShoeStore/ShoeStore/FormStorage.Designer.cs b/ShoeStore/ShoeStore/FormStorage.Designer.cs index 142f6c7..1aab265 100644 --- a/ShoeStore/ShoeStore/FormStorage.Designer.cs +++ b/ShoeStore/ShoeStore/FormStorage.Designer.cs @@ -37,6 +37,7 @@ продажаОбувиToolStripMenuItem = new ToolStripMenuItem(); закупкаОбувиToolStripMenuItem = new ToolStripMenuItem(); отчетыToolStripMenuItem = new ToolStripMenuItem(); + документыСоСправочникамиToolStripMenuItem = new ToolStripMenuItem(); menuStrip1.SuspendLayout(); SuspendLayout(); // @@ -59,21 +60,21 @@ // фабрикиToolStripMenuItem // фабрикиToolStripMenuItem.Name = "фабрикиToolStripMenuItem"; - фабрикиToolStripMenuItem.Size = new Size(180, 22); + фабрикиToolStripMenuItem.Size = new Size(130, 22); фабрикиToolStripMenuItem.Text = "Фабрики"; фабрикиToolStripMenuItem.Click += фабрикиToolStripMenuItem_Click; // // магазиныToolStripMenuItem // магазиныToolStripMenuItem.Name = "магазиныToolStripMenuItem"; - магазиныToolStripMenuItem.Size = new Size(180, 22); + магазиныToolStripMenuItem.Size = new Size(130, 22); магазиныToolStripMenuItem.Text = "Магазины"; магазиныToolStripMenuItem.Click += магазиныToolStripMenuItem_Click; // // обувьToolStripMenuItem // обувьToolStripMenuItem.Name = "обувьToolStripMenuItem"; - обувьToolStripMenuItem.Size = new Size(180, 22); + обувьToolStripMenuItem.Size = new Size(130, 22); обувьToolStripMenuItem.Text = "Обувь"; обувьToolStripMenuItem.Click += обувьToolStripMenuItem_Click; // @@ -87,23 +88,32 @@ // продажаОбувиToolStripMenuItem // продажаОбувиToolStripMenuItem.Name = "продажаОбувиToolStripMenuItem"; - продажаОбувиToolStripMenuItem.Size = new Size(180, 22); + продажаОбувиToolStripMenuItem.Size = new Size(160, 22); продажаОбувиToolStripMenuItem.Text = "Продажа обуви"; продажаОбувиToolStripMenuItem.Click += продажаОбувиToolStripMenuItem_Click; // // закупкаОбувиToolStripMenuItem // закупкаОбувиToolStripMenuItem.Name = "закупкаОбувиToolStripMenuItem"; - закупкаОбувиToolStripMenuItem.Size = new Size(180, 22); + закупкаОбувиToolStripMenuItem.Size = new Size(160, 22); закупкаОбувиToolStripMenuItem.Text = "Закупка обуви"; закупкаОбувиToolStripMenuItem.Click += закупкаОбувиToolStripMenuItem_Click; // // отчетыToolStripMenuItem // + отчетыToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { документыСоСправочникамиToolStripMenuItem }); отчетыToolStripMenuItem.Name = "отчетыToolStripMenuItem"; отчетыToolStripMenuItem.Size = new Size(60, 20); отчетыToolStripMenuItem.Text = "Отчеты"; // + // документыСоСправочникамиToolStripMenuItem + // + документыСоСправочникамиToolStripMenuItem.Name = "документыСоСправочникамиToolStripMenuItem"; + документыСоСправочникамиToolStripMenuItem.ShortcutKeys = Keys.Control | Keys.W; + документыСоСправочникамиToolStripMenuItem.Size = new Size(289, 22); + документыСоСправочникамиToolStripMenuItem.Text = "Документы со справочниками"; + документыСоСправочникамиToolStripMenuItem.Click += документыСоСправочникамиToolStripMenuItem_Click; + // // FormStorage // AutoScaleDimensions = new SizeF(7F, 15F); @@ -133,5 +143,6 @@ private ToolStripMenuItem продажаОбувиToolStripMenuItem; private ToolStripMenuItem закупкаОбувиToolStripMenuItem; private ToolStripMenuItem отчетыToolStripMenuItem; + private ToolStripMenuItem документыСоСправочникамиToolStripMenuItem; } } diff --git a/ShoeStore/ShoeStore/FormStorage.cs b/ShoeStore/ShoeStore/FormStorage.cs index e5dcf4a..efc7056 100644 --- a/ShoeStore/ShoeStore/FormStorage.cs +++ b/ShoeStore/ShoeStore/FormStorage.cs @@ -78,5 +78,20 @@ namespace ShoeStore } } } + + private void ToolStripMenuItem_Click(object sender, EventArgs e) + { + { + try + { + _container.Resolve().ShowDialog(); + } + catch (Exception ex) + { + MessageBox.Show(ex.Message, " ", + MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + } } } diff --git a/ShoeStore/ShoeStore/Forms/FormDirectoryReport.Designer.cs b/ShoeStore/ShoeStore/Forms/FormDirectoryReport.Designer.cs new file mode 100644 index 0000000..c3fb715 --- /dev/null +++ b/ShoeStore/ShoeStore/Forms/FormDirectoryReport.Designer.cs @@ -0,0 +1,100 @@ +namespace ShoeStore.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() + { + checkBox1 = new CheckBox(); + checkBox2 = new CheckBox(); + checkBox3 = new CheckBox(); + ButtonBuild = new Button(); + SuspendLayout(); + // + // checkBox1 + // + checkBox1.AutoSize = true; + checkBox1.Location = new Point(30, 39); + checkBox1.Name = "checkBox1"; + checkBox1.Size = new Size(82, 19); + checkBox1.TabIndex = 0; + checkBox1.Text = "Магазины"; + checkBox1.UseVisualStyleBackColor = true; + // + // checkBox2 + // + checkBox2.AutoSize = true; + checkBox2.Location = new Point(30, 79); + checkBox2.Name = "checkBox2"; + checkBox2.Size = new Size(75, 19); + checkBox2.TabIndex = 1; + checkBox2.Text = "Фабрики"; + checkBox2.UseVisualStyleBackColor = true; + // + // checkBox3 + // + checkBox3.AutoSize = true; + checkBox3.Location = new Point(30, 127); + checkBox3.Name = "checkBox3"; + checkBox3.Size = new Size(60, 19); + checkBox3.TabIndex = 2; + checkBox3.Text = "Обувь"; + checkBox3.UseVisualStyleBackColor = true; + // + // ButtonBuild + // + ButtonBuild.Location = new Point(164, 79); + ButtonBuild.Name = "ButtonBuild"; + ButtonBuild.Size = new Size(118, 23); + ButtonBuild.TabIndex = 3; + ButtonBuild.Text = "Сформировать"; + ButtonBuild.UseVisualStyleBackColor = true; + ButtonBuild.Click += ButtonBuild_Click; + // + // FormDirectoryReport + // + AutoScaleDimensions = new SizeF(7F, 15F); + AutoScaleMode = AutoScaleMode.Font; + ClientSize = new Size(294, 188); + Controls.Add(ButtonBuild); + Controls.Add(checkBox3); + Controls.Add(checkBox2); + Controls.Add(checkBox1); + Name = "FormDirectoryReport"; + Text = "FormDirectoryReports"; + Load += FormDirectoryReport_Load; + ResumeLayout(false); + PerformLayout(); + } + + #endregion + + private CheckBox checkBox1; + private CheckBox checkBox2; + private CheckBox checkBox3; + private Button ButtonBuild; + } +} \ No newline at end of file diff --git a/ShoeStore/ShoeStore/Forms/FormDirectoryReport.cs b/ShoeStore/ShoeStore/Forms/FormDirectoryReport.cs new file mode 100644 index 0000000..4447dcb --- /dev/null +++ b/ShoeStore/ShoeStore/Forms/FormDirectoryReport.cs @@ -0,0 +1,73 @@ +using ShoeStore.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 ShoeStore.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 (!checkBox1.Checked && + !checkBox2.Checked && !checkBox3.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, checkBox1.Checked, + checkBox2.Checked, + checkBox3.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 FormDirectoryReport_Load(object sender, EventArgs e) + { + + } + + + } + +} diff --git a/ShoeStore/ShoeStore/Forms/FormDirectoryReport.resx b/ShoeStore/ShoeStore/Forms/FormDirectoryReport.resx new file mode 100644 index 0000000..8b2ff64 --- /dev/null +++ b/ShoeStore/ShoeStore/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/ShoeStore/ShoeStore/Forms/FormShoesReplenishment.cs b/ShoeStore/ShoeStore/Forms/FormShoesReplenishment.cs index 149a5c6..85681b7 100644 --- a/ShoeStore/ShoeStore/Forms/FormShoesReplenishment.cs +++ b/ShoeStore/ShoeStore/Forms/FormShoesReplenishment.cs @@ -39,7 +39,7 @@ namespace ShoeStore.Forms { throw new Exception("Имеются незаполненные поля"); } - _shoesReplenishmentRepository.CreateShoesReplenishment(ShoesReplenishment.CreateOpeartion(0, + _shoesReplenishmentRepository.CreateShoesReplenishment(ShoesReplenishments.CreateOpeartion(0, (int)comboBoxFactory.SelectedValue!, CreateListShoesShoesReplenishmentsFromDataGrid())); Close(); @@ -52,10 +52,10 @@ namespace ShoeStore.Forms } private void ButtonCancel_Click(object sender, EventArgs e) => Close(); - private List + private List CreateListShoesShoesReplenishmentsFromDataGrid() { - var list = new List(); + var list = new List(); foreach (DataGridViewRow row in dataGridViewShoess.Rows) { if (row.Cells["ColumnShoes"].Value == null || @@ -63,7 +63,7 @@ namespace ShoeStore.Forms { continue; } - list.Add(ShoesShoesReplenishment.CreateElement(0, + list.Add(ShoesShoesReplenishments.CreateElement(0, Convert.ToInt32(row.Cells["ColumnShoes"].Value), Convert.ToInt32(row.Cells["ColumnCount"].Value))); } diff --git a/ShoeStore/ShoeStore/Reports/DocReport.cs b/ShoeStore/ShoeStore/Reports/DocReport.cs new file mode 100644 index 0000000..30086ef --- /dev/null +++ b/ShoeStore/ShoeStore/Reports/DocReport.cs @@ -0,0 +1,84 @@ +using Microsoft.Extensions.Logging; +using ShoeStore.Repositories; + +namespace ShoeStore.Reports; + +internal class DocReport +{ + private readonly IStoreRepository _storeRepository;//IStoreRepository _storeRepository + private readonly IFactoryRepository _factoryRepository; + private readonly IShoesRepository _shoesRepository; + + private readonly ILogger _logger; + + public DocReport(IStoreRepository storeRepository, IFactoryRepository factoryRepository, + IShoesRepository shoesRepository, ILogger logger) + { + _storeRepository = storeRepository ?? throw new ArgumentNullException(nameof(storeRepository)); + _factoryRepository = factoryRepository ?? throw new ArgumentNullException(nameof(factoryRepository)); + _shoesRepository = shoesRepository ?? throw new ArgumentNullException(nameof(shoesRepository)); + _logger = logger ?? throw new ArgumentNullException(nameof(logger)); + } + + public bool CreateDoc(string filePath, bool includeStore, bool includeFactorys, bool includeShoess) + { + try + { + var builder = new WordBuilder(filePath).AddHeader("Документ со справочниками"); + + if (includeStore) + { + builder.AddParagraph("Магазины").AddTable([2400, 2400, 1200], GetStores()); + } + + if (includeFactorys) + { + builder.AddParagraph("Фабрики").AddTable([2400, 2400 ], GetFactorys()); + } + + if (includeShoess) + { + builder.AddParagraph("Обувь").AddTable([2400, 2400], GetShoess()); + } + + builder.Build(); + + return true; + } + catch (Exception ex) + { + _logger.LogError(ex, "Ошибка при формировании документа"); + return false; + } + } + + private List GetStores() + { + return [ + ["Название", "Работники", "Посетители"], + .. _storeRepository + .ReadStores() + .Select(x => new string[] { /*x.AnimalSpecies,*/ x.StoreName, x.Employees.ToString(), x.Visitors.ToString() }), + ]; + } + + private List GetFactorys() + { + return [ + ["Название", "Страна"], + .. _factoryRepository + .ReadFactorys() + .Select(x => new string[] { x.FactoryName/*, x.LastName*/, x.Manufacturer.ToString() }), + ]; + } + + private List GetShoess() + { + return [ + ["Название", "Описание"], + .. _shoesRepository + .ReadShoess() + .Select(x => new string[] { /*x.ShoesType.ToString(),*/ x.Name, x.Description }), + ]; + } +} diff --git a/ShoeStore/ShoeStore/Reports/ExcelBuilder.cs b/ShoeStore/ShoeStore/Reports/ExcelBuilder.cs new file mode 100644 index 0000000..70f956f --- /dev/null +++ b/ShoeStore/ShoeStore/Reports/ExcelBuilder.cs @@ -0,0 +1,258 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using DocumentFormat.OpenXml; +using DocumentFormat.OpenXml.Packaging; +using DocumentFormat.OpenXml.Spreadsheet; + +namespace ShoeStore.Reports; + +internal class ExcelBuilder +{ + private readonly string _filePath; + private readonly SheetData _sheetData; + private readonly MergeCells _mergeCells; + private readonly Columns _columns; + private uint _rowIndex = 0; + public ExcelBuilder(string filePath) + { + if (string.IsNullOrWhiteSpace(filePath)) + { + throw new ArgumentNullException(nameof(filePath)); + } + if (File.Exists(filePath)) + { + File.Delete(filePath); + } + _filePath = filePath; + _sheetData = new SheetData(); + _mergeCells = new MergeCells(); + _columns = new Columns(); + _rowIndex = 1; + } + public ExcelBuilder AddHeader(string header, int startIndex, int count) + { + CreateCell(startIndex, _rowIndex, header, + StyleIndex.SimpleTextWithoutBorder); + for (int i = startIndex + 1; i < startIndex + count; ++i) + { + CreateCell(i, _rowIndex, "", + StyleIndex.SimpleTextWithoutBorder); + } + _mergeCells.Append(new MergeCell() + { + Reference = + new + StringValue($"{GetExcelColumnName(startIndex)}{_rowIndex}:{GetExcelColumnName(startIndex + count - 1)}{_rowIndex}") + }); + _rowIndex++; + return this; + } + public ExcelBuilder AddParagraph(string text, int columnIndex) + { + CreateCell(columnIndex, _rowIndex++, text, + StyleIndex.SimpleTextWithoutBorder); + return this; + } + public ExcelBuilder AddTable(int[] columnsWidths, List data) + { + if (columnsWidths == null || columnsWidths.Length == 0) + { + throw new ArgumentNullException(nameof(columnsWidths)); + } + if (data == null || data.Count == 0) + { + throw new ArgumentNullException(nameof(data)); + } + if (data.Any(x => x.Length != columnsWidths.Length)) + { + throw new InvalidOperationException("widths.Length != data.Length"); + } + uint counter = 1; + int coef = 2; + _columns.Append(columnsWidths.Select(x => new Column + { + Min = counter, + Max = counter++, + Width = x * coef, + CustomWidth = true + })); for (var j = 0; j < data.First().Length; ++j) + { + CreateCell(j, _rowIndex, data.First()[j], + StyleIndex.SimpleTextWithoutBorder); + } + _rowIndex++; + for (var i = 1; i < data.Count - 1; ++i) + { + for (var j = 0; j < data[i].Length; ++j) + { + CreateCell(j, _rowIndex, data[i][j], + StyleIndex.SimpleTextWithoutBorder); + } + _rowIndex++; + } + for (var j = 0; j < data.Last().Length; ++j) + { + CreateCell(j, _rowIndex, data.Last()[j], + StyleIndex.SimpleTextWithoutBorder); + } + _rowIndex++; + return this; + } + public void Build() + { + using var spreadsheetDocument = SpreadsheetDocument.Create(_filePath, + SpreadsheetDocumentType.Workbook); + var workbookpart = spreadsheetDocument.AddWorkbookPart(); + GenerateStyle(workbookpart); + workbookpart.Workbook = new Workbook(); + var worksheetPart = workbookpart.AddNewPart(); + worksheetPart.Worksheet = new Worksheet(); + if (_columns.HasChildren) + { + worksheetPart.Worksheet.Append(_columns); + } + worksheetPart.Worksheet.Append(_sheetData); + var sheets = + spreadsheetDocument.WorkbookPart!.Workbook.AppendChild(new Sheets()); + var sheet = new Sheet() + { + Id = + spreadsheetDocument.WorkbookPart.GetIdOfPart(worksheetPart), + SheetId = 1, + Name = "Лист 1" + }; + sheets.Append(sheet); + if (_mergeCells.HasChildren) + { + worksheetPart.Worksheet.InsertAfter(_mergeCells, + worksheetPart.Worksheet.Elements().First()); + } + } + private static void GenerateStyle(WorkbookPart workbookPart) + { + var workbookStylesPart = +workbookPart.AddNewPart(); + workbookStylesPart.Stylesheet = new Stylesheet(); + var fonts = new Fonts() + { + Count = 2, + KnownFonts = + BooleanValue.FromBoolean(true) + }; + fonts.Append(new DocumentFormat.OpenXml.Spreadsheet.Font + { + FontSize = new FontSize() { Val = 11 }, + FontName = new FontName() { Val = "Calibri" }, + FontFamilyNumbering = new FontFamilyNumbering() { Val = 2 }, + FontScheme = new FontScheme() + { + Val = new + EnumValue(FontSchemeValues.Minor) + } + }); + // TODO добавить шрифт с жирным + workbookStylesPart.Stylesheet.Append(fonts); + // Default Fill + var fills = new Fills() { Count = 1 }; + fills.Append(new Fill + { + PatternFill = new PatternFill() + { + PatternType = new + EnumValue(PatternValues.None) + } + }); + workbookStylesPart.Stylesheet.Append(fills); + // Default Border + var borders = new Borders() { Count = 2 }; + borders.Append(new Border + { + LeftBorder = new LeftBorder(), + RightBorder = new RightBorder(), + TopBorder = new TopBorder(), + BottomBorder = new BottomBorder(), + DiagonalBorder = new DiagonalBorder() + }); + // TODO добавить настройку с границами + workbookStylesPart.Stylesheet.Append(borders); + // Default cell format and a date cell format + var cellFormats = new CellFormats() { Count = 4 }; + cellFormats.Append(new CellFormat + { + NumberFormatId = 0, + FormatId = 0, + FontId = 0, + BorderId = 0, + FillId = 0, + Alignment = new Alignment() + { + Horizontal = HorizontalAlignmentValues.Left, + Vertical = VerticalAlignmentValues.Center, + WrapText = true + } + }); + // TODO дополнить форматы + workbookStylesPart.Stylesheet.Append(cellFormats); + } + private enum StyleIndex + { + SimpleTextWithoutBorder = 0, + // TODO дополнить стили + } + private void CreateCell(int columnIndex, uint rowIndex, string text, +StyleIndex styleIndex) + { + var columnName = GetExcelColumnName(columnIndex); + var cellReference = columnName + rowIndex; + var row = _sheetData.Elements().FirstOrDefault(r => r.RowIndex! + == rowIndex); + if (row == null) + { + row = new Row() { RowIndex = rowIndex }; + _sheetData.Append(row); + } + var newCell = row.Elements() + .FirstOrDefault(c => c.CellReference != null && + c.CellReference.Value == columnName + rowIndex); + if (newCell == null) + { + Cell? refCell = null; + foreach (Cell cell in row.Elements()) + { + if (cell.CellReference?.Value != null && + cell.CellReference.Value.Length == cellReference.Length) + { + if (string.Compare(cell.CellReference.Value, + cellReference, true) > 0) + { + refCell = cell; + break; + } + } + } + newCell = new Cell() { CellReference = cellReference }; + row.InsertBefore(newCell, refCell); + } + newCell.CellValue = new CellValue(text); + newCell.DataType = CellValues.String; + newCell.StyleIndex = (uint)styleIndex; + } + private static string GetExcelColumnName(int columnNumber) + { + columnNumber += 1; + int dividend = columnNumber; + string columnName = string.Empty; + int modulo; + while (dividend > 0) + { + modulo = (dividend - 1) % 26; + columnName = Convert.ToChar(65 + modulo).ToString() + + columnName; + dividend = (dividend - modulo) / 26; + } + return columnName; + } +} diff --git a/ShoeStore/ShoeStore/Reports/WordBuilder.cs b/ShoeStore/ShoeStore/Reports/WordBuilder.cs new file mode 100644 index 0000000..5d3a883 --- /dev/null +++ b/ShoeStore/ShoeStore/Reports/WordBuilder.cs @@ -0,0 +1,102 @@ +using DocumentFormat.OpenXml.Wordprocessing; +using DocumentFormat.OpenXml; +using DocumentFormat.OpenXml.Packaging; + +namespace ShoeStore.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; + } +} diff --git a/ShoeStore/ShoeStore/Repositories/IShoesReplenishmentRepository.cs b/ShoeStore/ShoeStore/Repositories/IShoesReplenishmentRepository.cs index 673ad17..b51c720 100644 --- a/ShoeStore/ShoeStore/Repositories/IShoesReplenishmentRepository.cs +++ b/ShoeStore/ShoeStore/Repositories/IShoesReplenishmentRepository.cs @@ -9,9 +9,9 @@ namespace ShoeStore.Repositories; public interface IShoesReplenishmentRepository { - IEnumerable ReadShoesReplenishment(DateTime? dateForm = + IEnumerable ReadShoesReplenishment(DateTime? dateForm = null, DateTime? dateTo = null, int? shoesId = null, int? factoryId = null); - void CreateShoesReplenishment(ShoesReplenishment shoesReplenishment); + void CreateShoesReplenishment(ShoesReplenishments shoesReplenishment); void DeleteShoesReplenishment(int id); } \ No newline at end of file diff --git a/ShoeStore/ShoeStore/Repositories/Implementations/ShoesReplenishmentRepository.cs b/ShoeStore/ShoeStore/Repositories/Implementations/ShoesReplenishmentRepository.cs index a24eb59..f60b06b 100644 --- a/ShoeStore/ShoeStore/Repositories/Implementations/ShoesReplenishmentRepository.cs +++ b/ShoeStore/ShoeStore/Repositories/Implementations/ShoesReplenishmentRepository.cs @@ -23,7 +23,7 @@ internal class ShoesReplenishmentRepository : IShoesReplenishmentRepository _connectionString = connectionString; _logger = logger; } - public void CreateShoesReplenishment(ShoesReplenishment shoesReplenishment) + public void CreateShoesReplenishment(ShoesReplenishments shoesReplenishment) { _logger.LogInformation("Добавление объекта"); _logger.LogDebug("Объект: {json}", @@ -79,7 +79,7 @@ WHERE Id=@id"; throw; } } - public IEnumerable ReadShoesReplenishment(DateTime? + public IEnumerable ReadShoesReplenishment(DateTime? dateForm = null, DateTime? dateTo = null, int? shoesId = null, int? factorysId = null) { @@ -90,7 +90,7 @@ WHERE Id=@id"; NpgsqlConnection(_connectionString.ConnectionString); var querySelect = @"SELECT * FROM ShoesReplenishments"; var shoesReplenishments = - connection.Query(querySelect); + connection.Query(querySelect); _logger.LogDebug("Полученные объекты: {json}", JsonConvert.SerializeObject(shoesReplenishments)); return shoesReplenishments; diff --git a/ShoeStore/ShoeStore/ShoeStore.csproj b/ShoeStore/ShoeStore/ShoeStore.csproj index 14f791f..ddc8387 100644 --- a/ShoeStore/ShoeStore/ShoeStore.csproj +++ b/ShoeStore/ShoeStore/ShoeStore.csproj @@ -10,6 +10,8 @@ + +