From 64766eabc4a570a20dd548559d24592a2691606d Mon Sep 17 00:00:00 2001
From: ksenianeva <95441235+ksenianeva@users.noreply.github.com>
Date: Thu, 2 Nov 2023 23:55:44 +0400
Subject: [PATCH] Made excel diagram component
---
.../LogicalComponents/DiagramLegendEnum.cs | 16 ++
.../WordDiagramComponent.Designer.cs | 36 +++++
.../LogicalComponents/WordDiagramComponent.cs | 142 ++++++++++++++++++
.../NevaevaLibrary/NevaevaLibrary.csproj | 9 ++
NevaevaLibrary/TestApp/Department.cs | 20 +++
NevaevaLibrary/TestApp/FormTest.Designer.cs | 15 ++
NevaevaLibrary/TestApp/FormTest.cs | 12 ++
NevaevaLibrary/TestApp/FormTest.resx | 3 +
8 files changed, 253 insertions(+)
create mode 100644 NevaevaLibrary/NevaevaLibrary/LogicalComponents/DiagramLegendEnum.cs
create mode 100644 NevaevaLibrary/NevaevaLibrary/LogicalComponents/WordDiagramComponent.Designer.cs
create mode 100644 NevaevaLibrary/NevaevaLibrary/LogicalComponents/WordDiagramComponent.cs
create mode 100644 NevaevaLibrary/TestApp/Department.cs
diff --git a/NevaevaLibrary/NevaevaLibrary/LogicalComponents/DiagramLegendEnum.cs b/NevaevaLibrary/NevaevaLibrary/LogicalComponents/DiagramLegendEnum.cs
new file mode 100644
index 0000000..90ec627
--- /dev/null
+++ b/NevaevaLibrary/NevaevaLibrary/LogicalComponents/DiagramLegendEnum.cs
@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace NevaevaLibrary.LogicalComponents
+{
+ public enum DiagramLegendEnum
+ {
+ TopLeft = 0,
+ TopRight = 1,
+ BottomRight = 2,
+ BottomLeft = 3,
+ }
+}
diff --git a/NevaevaLibrary/NevaevaLibrary/LogicalComponents/WordDiagramComponent.Designer.cs b/NevaevaLibrary/NevaevaLibrary/LogicalComponents/WordDiagramComponent.Designer.cs
new file mode 100644
index 0000000..5960bd9
--- /dev/null
+++ b/NevaevaLibrary/NevaevaLibrary/LogicalComponents/WordDiagramComponent.Designer.cs
@@ -0,0 +1,36 @@
+namespace NevaevaLibrary.LogicalComponents
+{
+ partial class WordDiagramComponent
+ {
+ ///
+ /// Обязательная переменная конструктора.
+ ///
+ 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/NevaevaLibrary/NevaevaLibrary/LogicalComponents/WordDiagramComponent.cs b/NevaevaLibrary/NevaevaLibrary/LogicalComponents/WordDiagramComponent.cs
new file mode 100644
index 0000000..c74e69d
--- /dev/null
+++ b/NevaevaLibrary/NevaevaLibrary/LogicalComponents/WordDiagramComponent.cs
@@ -0,0 +1,142 @@
+using Microsoft.Office.Interop.Excel;
+using Microsoft.Office.Interop.Word;
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Diagnostics;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace NevaevaLibrary.LogicalComponents
+{
+ public partial class WordDiagramComponent : Component
+ {
+ public WordDiagramComponent()
+ {
+ InitializeComponent();
+ }
+
+ public WordDiagramComponent(IContainer container)
+ {
+ container.Add(this);
+
+ InitializeComponent();
+ }
+
+ private object missing = System.Reflection.Missing.Value;
+
+ private string GetExcelColumnName(int columnNumber)
+ {
+ string columnName = "";
+
+ while (columnNumber > 0)
+ {
+ int modulo = (columnNumber - 1) % 26;
+ columnName = Convert.ToChar('A' + modulo) + columnName;
+ columnNumber = (columnNumber - modulo) / 26;
+ }
+
+ return columnName;
+ }
+
+ public void 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);
+ 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 offsetX = 1;
+ int offsetYMax = -1;
+ foreach (var item in data)
+ {
+ string columnChar = GetExcelColumnName(offsetX);
+ var cell = worksheet.get_Range(columnChar + "2", columnChar + "2");
+ 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);
+
+ int offsetY = 3;
+
+ foreach (var val in (value.GetValue(item) as IEnumerable))
+ {
+ cell = worksheet.get_Range(columnChar + offsetY, columnChar + offsetY);
+ cell.Value2 = val;
+
+ offsetY++;
+ }
+ if (offsetY > offsetYMax) offsetYMax = offsetY;
+
+ offsetX++;
+ }
+
+ 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 endColumn = GetExcelColumnName(offsetX - 1);
+ var range = worksheet.get_Range($"A2", endColumn + (offsetYMax - 1));
+ chart.SetSourceData(range);
+ chart.ChartType = XlChartType.xlLine;
+ 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);
+
+ chart.Export(path.Substring(0, path.Length - 5) + ".jpg", "JPG", false);
+
+ workbook.Close(SaveChanges: false);
+ excelApp.Quit();
+
+ var winword = new Microsoft.Office.Interop.Word.Application();
+ var document = winword.Documents.Add(ref missing, ref missing, ref missing, ref missing);
+ document.PageSetup.RightMargin = 50;
+ document.PageSetup.LeftMargin = 50;
+
+ var header = document.Content.Paragraphs.Add(Type.Missing);
+ header.Range.Text = title;
+ header.Format.Alignment = WdParagraphAlignment.wdAlignParagraphCenter;
+ header.Range.Font.Name = "Times New Roman";
+ header.Range.Font.Size = 22;
+ header.Range.Font.Bold = 2;
+ header.Format.SpaceAfter = 18;
+ header.Range.InsertParagraphAfter();
+
+ document.Shapes.AddPicture(path.Substring(0, path.Length - 5) + ".jpg", Top: 200);
+
+ document.SaveAs(path, Type.Missing, Type.Missing, Type.Missing,
+ Type.Missing, Type.Missing, Type.Missing, Type.Missing,
+ Type.Missing, Type.Missing, Type.Missing, Type.Missing,
+ Type.Missing, Type.Missing, Type.Missing, Type.Missing);
+ document.Close(ref missing, ref missing, ref missing);
+ document = null;
+ winword.Quit(ref missing, ref missing, ref missing);
+ }
+ }
+}
diff --git a/NevaevaLibrary/NevaevaLibrary/NevaevaLibrary.csproj b/NevaevaLibrary/NevaevaLibrary/NevaevaLibrary.csproj
index 3bfe1be..c31a54e 100644
--- a/NevaevaLibrary/NevaevaLibrary/NevaevaLibrary.csproj
+++ b/NevaevaLibrary/NevaevaLibrary/NevaevaLibrary.csproj
@@ -26,6 +26,15 @@
false
true
+
+ tlbimp
+ 9
+ 1
+ 00020813-0000-0000-c000-000000000046
+ 0
+ false
+ true
+
diff --git a/NevaevaLibrary/TestApp/Department.cs b/NevaevaLibrary/TestApp/Department.cs
new file mode 100644
index 0000000..cc35978
--- /dev/null
+++ b/NevaevaLibrary/TestApp/Department.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace TestApp
+{
+ public class Department
+ {
+ public string name;
+ public List sells;
+
+ public Department(string name, List sells)
+ {
+ this.name = name;
+ this.sells = sells;
+ }
+ }
+}
diff --git a/NevaevaLibrary/TestApp/FormTest.Designer.cs b/NevaevaLibrary/TestApp/FormTest.Designer.cs
index e5f8d35..d137799 100644
--- a/NevaevaLibrary/TestApp/FormTest.Designer.cs
+++ b/NevaevaLibrary/TestApp/FormTest.Designer.cs
@@ -44,6 +44,8 @@
this.openFileDialog = new System.Windows.Forms.OpenFileDialog();
this.buttonTable = new System.Windows.Forms.Button();
this.wordTableComponent = new NevaevaLibrary.LogicalComponents.WordTableComponent(this.components);
+ this.wordDiagramComponent = new NevaevaLibrary.LogicalComponents.WordDiagramComponent(this.components);
+ this.buttonDiagram = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// comboBoxControl
@@ -166,11 +168,22 @@
this.buttonTable.UseVisualStyleBackColor = true;
this.buttonTable.Click += new System.EventHandler(this.buttonTable_Click);
//
+ // buttonDiagram
+ //
+ this.buttonDiagram.Location = new System.Drawing.Point(345, 319);
+ this.buttonDiagram.Name = "buttonDiagram";
+ this.buttonDiagram.Size = new System.Drawing.Size(145, 29);
+ this.buttonDiagram.TabIndex = 12;
+ this.buttonDiagram.Text = "Word (диаграмма)";
+ this.buttonDiagram.UseVisualStyleBackColor = true;
+ this.buttonDiagram.Click += new System.EventHandler(this.buttonDiagram_Click);
+ //
// FormTest
//
this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 20F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(1109, 363);
+ this.Controls.Add(this.buttonDiagram);
this.Controls.Add(this.buttonTable);
this.Controls.Add(this.buttonWordText);
this.Controls.Add(this.buttonGetSelectedList);
@@ -206,5 +219,7 @@
private OpenFileDialog openFileDialog;
private Button buttonTable;
private NevaevaLibrary.LogicalComponents.WordTableComponent wordTableComponent;
+ private NevaevaLibrary.LogicalComponents.WordDiagramComponent wordDiagramComponent;
+ private Button buttonDiagram;
}
}
\ No newline at end of file
diff --git a/NevaevaLibrary/TestApp/FormTest.cs b/NevaevaLibrary/TestApp/FormTest.cs
index 1e97309..338410b 100644
--- a/NevaevaLibrary/TestApp/FormTest.cs
+++ b/NevaevaLibrary/TestApp/FormTest.cs
@@ -100,5 +100,17 @@ namespace TestApp
wordTableComponent.createWithTable(path, "header", merges, widths, headers, workers);
MessageBox.Show("Готово!");
}
+
+ private void buttonDiagram_Click(object sender, EventArgs e)
+ {
+ List departments = new List();
+
+ departments.Add(new Department("Dep 1", new List { 330, 220, 400, 500 }));
+ departments.Add(new Department("Dep 2", new List { 400, 300, 302 }));
+ departments.Add(new Department("Dep 3", new List { 200, 220, 270 }));
+ string path = AppDomain.CurrentDomain.BaseDirectory + "test3.docx";
+ wordDiagramComponent.createWithDiagram(path, "test3", "Продажи", DiagramLegendEnum.TopRight, departments, "name", "sells");
+ MessageBox.Show("Готово!");
+ }
}
}
diff --git a/NevaevaLibrary/TestApp/FormTest.resx b/NevaevaLibrary/TestApp/FormTest.resx
index 65b5cbd..18b2509 100644
--- a/NevaevaLibrary/TestApp/FormTest.resx
+++ b/NevaevaLibrary/TestApp/FormTest.resx
@@ -66,4 +66,7 @@
407, 17
+
+ 612, 17
+
\ No newline at end of file