From d302d4644b5e6ca4a7a71fa4eec7ac4e6595b34d Mon Sep 17 00:00:00 2001 From: abazov73 <92822431+abazov73@users.noreply.github.com> Date: Thu, 19 Oct 2023 22:07:56 +0400 Subject: [PATCH] Added excel diagram component --- AbazovApp/AbazovAppView/Department.cs | 20 +++ AbazovApp/AbazovAppView/FormTest.Designer.cs | 15 +++ AbazovApp/AbazovAppView/FormTest.cs | 13 +- AbazovApp/AbazovAppView/FormTest.resx | 3 + .../LogicalComponents/DiagramLegendEnum.cs | 16 +++ .../ExcelDiagramComponent.Designer.cs | 36 ++++++ .../ExcelDiagramComponent.cs | 118 ++++++++++++++++++ 7 files changed, 220 insertions(+), 1 deletion(-) create mode 100644 AbazovApp/AbazovAppView/Department.cs create mode 100644 AbazovApp/AbazovViewComponents/LogicalComponents/DiagramLegendEnum.cs create mode 100644 AbazovApp/AbazovViewComponents/LogicalComponents/ExcelDiagramComponent.Designer.cs create mode 100644 AbazovApp/AbazovViewComponents/LogicalComponents/ExcelDiagramComponent.cs diff --git a/AbazovApp/AbazovAppView/Department.cs b/AbazovApp/AbazovAppView/Department.cs new file mode 100644 index 0000000..5172961 --- /dev/null +++ b/AbazovApp/AbazovAppView/Department.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AbazovAppView +{ + public class Department + { + public string name; + public int sells; + + public Department(string name, int sells) + { + this.name = name; + this.sells = sells; + } + } +} diff --git a/AbazovApp/AbazovAppView/FormTest.Designer.cs b/AbazovApp/AbazovAppView/FormTest.Designer.cs index 9e6cdf4..a715a85 100644 --- a/AbazovApp/AbazovAppView/FormTest.Designer.cs +++ b/AbazovApp/AbazovAppView/FormTest.Designer.cs @@ -48,6 +48,8 @@ this.openFileDialog = new System.Windows.Forms.OpenFileDialog(); this.buttonExcelTable = new System.Windows.Forms.Button(); this.excelTableComponent = new AbazovViewComponents.LogicalComponents.ExcelTableComponent(this.components); + this.excelDiagramComponent = new AbazovViewComponents.LogicalComponents.ExcelDiagramComponent(this.components); + this.buttonExcelDiagram = new System.Windows.Forms.Button(); this.SuspendLayout(); // // abazovCheckedListBox @@ -215,11 +217,22 @@ this.buttonExcelTable.UseVisualStyleBackColor = true; this.buttonExcelTable.Click += new System.EventHandler(this.buttonExcelTable_Click); // + // buttonExcelDiagram + // + this.buttonExcelDiagram.Location = new System.Drawing.Point(12, 372); + this.buttonExcelDiagram.Name = "buttonExcelDiagram"; + this.buttonExcelDiagram.Size = new System.Drawing.Size(150, 29); + this.buttonExcelDiagram.TabIndex = 16; + this.buttonExcelDiagram.Text = "Excel (Диаграмма)"; + this.buttonExcelDiagram.UseVisualStyleBackColor = true; + this.buttonExcelDiagram.Click += new System.EventHandler(this.buttonExcelDiagram_Click); + // // FormTest // this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 20F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(850, 450); + this.Controls.Add(this.buttonExcelDiagram); this.Controls.Add(this.buttonExcelTable); this.Controls.Add(this.buttonExcelImages); this.Controls.Add(this.buttonSetIndex); @@ -263,5 +276,7 @@ private OpenFileDialog openFileDialog; private Button buttonExcelTable; private AbazovViewComponents.LogicalComponents.ExcelTableComponent excelTableComponent; + private AbazovViewComponents.LogicalComponents.ExcelDiagramComponent excelDiagramComponent; + private Button buttonExcelDiagram; } } \ No newline at end of file diff --git a/AbazovApp/AbazovAppView/FormTest.cs b/AbazovApp/AbazovAppView/FormTest.cs index 8fd050c..6a052d0 100644 --- a/AbazovApp/AbazovAppView/FormTest.cs +++ b/AbazovApp/AbazovAppView/FormTest.cs @@ -138,7 +138,6 @@ namespace AbazovAppView openFileDialog.Dispose(); List images = new List(); string path = AppDomain.CurrentDomain.BaseDirectory + "test.xlsx"; - MessageBox.Show(path); if (excelImagesComponent.createWithImages(new ExcelImageInfo(path, "Header", files))) MessageBox.Show("Успех!"); else MessageBox.Show("Ошибка, проверьте консоль"); } @@ -165,5 +164,17 @@ namespace AbazovAppView if (excelTableComponent.createWithTable(path, "test", merges, heights, headers, workers)) MessageBox.Show("Успех"); } + + private void buttonExcelDiagram_Click(object sender, EventArgs e) + { + List departments = new List(); + + departments.Add(new Department("Dep 1", 330)); + departments.Add(new Department("Dep 2", 500)); + departments.Add(new Department("Dep 3", 170)); + string path = AppDomain.CurrentDomain.BaseDirectory + "test.xlsx"; + if (excelDiagramComponent.createWithDiagram(path, "test", "Продажи", DiagramLegendEnum.TopRight, departments, "name", "sells")) MessageBox.Show("Успех"); + else MessageBox.Show("Fail :("); + } } } diff --git a/AbazovApp/AbazovAppView/FormTest.resx b/AbazovApp/AbazovAppView/FormTest.resx index 7bad74a..b5e1c7d 100644 --- a/AbazovApp/AbazovAppView/FormTest.resx +++ b/AbazovApp/AbazovAppView/FormTest.resx @@ -66,4 +66,7 @@ 392, 17 + + 596, 17 + \ No newline at end of file diff --git a/AbazovApp/AbazovViewComponents/LogicalComponents/DiagramLegendEnum.cs b/AbazovApp/AbazovViewComponents/LogicalComponents/DiagramLegendEnum.cs new file mode 100644 index 0000000..5d0d926 --- /dev/null +++ b/AbazovApp/AbazovViewComponents/LogicalComponents/DiagramLegendEnum.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace AbazovViewComponents.LogicalComponents +{ + public enum DiagramLegendEnum + { + TopLeft = 0, + TopRight = 1, + BottomRight = 2, + BottomLeft = 3, + } +} diff --git a/AbazovApp/AbazovViewComponents/LogicalComponents/ExcelDiagramComponent.Designer.cs b/AbazovApp/AbazovViewComponents/LogicalComponents/ExcelDiagramComponent.Designer.cs new file mode 100644 index 0000000..e483c14 --- /dev/null +++ b/AbazovApp/AbazovViewComponents/LogicalComponents/ExcelDiagramComponent.Designer.cs @@ -0,0 +1,36 @@ +namespace AbazovViewComponents.LogicalComponents +{ + partial class ExcelDiagramComponent + { + /// + /// Обязательная переменная конструктора. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Освободить все используемые ресурсы. + /// + /// истинно, если управляемый ресурс должен быть удален; иначе ложно. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Код, автоматически созданный конструктором компонентов + + /// + /// Требуемый метод для поддержки конструктора — не изменяйте + /// содержимое этого метода с помощью редактора кода. + /// + private void InitializeComponent() + { + components = new System.ComponentModel.Container(); + } + + #endregion + } +} diff --git a/AbazovApp/AbazovViewComponents/LogicalComponents/ExcelDiagramComponent.cs b/AbazovApp/AbazovViewComponents/LogicalComponents/ExcelDiagramComponent.cs new file mode 100644 index 0000000..79595ac --- /dev/null +++ b/AbazovApp/AbazovViewComponents/LogicalComponents/ExcelDiagramComponent.cs @@ -0,0 +1,118 @@ +using Microsoft.Office.Interop.Excel; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; + +namespace AbazovViewComponents.LogicalComponents +{ + public partial class ExcelDiagramComponent : Component + { + public ExcelDiagramComponent() + { + InitializeComponent(); + } + + public ExcelDiagramComponent(IContainer container) + { + container.Add(this); + + InitializeComponent(); + } + + public bool createWithDiagram(string path, string title, string diagramTitle, DiagramLegendEnum diagramLegendAnchor, List data, string seriesNameField, string valueField) + { + var excelApp = new Microsoft.Office.Interop.Excel.Application { SheetsInNewWorkbook = 1 }; + Workbook workbook = excelApp.Workbooks.Add(Type.Missing); + try + { + Worksheet worksheet = (Worksheet)workbook.Worksheets.get_Item(1); + + FieldInfo? seriesName = typeof(T).GetField(seriesNameField); + FieldInfo? value = typeof(T).GetField(valueField); + if (seriesName == null || value == null) throw new ArgumentException("Переданного поля не существует"); + int columnCount = 2; + foreach(var item in data) + { + var cell = worksheet.get_Range("A" + columnCount, "A" + columnCount); + cell.Font.Size = 14; + cell.Font.Name = "Times New Roman"; + cell.ColumnWidth = 8; + cell.RowHeight = 25; + cell.HorizontalAlignment = Constants.xlCenter; + cell.VerticalAlignment = Constants.xlCenter; + cell.Value2 = seriesName.GetValue(item); + + cell = worksheet.get_Range("B" + columnCount, "B" + columnCount); + cell.Font.Size = 14; + cell.Font.Name = "Times New Roman"; + cell.ColumnWidth = 8; + cell.RowHeight = 25; + cell.HorizontalAlignment = Constants.xlCenter; + cell.VerticalAlignment = Constants.xlCenter; + cell.Value2 = value.GetValue(item); + + columnCount++; + } + + //header + var excelcells = worksheet.get_Range("A1", "A1"); + excelcells.Font.Bold = true; + excelcells.Font.Size = 14; + excelcells.Font.Name = "Times New Roman"; + excelcells.ColumnWidth = 8; + excelcells.RowHeight = 25; + excelcells.HorizontalAlignment = Constants.xlCenter; + excelcells.VerticalAlignment = Constants.xlCenter; + excelcells.Value2 = title; + + var charts = worksheet.ChartObjects() as ChartObjects; + int chartWidth = 300; + int chartHeight = 300; + var chartObject = charts.Add(250, 10, chartWidth, chartHeight); + var chart = chartObject.Chart; + var range = worksheet.get_Range($"A2", $"B{columnCount - 1}"); + chart.SetSourceData(range); + chart.ChartType = XlChartType.xlPie; + switch (diagramLegendAnchor) + { + case DiagramLegendEnum.TopLeft: + chart.Legend.Top = 0; + chart.Legend.Left = 0; + break; + case DiagramLegendEnum.TopRight: + chart.Legend.Top = 0; + chart.Legend.Left = chartWidth - chart.Legend.Width; + break; + case DiagramLegendEnum.BottomLeft: + chart.Legend.Top = chartHeight - chart.Legend.Height; + chart.Legend.Left = 0; + break; + case DiagramLegendEnum.BottomRight: + chart.Legend.Top = chartHeight - chart.Legend.Height; + chart.Legend.Left = chartWidth - chart.Legend.Width; + break; + } + chart.ChartWizard(Source: range, Title: diagramTitle); + + object missing = System.Reflection.Missing.Value; + workbook.SaveAs(path, XlFileFormat.xlOpenXMLWorkbook, missing, missing, false, false, XlSaveAsAccessMode.xlNoChange, + XlSaveConflictResolution.xlUserResolution, true, missing, missing, missing); + workbook.Close(); + excelApp.Quit(); + + return true; + } + catch (Exception) + { + workbook.Close(); + excelApp.Quit(); + throw; + } + } + } +}