diff --git a/Accounting-Time-It-Company/Accounting-Time-It-Company/Accounting-Time-It-Company.csproj b/Accounting-Time-It-Company/Accounting-Time-It-Company/Accounting-Time-It-Company.csproj
index e869823..e365797 100644
--- a/Accounting-Time-It-Company/Accounting-Time-It-Company/Accounting-Time-It-Company.csproj
+++ b/Accounting-Time-It-Company/Accounting-Time-It-Company/Accounting-Time-It-Company.csproj
@@ -9,8 +9,13 @@
enable
+
+
+
+
+
diff --git a/Accounting-Time-It-Company/Accounting-Time-It-Company/FormCompany.Designer.cs b/Accounting-Time-It-Company/Accounting-Time-It-Company/FormCompany.Designer.cs
index 24d0be2..7dabb14 100644
--- a/Accounting-Time-It-Company/Accounting-Time-It-Company/FormCompany.Designer.cs
+++ b/Accounting-Time-It-Company/Accounting-Time-It-Company/FormCompany.Designer.cs
@@ -38,6 +38,7 @@
vacationsToolStripMenuItem = new ToolStripMenuItem();
typeJobsРаботуToolStripMenuItem = new ToolStripMenuItem();
reportsToolStripMenuItem = new ToolStripMenuItem();
+ DirectoryReportToolStripMenuItem = new ToolStripMenuItem();
menuStrip1.SuspendLayout();
SuspendLayout();
//
@@ -109,10 +110,19 @@
//
// reportsToolStripMenuItem
//
+ reportsToolStripMenuItem.DropDownItems.AddRange(new ToolStripItem[] { DirectoryReportToolStripMenuItem });
reportsToolStripMenuItem.Name = "reportsToolStripMenuItem";
+ reportsToolStripMenuItem.ShortcutKeys = Keys.Control | Keys.W;
reportsToolStripMenuItem.Size = new Size(73, 24);
reportsToolStripMenuItem.Text = "Отчеты";
//
+ // DirectoryReportToolStripMenuItem
+ //
+ DirectoryReportToolStripMenuItem.Name = "DirectoryReportToolStripMenuItem";
+ DirectoryReportToolStripMenuItem.Size = new Size(294, 26);
+ DirectoryReportToolStripMenuItem.Text = "Документ со справочниками";
+ DirectoryReportToolStripMenuItem.Click += DirectoryReportToolStripMenuItem_Click;
+ //
// FormCompany
//
AutoScaleDimensions = new SizeF(8F, 20F);
@@ -143,5 +153,6 @@
private ToolStripMenuItem typeJobsРаботуToolStripMenuItem;
private ToolStripMenuItem reportsToolStripMenuItem;
private ToolStripMenuItem EmployeesToolStripMenuItem;
+ private ToolStripMenuItem DirectoryReportToolStripMenuItem;
}
}
diff --git a/Accounting-Time-It-Company/Accounting-Time-It-Company/FormCompany.cs b/Accounting-Time-It-Company/Accounting-Time-It-Company/FormCompany.cs
index 65493b4..0074f60 100644
--- a/Accounting-Time-It-Company/Accounting-Time-It-Company/FormCompany.cs
+++ b/Accounting-Time-It-Company/Accounting-Time-It-Company/FormCompany.cs
@@ -90,5 +90,18 @@ namespace Accounting_Time_It_Company
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/Accounting-Time-It-Company/Accounting-Time-It-Company/Forms/FormDirectoryReport.Designer.cs b/Accounting-Time-It-Company/Accounting-Time-It-Company/Forms/FormDirectoryReport.Designer.cs
new file mode 100644
index 0000000..313bb91
--- /dev/null
+++ b/Accounting-Time-It-Company/Accounting-Time-It-Company/Forms/FormDirectoryReport.Designer.cs
@@ -0,0 +1,112 @@
+namespace Accounting_Time_It_Company.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()
+ {
+ checkBoxClients = new CheckBox();
+ checkBoxEmployees = new CheckBox();
+ checkBoxPosts = new CheckBox();
+ buttonBuild = new Button();
+ checkBoxProducts = new CheckBox();
+ SuspendLayout();
+ //
+ // checkBoxClients
+ //
+ checkBoxClients.AutoSize = true;
+ checkBoxClients.Location = new Point(42, 12);
+ checkBoxClients.Name = "checkBoxClients";
+ checkBoxClients.Size = new Size(91, 24);
+ checkBoxClients.TabIndex = 0;
+ checkBoxClients.Text = "Клиенты";
+ checkBoxClients.UseVisualStyleBackColor = true;
+ //
+ // checkBoxEmployees
+ //
+ checkBoxEmployees.AutoSize = true;
+ checkBoxEmployees.Location = new Point(42, 42);
+ checkBoxEmployees.Name = "checkBoxEmployees";
+ checkBoxEmployees.Size = new Size(104, 24);
+ checkBoxEmployees.TabIndex = 1;
+ checkBoxEmployees.Text = "Работника";
+ checkBoxEmployees.UseVisualStyleBackColor = true;
+ //
+ // checkBoxPosts
+ //
+ checkBoxPosts.AutoSize = true;
+ checkBoxPosts.Location = new Point(42, 72);
+ checkBoxPosts.Name = "checkBoxPosts";
+ checkBoxPosts.Size = new Size(109, 24);
+ checkBoxPosts.TabIndex = 2;
+ checkBoxPosts.Text = "Должности";
+ checkBoxPosts.UseVisualStyleBackColor = true;
+ //
+ // buttonBuild
+ //
+ buttonBuild.Location = new Point(173, 54);
+ buttonBuild.Name = "buttonBuild";
+ buttonBuild.Size = new Size(128, 29);
+ buttonBuild.TabIndex = 3;
+ buttonBuild.Text = "Сформировать";
+ buttonBuild.UseVisualStyleBackColor = true;
+ buttonBuild.Click += ButtonBuild_Click;
+ //
+ // checkBoxProducts
+ //
+ checkBoxProducts.AutoSize = true;
+ checkBoxProducts.Location = new Point(42, 102);
+ checkBoxProducts.Name = "checkBoxProducts";
+ checkBoxProducts.Size = new Size(92, 24);
+ checkBoxProducts.TabIndex = 4;
+ checkBoxProducts.Text = "Проекты";
+ checkBoxProducts.UseVisualStyleBackColor = true;
+ //
+ // FormDirectoryReport
+ //
+ AutoScaleDimensions = new SizeF(8F, 20F);
+ AutoScaleMode = AutoScaleMode.Font;
+ ClientSize = new Size(313, 148);
+ Controls.Add(checkBoxProducts);
+ Controls.Add(buttonBuild);
+ Controls.Add(checkBoxPosts);
+ Controls.Add(checkBoxEmployees);
+ Controls.Add(checkBoxClients);
+ Name = "FormDirectoryReport";
+ Text = "FormDirectoryReport";
+ ResumeLayout(false);
+ PerformLayout();
+ }
+
+ #endregion
+
+ private CheckBox checkBoxClients;
+ private CheckBox checkBoxEmployees;
+ private CheckBox checkBoxPosts;
+ private Button buttonBuild;
+ private CheckBox checkBoxProducts;
+ }
+}
\ No newline at end of file
diff --git a/Accounting-Time-It-Company/Accounting-Time-It-Company/Forms/FormDirectoryReport.cs b/Accounting-Time-It-Company/Accounting-Time-It-Company/Forms/FormDirectoryReport.cs
new file mode 100644
index 0000000..40e5def
--- /dev/null
+++ b/Accounting-Time-It-Company/Accounting-Time-It-Company/Forms/FormDirectoryReport.cs
@@ -0,0 +1,52 @@
+using Accounting_Time_It_Company.Reports;
+using Unity;
+
+namespace Accounting_Time_It_Company.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 (!checkBoxClients.Checked && !checkBoxEmployees.Checked
+ && !checkBoxPosts.Checked && !checkBoxProducts.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, checkBoxClients.Checked,
+ checkBoxEmployees.Checked, checkBoxPosts.Checked, checkBoxProducts.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/Accounting-Time-It-Company/Accounting-Time-It-Company/Forms/FormDirectoryReport.resx b/Accounting-Time-It-Company/Accounting-Time-It-Company/Forms/FormDirectoryReport.resx
new file mode 100644
index 0000000..8b2ff64
--- /dev/null
+++ b/Accounting-Time-It-Company/Accounting-Time-It-Company/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/Accounting-Time-It-Company/Accounting-Time-It-Company/Reports/DocReport.cs b/Accounting-Time-It-Company/Accounting-Time-It-Company/Reports/DocReport.cs
new file mode 100644
index 0000000..4d45bfa
--- /dev/null
+++ b/Accounting-Time-It-Company/Accounting-Time-It-Company/Reports/DocReport.cs
@@ -0,0 +1,99 @@
+using Accounting_Time_It_Company.Repositories;
+using Microsoft.Extensions.Logging;
+
+namespace Accounting_Time_It_Company.Reports;
+
+internal class DocReport
+{
+ private readonly IClientRepositories _clientRepository;
+ private readonly IEmployeeRepositories _employeeRepository;
+ private readonly IPostRepositories _postRepository;
+ private readonly IProductRepositories _productRepository;
+ private readonly ILogger _logger;
+ public DocReport(IClientRepositories clientRepository, IEmployeeRepositories employeeRepository,
+ IPostRepositories postRepository, IProductRepositories productRepository, ILogger logger)
+ {
+ _clientRepository = clientRepository ??
+ throw new ArgumentNullException(nameof(clientRepository));
+ _employeeRepository = employeeRepository ??
+ throw new ArgumentNullException(nameof(employeeRepository));
+ _postRepository = postRepository ??
+ throw new ArgumentNullException(nameof(postRepository));
+ _productRepository = productRepository ?? throw new ArgumentNullException(nameof(productRepository));
+ _logger = logger ??
+ throw new ArgumentNullException(nameof(logger));
+ }
+ public bool CreateDoc(string filePath, bool includeClients, bool
+ includeEmployees, bool includePosts, bool includeProducts)
+ {
+ try
+ {
+ var builder = new WordBuilder(filePath)
+ .AddHeader("Документ со справочниками");
+ if (includeClients)
+ {
+ builder.AddParagraph("Клиенты")
+ .AddTable([2400, 2400],
+ GetClients());
+ }
+ if (includeEmployees)
+ {
+ builder.AddParagraph("Работники")
+ .AddTable([2400, 1200, 2400, 1200], GetEmployess());
+ }
+ if (includePosts)
+ {
+ builder.AddParagraph("Должности")
+ .AddTable([2400, 1200, 1200], GetPosts());
+ }
+ if (includeProducts)
+ {
+ builder.AddParagraph("Проекты")
+ .AddTable([1200, 2400, 2400], GetProducts());
+ }
+ builder.Build();
+ return true;
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, "Ошибка при формировании документа");
+ return false;
+ }
+ }
+ private List GetClients()
+ {
+ return [
+ ["Имя клиента", "Телефон"],
+ .. _clientRepository
+ .ReadClients()
+ .Select(x => new string[] { x.NameClient, x.Phone}),
+ ];
+ }
+ private List GetEmployess()
+ {
+ return [
+ ["Имя", "Id должности", "Телефон", "Надбавка"],
+ .. _employeeRepository
+ .ReadEmployees()
+ .Select(x => new string[] { x.Name, x.PostId.ToString(), x.Phone, x.Allowance.ToString() }),
+ ];
+ }
+ private List GetPosts()
+ {
+ return [
+ ["Название", "Уровень", "Зарплата"],
+ .. _postRepository
+ .ReadPosts()
+ .Select(x => new string[] { x.NamePost.ToString(), x.LevelPost, x.Wage.ToString() }),
+ ];
+ }
+ private List GetProducts()
+ {
+ return [
+ ["Id заказчика", "Название", "Тип"],
+ .. _productRepository
+ .ReadProducts()
+ .Select(x => new string[] { x.ClientId.ToString(), x.Name, x.Type.ToString() }),
+ ];
+ }
+}
diff --git a/Accounting-Time-It-Company/Accounting-Time-It-Company/Reports/ExcelBuilder.cs b/Accounting-Time-It-Company/Accounting-Time-It-Company/Reports/ExcelBuilder.cs
new file mode 100644
index 0000000..fe85f86
--- /dev/null
+++ b/Accounting-Time-It-Company/Accounting-Time-It-Company/Reports/ExcelBuilder.cs
@@ -0,0 +1,254 @@
+using DocumentFormat.OpenXml.Packaging;
+using DocumentFormat.OpenXml.Spreadsheet;
+using DocumentFormat.OpenXml;
+
+namespace Accounting_Time_It_Company.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/Accounting-Time-It-Company/Accounting-Time-It-Company/Reports/TableReport.cs b/Accounting-Time-It-Company/Accounting-Time-It-Company/Reports/TableReport.cs
new file mode 100644
index 0000000..3df4443
--- /dev/null
+++ b/Accounting-Time-It-Company/Accounting-Time-It-Company/Reports/TableReport.cs
@@ -0,0 +1,83 @@
+
+using Accounting_Time_It_Company.Repositories;
+using Microsoft.Extensions.Logging;
+
+namespace Accounting_Time_It_Company.Reports;
+
+internal class TableReport
+{
+ private readonly ITypeJobRepositories _typeJobRepositories;
+ private readonly IVacationRepositories _vacationRepositories;
+ private readonly ILogger _logger;
+
+ internal static readonly string[] item = ["Сотрудник", "Дата", "Количество пришло", "Количество ушло"];
+
+ public TableReport(ITypeJobRepositories typeJobRepositories,
+ IVacationRepositories vacationRepositories, ILogger logger)
+ {
+ _typeJobRepositories = typeJobRepositories ??
+ throw new ArgumentNullException(nameof(typeJobRepositories));
+
+ _vacationRepositories = vacationRepositories ??
+ throw new ArgumentNullException(nameof(vacationRepositories));
+
+ _logger = logger ?? throw new ArgumentNullException(nameof(logger));
+ }
+
+ public bool CreateTable(string filePath, int feedId, DateTime startDate, DateTime endDate)
+ {
+ try
+ {
+ new ExcelBuilder(filePath)
+ .AddHeader("Сводка по движению корма", 0, 4)
+ .AddParagraph("за период", 0)
+ .AddTable([10, 10, 15, 15], GetData(feedId, startDate,
+ endDate)).Build();
+ return true;
+ }
+ catch (Exception ex)
+ {
+ _logger.LogError(ex, "Ошибка при формировании документа");
+ return false;
+ }
+ }
+
+ private List GetData(int feedId, DateTime startDate, DateTime endDate)
+ {
+ var data = _feedReplenishmentRepository
+ .ReadFeedReplenishment()
+ .Where(x => x.DateReceipt >= startDate && x.DateReceipt <=
+ endDate && x.FeedFeedReplenishments.Any(y => y.FeedId == feedId))
+ .Select(x => new {
+ x.EmployeeId,
+ Date = x.DateReceipt,
+ CountIn
+ = x.FeedFeedReplenishments.FirstOrDefault(y => y.FeedId == feedId)?.Count,
+ CountOut = (int?)null
+ })
+ .Union(
+ _feedingAnimalRepository
+ .ReadFeedingAnimals()
+ .Where(x => x.FeedingDate >= startDate &&
+ x.FeedingDate <= endDate && x.FeedId == feedId)
+ .Select(x => new {
+ x.EmployeeId,
+ Date =
+ x.FeedingDate,
+ CountIn = (int?)null,
+ CountOut = (int?)x.Ration
+ }))
+ .OrderBy(x => x.Date);
+ return
+ new List() { item }
+ .Union(
+ data
+ .Select(x => new string[] {
+x.EmployeeId.ToString(), x.Date.ToString(), x.CountIn?.ToString() ??
+string.Empty, x.CountOut?.ToString() ?? string.Empty}))
+ .Union(
+ [["Всего", "", data.Sum(x => x.CountIn ?? 0).ToString(),
+data.Sum(x => x.CountOut ?? 0).ToString()]])
+ .ToList();
+ }
+}
diff --git a/Accounting-Time-It-Company/Accounting-Time-It-Company/Reports/WordBuilder.cs b/Accounting-Time-It-Company/Accounting-Time-It-Company/Reports/WordBuilder.cs
new file mode 100644
index 0000000..387c465
--- /dev/null
+++ b/Accounting-Time-It-Company/Accounting-Time-It-Company/Reports/WordBuilder.cs
@@ -0,0 +1,124 @@
+using DocumentFormat.OpenXml.Packaging;
+using DocumentFormat.OpenXml.Wordprocessing;
+using DocumentFormat.OpenXml;
+
+namespace Accounting_Time_It_Company.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());
+ // TODO прописать настройки под жирный текст
+ 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;
+ }
+}
| |