diff --git a/COP_LabWork.sln b/COP_LabWork.sln new file mode 100644 index 0000000..460eb79 --- /dev/null +++ b/COP_LabWork.sln @@ -0,0 +1,37 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.5.33502.453 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestForms", "TestForms\TestForms.csproj", "{8F7F9843-EC02-4318-B507-0D114253D021}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CustomComponents", "CustomComponents\CustomComponents.csproj", "{84341626-2887-45C2-9D91-FB8B5A14EBFB}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExcelComponents", "ExcelComponents\ExcelComponents.csproj", "{D649516B-CA77-4AEF-AB2C-515B92331527}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {8F7F9843-EC02-4318-B507-0D114253D021}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8F7F9843-EC02-4318-B507-0D114253D021}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8F7F9843-EC02-4318-B507-0D114253D021}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8F7F9843-EC02-4318-B507-0D114253D021}.Release|Any CPU.Build.0 = Release|Any CPU + {84341626-2887-45C2-9D91-FB8B5A14EBFB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {84341626-2887-45C2-9D91-FB8B5A14EBFB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {84341626-2887-45C2-9D91-FB8B5A14EBFB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {84341626-2887-45C2-9D91-FB8B5A14EBFB}.Release|Any CPU.Build.0 = Release|Any CPU + {D649516B-CA77-4AEF-AB2C-515B92331527}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D649516B-CA77-4AEF-AB2C-515B92331527}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D649516B-CA77-4AEF-AB2C-515B92331527}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D649516B-CA77-4AEF-AB2C-515B92331527}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {308288F3-F285-4816-9F45-4BE8A1BF6F8A} + EndGlobalSection +EndGlobal diff --git a/CustomComponents/CustomComponents.csproj b/CustomComponents/CustomComponents.csproj new file mode 100644 index 0000000..8782907 --- /dev/null +++ b/CustomComponents/CustomComponents.csproj @@ -0,0 +1,10 @@ + + + + net6.0-windows + enable + true + enable + + + diff --git a/CustomComponents/DateTextBox.Designer.cs b/CustomComponents/DateTextBox.Designer.cs new file mode 100644 index 0000000..e671454 --- /dev/null +++ b/CustomComponents/DateTextBox.Designer.cs @@ -0,0 +1,59 @@ +namespace CustomComponents +{ + partial class DateTextBox + { + /// + /// Обязательная переменная конструктора. + /// + 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() + { + textBox = new TextBox(); + SuspendLayout(); + // + // textBox + // + textBox.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right; + textBox.Location = new Point(0, 0); + textBox.Name = "textBox"; + textBox.Size = new Size(150, 27); + textBox.TabIndex = 0; + textBox.TextChanged += textBox_TextChanged; + textBox.Enter += textBox_Enter; + // + // DateTextBox + // + AutoScaleDimensions = new SizeF(8F, 20F); + AutoScaleMode = AutoScaleMode.Font; + Controls.Add(textBox); + Name = "DateTextBox"; + Size = new Size(150, 28); + ResumeLayout(false); + PerformLayout(); + } + + #endregion + + private TextBox textBox; + } +} diff --git a/CustomComponents/DateTextBox.cs b/CustomComponents/DateTextBox.cs new file mode 100644 index 0000000..2488ae2 --- /dev/null +++ b/CustomComponents/DateTextBox.cs @@ -0,0 +1,95 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace CustomComponents +{ + public partial class DateTextBox : UserControl + { + private string? pattern; + private string example = "Формат ввода: DD.MM.YYYY"; + public DateTextBox() + { + InitializeComponent(); + } + public string? Pattern + { + get { return pattern; } + set { pattern = value; } + } + public string TextBoxValue + { + get + { + Regex regex = new Regex(Pattern); + bool isValid = regex.IsMatch(textBox.Text); + if (isValid) + { + return textBox.Text; + } + else + { + Error = "Неправильный ввод"; + return null; + } + } + set + { + if (value == null) return; + Regex regex = new Regex(Pattern); + bool isValid = regex.IsMatch(value); + if (isValid) + { + textBox.Text = value; + } + else + { + Error = "Неправильно"; + } + } + } + public string Error + { + get; private set; + } + public void SetExample(string exampleStr) + { + Regex regex = new Regex(Pattern); + bool isValid = regex.IsMatch(exampleStr); + if (isValid) + { + example = exampleStr; + } + } + private void textBox_Enter(object sender, EventArgs e) + { + ToolTip tt = new ToolTip(); + tt.Show(example, textBox, 30, -20, 1000); + } + + private void textBox_TextChanged(object sender, EventArgs e) + { + _changeEvent?.Invoke(sender, e); + } + + private EventHandler _changeEvent; + public event EventHandler ChangeEvent + { + add + { + _changeEvent += value; + } + remove + { + _changeEvent -= value; + } + } + } +} diff --git a/CustomComponents/DateTextBox.resx b/CustomComponents/DateTextBox.resx new file mode 100644 index 0000000..f298a7b --- /dev/null +++ b/CustomComponents/DateTextBox.resx @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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/CustomComponents/DropDownList.Designer.cs b/CustomComponents/DropDownList.Designer.cs new file mode 100644 index 0000000..ba2a0f3 --- /dev/null +++ b/CustomComponents/DropDownList.Designer.cs @@ -0,0 +1,58 @@ +namespace CustomComponents +{ + partial class DropDownList + { + /// + /// Обязательная переменная конструктора. + /// + 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() + { + ComboBox = new ComboBox(); + SuspendLayout(); + // + // ComboBox + // + ComboBox.DropDownStyle = ComboBoxStyle.DropDownList; + ComboBox.FormattingEnabled = true; + ComboBox.Location = new Point(0, 0); + ComboBox.Name = "ComboBox"; + ComboBox.Size = new Size(151, 28); + ComboBox.TabIndex = 0; + ComboBox.SelectedIndexChanged += ComboBox_SelectedIndexChanged; + // + // DropDownList + // + AutoScaleDimensions = new SizeF(8F, 20F); + AutoScaleMode = AutoScaleMode.Font; + Controls.Add(ComboBox); + Name = "DropDownList"; + Size = new Size(154, 29); + ResumeLayout(false); + } + + #endregion + + private ComboBox ComboBox; + } +} diff --git a/CustomComponents/DropDownList.cs b/CustomComponents/DropDownList.cs new file mode 100644 index 0000000..87621ea --- /dev/null +++ b/CustomComponents/DropDownList.cs @@ -0,0 +1,70 @@ +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; + +namespace CustomComponents +{ + public partial class DropDownList : UserControl + { + public DropDownList() + { + InitializeComponent(); + } + public void AddToList(string value) + { + if (value == null) + { + return; + } + ComboBox.Items.Add(value); + } + public void ClearList() + { + ComboBox.Items.Clear(); + } + + private void ComboBox_SelectedIndexChanged(object sender, EventArgs e) + { + _changeEvent?.Invoke(sender, e); + + } + + public string? Selected + { + get + { + if (ComboBox.Items.Count == 0 || ComboBox.SelectedItem == null) + { + return ""; + } + return ComboBox.SelectedItem.ToString()!; + } + set + { + if (ComboBox.Items.Contains(value)) + { + ComboBox.SelectedItem = value; + } + } + } + private EventHandler _changeEvent; + public event EventHandler ChangeEvent + { + add + { + _changeEvent += value; + } + remove + { + _changeEvent -= value; + } + + } + } +} diff --git a/CustomComponents/DropDownList.resx b/CustomComponents/DropDownList.resx new file mode 100644 index 0000000..f298a7b --- /dev/null +++ b/CustomComponents/DropDownList.resx @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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/CustomComponents/ListBoxObjects.Designer.cs b/CustomComponents/ListBoxObjects.Designer.cs new file mode 100644 index 0000000..f6e4945 --- /dev/null +++ b/CustomComponents/ListBoxObjects.Designer.cs @@ -0,0 +1,57 @@ +namespace CustomComponents +{ + partial class ListBoxObjects + { + /// + /// Обязательная переменная конструктора. + /// + 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() + { + listBox = new ListBox(); + SuspendLayout(); + // + // listBox + // + listBox.FormattingEnabled = true; + listBox.ItemHeight = 20; + listBox.Location = new Point(0, 0); + listBox.Name = "listBox"; + listBox.Size = new Size(458, 144); + listBox.TabIndex = 0; + // + // ListBoxObjects + // + AutoScaleDimensions = new SizeF(8F, 20F); + AutoScaleMode = AutoScaleMode.Font; + Controls.Add(listBox); + Name = "ListBoxObjects"; + Size = new Size(458, 143); + ResumeLayout(false); + } + + #endregion + + private ListBox listBox; + } +} diff --git a/CustomComponents/ListBoxObjects.cs b/CustomComponents/ListBoxObjects.cs new file mode 100644 index 0000000..8adaccb --- /dev/null +++ b/CustomComponents/ListBoxObjects.cs @@ -0,0 +1,95 @@ +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; + +namespace CustomComponents +{ + public partial class ListBoxObjects : UserControl + { + private string LayoutString; + private string StartS; + private string EndS; + private int SelectedStr; + public ListBoxObjects() + { + InitializeComponent(); + } + public int SelectedIndex { + get { + if (listBox.SelectedIndex == -1) + { + return -1; + } + return listBox.SelectedIndex; + } + set + { + if(listBox.Items.Count != 0) + { + listBox.SelectedIndex = value; + } + } + } + public void SetLayout(string layoutString, string startS, string endS) + { + if (layoutString == null || startS == null || endS == null) return; + LayoutString = layoutString; + StartS = startS; + EndS = endS; + } + public void AddItemInList(T Object) + { + if (Object == null) + { + throw new ArgumentNullException(); + } + if (!LayoutString.Contains(StartS) && !LayoutString.Contains(EndS)) + { + return; + } + string str = LayoutString; + + foreach (var prop in Object.GetType().GetProperties()) + { + string str1 = $"{StartS}" + prop.Name + $"{EndS}"; + str = str.Replace(str1, $"{StartS}" + prop.GetValue(Object).ToString() + $"{EndS}"); + } + listBox.Items.Add(str); + } + + public T GetItemFromList() where T : class, new() + { + string SelectedStr = ""; + if (listBox.SelectedIndex != -1) + { + SelectedStr = listBox.SelectedItem.ToString(); + } + + T currentObject = new T(); + + foreach (var prop in typeof(T).GetProperties()) + { + if (!prop.CanWrite) + { + continue; + } + int startS = SelectedStr.IndexOf(StartS); + int endS = SelectedStr.IndexOf(EndS); + if (startS == -1 || endS == -1) + { + break; + } + string propValue = SelectedStr.Substring(startS + 1, endS - startS - 1); + SelectedStr = SelectedStr.Substring(endS + 1); + prop.SetValue(currentObject, Convert.ChangeType(propValue, prop.PropertyType)); + } + return currentObject; + } + } +} diff --git a/CustomComponents/ListBoxObjects.resx b/CustomComponents/ListBoxObjects.resx new file mode 100644 index 0000000..f298a7b --- /dev/null +++ b/CustomComponents/ListBoxObjects.resx @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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/CustomComponents/Objects/DaysOfWeek.cs b/CustomComponents/Objects/DaysOfWeek.cs new file mode 100644 index 0000000..b597a05 --- /dev/null +++ b/CustomComponents/Objects/DaysOfWeek.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CustomComponents.Objects +{ + public class DaysOfWeek + { + public DateTime Date { get; set; } + public string Day { get; set; } + public int Temperature { get; set; } + public DaysOfWeek(DateTime date, string day, int temperature) + { + Date = date; + Day = day; + Temperature = temperature; + } + public DaysOfWeek() { } + } +} diff --git a/ExcelComponents/BigTextExcel.Designer.cs b/ExcelComponents/BigTextExcel.Designer.cs new file mode 100644 index 0000000..c2beb9d --- /dev/null +++ b/ExcelComponents/BigTextExcel.Designer.cs @@ -0,0 +1,36 @@ +namespace ExcelComponents +{ + partial class BigTextExcel + { + /// + /// Обязательная переменная конструктора. + /// + 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/ExcelComponents/BigTextExcel.cs b/ExcelComponents/BigTextExcel.cs new file mode 100644 index 0000000..70ff844 --- /dev/null +++ b/ExcelComponents/BigTextExcel.cs @@ -0,0 +1,44 @@ +using ExcelComponents.Models; +using System.ComponentModel; + +namespace ExcelComponents +{ + public partial class BigTextExcel : Component + { + private readonly ExcelBuilder builder = new(); + public BigTextExcel() + { + InitializeComponent(); + } + + public BigTextExcel(IContainer container) + { + container.Add(this); + + InitializeComponent(); + } + private static bool ConfigIsCorrect(BigTextConfig config) + { + if(config == null) + { + return false; + } + if(string.IsNullOrEmpty(config.FilePath) || File.Exists(config.FilePath)) + { + return false; + } + return true; + } + public void BigTextGen(BigTextConfig config) + { + if(!ConfigIsCorrect(config)) + { + return; + } + builder.CreateDocument(); + builder.InsertText(1, 1, config.Title); + builder.InsertBigText(config.Text); + builder.SaveDocument(config.FilePath); + } + } +} diff --git a/ExcelComponents/ExcelBuilder.cs b/ExcelComponents/ExcelBuilder.cs new file mode 100644 index 0000000..7e5e3db --- /dev/null +++ b/ExcelComponents/ExcelBuilder.cs @@ -0,0 +1,221 @@ +using ExcelComponents.Models; +using OfficeOpenXml; +using OfficeOpenXml.Drawing.Chart; +using OfficeOpenXml.Style; +using System; +using System.Collections.Generic; +using System.Data.Common; +using System.Drawing.Drawing2D; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ExcelComponents +{ + public class ExcelBuilder + { + private ExcelPackage? package = null; + private ExcelWorksheet? worksheet = null; + public ExcelBuilder() + { + ExcelPackage.LicenseContext = LicenseContext.NonCommercial; + } + private void SetStyle(int row, int col, ExcelCellStyle style) + { + if (worksheet == null) + { + return; + } + ExcelStyle excelStyle = worksheet.Cells[row, col].Style; + excelStyle.WrapText = style.WrapText; + excelStyle.HorizontalAlignment = style.HorizontalAlignment; + excelStyle.VerticalAlignment = style.VerticalAlignment; + excelStyle.Border.Top.Style = style.TopBorderStyle; + excelStyle.Border.Bottom.Style = style.BottomBorderStyle; + excelStyle.Border.Left.Style = style.LeftBorderStyle; + excelStyle.Border.Right.Style = style.RightBorderStyle; + } + private void SetStyle(int row, int col, int endRow, int endCol, ExcelCellStyle style) + { + if (worksheet == null) + { + return; + } + ExcelStyle excelStyle = worksheet.Cells[row, col, endRow, endCol].Style; + excelStyle.WrapText = style.WrapText; + excelStyle.HorizontalAlignment = style.HorizontalAlignment; + excelStyle.VerticalAlignment = style.VerticalAlignment; + excelStyle.Border.Top.Style = style.TopBorderStyle; + excelStyle.Border.Bottom.Style = style.BottomBorderStyle; + excelStyle.Border.Left.Style = style.LeftBorderStyle; + excelStyle.Border.Right.Style = style.RightBorderStyle; + } + + private void MergeCells(int row, int col, int endRow, int endCol, ExcelCellStyle? style = null) + { + if(worksheet == null) { return; } + worksheet.Cells[row, col, endRow, endCol].Merge = true; + style ??= new(); + SetStyle(row, col, endRow, endCol, style); + } + public void ConfigureColumns(double[] columnWidth) + { + if(worksheet == null) + { + return; + } + for(int i = 0; i < columnWidth.Length; i++) + { + worksheet.Column(i+1).Width = columnWidth[i]; + } + } + public void CreateDocument() + { + package = new(); + worksheet = package.Workbook.Worksheets.Add("First list"); + } + public void SaveDocument(string filePath) + { + package?.SaveAs(filePath); + } + public void InsertText(int row, int column, string str,ExcelCellStyle? style = null) + { + if(worksheet == null) + { + return; + } + worksheet.Cells[row, column].Value = str; + style ??= new(); + SetStyle(row, column, style); + } + private static string GetPropertyValue(string propertyName, T obj) + { + Type type = typeof(T); + string value = type.GetProperty(propertyName)!.GetValue(obj, null).ToString()!; + return value; + } + public void InsertTable(Dictionary merge, string[] headers, string[] props, T[] data ) + { + if(worksheet == null) + { + return; + } + ExcelCellStyle style = new() + { + NoBorder = false, + WrapText = true, + }; + + int rowInd = 2; + int colStart = 1; + int colInd = colStart; + int mergeskip = 0; + + foreach(string header in headers){ + InsertText(rowInd, colInd, header,style); + if (mergeskip == 0) + { + if (!merge.ContainsKey(colInd - colStart)) + { + MergeCells(rowInd, colInd, rowInd + 1, colInd, style); + colInd++; + } + else + { + int colEnd = colInd + merge[colInd - colStart] - 1; + MergeCells(rowInd, colInd, rowInd, colEnd, style); + rowInd = 3; + mergeskip = merge[colInd - colStart]; + } + } + else + { + mergeskip--; + colInd++; + if(mergeskip == 0) + { + rowInd = 2; + } + } + } + rowInd++; + for(int i = 0; i < data.Length; i++) + { + colInd = colStart; + rowInd++; + foreach(string prop in props) + { + string value = GetPropertyValue(prop, data[i]); + InsertText(rowInd, colInd, value, style); + colInd++; + } + } + } + public void InsertBigText(string[] text, ExcelCellStyle? style = null) + { + if (worksheet == null) + { + return; + } + style ??= new() { HorizontalAlignment = ExcelHorizontalAlignment.Left}; + for (int i = 0; i < text.Length; i++) + { + worksheet.Cells[i + 2, 1].Value = text[i]; + MergeCells(i + 2, 1, i + 2, text[i].Length / 7 + 1, style); + } + } + public void InsertLinearChart(string chartTitle, List<(string, double[])> data, string[] labels, ChartLegendPosition legendPosition) + { + if(worksheet == null) { return; } + ExcelChart linearchar = (ExcelLineChart)worksheet.Drawings.AddChart("Linear Chart", eChartType.Line); + linearchar.Title.Text = chartTitle; + foreach(var item in data) + { + linearchar.Series.Add(ArrayToString(item.Item2)).Header = item.Item1; + } + linearchar.Series[0].XSeries = ArrayToString(labels); + linearchar.Legend.Position = GetLegendPosition(legendPosition); + linearchar.SetSize(500, 500); + linearchar.SetPosition(1, 0, 0, 0); + } + private static string ArrayToString(T[] data) + { + StringBuilder builder = new StringBuilder("{"); + for(int i = 0; i < data.Length; i++) + { + if (typeof(T) == typeof(string)) + { + builder.Append($"\"{data[i]}\""); + } + else if (typeof(T) == typeof(double)) + { + builder.Append(data[i].ToString().Replace(",", ".")); + } + else + { + builder.Append(data[i].ToString()); + } + if(i == data.Length - 1) + { + builder.Append('}'); + } + else + { + builder.Append(','); + } + } + return builder.ToString(); + } + private static eLegendPosition GetLegendPosition(ChartLegendPosition legendPosition) + { + return legendPosition switch + { + ChartLegendPosition.Top => eLegendPosition.Top, + ChartLegendPosition.Bottom => eLegendPosition.Bottom, + ChartLegendPosition.Left => eLegendPosition.Left, + ChartLegendPosition.Right => eLegendPosition.Right, + _ => eLegendPosition.Right + }; + } + } +} diff --git a/ExcelComponents/ExcelComponents.csproj b/ExcelComponents/ExcelComponents.csproj new file mode 100644 index 0000000..9a719a0 --- /dev/null +++ b/ExcelComponents/ExcelComponents.csproj @@ -0,0 +1,14 @@ + + + + net6.0-windows + enable + true + enable + + + + + + + diff --git a/ExcelComponents/ExcelLinearChart.Designer.cs b/ExcelComponents/ExcelLinearChart.Designer.cs new file mode 100644 index 0000000..d920c2b --- /dev/null +++ b/ExcelComponents/ExcelLinearChart.Designer.cs @@ -0,0 +1,36 @@ +namespace ExcelComponents +{ + partial class ExcelLinearChart + { + /// + /// Обязательная переменная конструктора. + /// + 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/ExcelComponents/ExcelLinearChart.cs b/ExcelComponents/ExcelLinearChart.cs new file mode 100644 index 0000000..dcec0cb --- /dev/null +++ b/ExcelComponents/ExcelLinearChart.cs @@ -0,0 +1,57 @@ +using ExcelComponents.Models; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ExcelComponents +{ + public partial class ExcelLinearChart : Component + { + ExcelBuilder builder = new ExcelBuilder(); + public ExcelLinearChart() + { + InitializeComponent(); + } + + public ExcelLinearChart(IContainer container) + { + container.Add(this); + + InitializeComponent(); + } + private static bool ConfigIsCorrect(LinearChartConfig config) + { + if (config == null) + { + return false; + } + if (string.IsNullOrEmpty(config.FilePath) || File.Exists(config.FilePath)) + { + return false; + } + foreach(var item in config.Data) + { + if (config.Labels.Length != item.Item2.Length) + { + return false; + } + } + return true; + } + public void GenChart(LinearChartConfig config) + { + if (!ConfigIsCorrect(config)) + { + return; + } + builder.CreateDocument(); + builder.InsertText(1, 1, config.Title); + builder.InsertLinearChart(config.ChartTitle, config.Data, config.Labels, config.LegendPosition); + builder.SaveDocument(config.FilePath); + } + } +} diff --git a/ExcelComponents/ExcelTable.Designer.cs b/ExcelComponents/ExcelTable.Designer.cs new file mode 100644 index 0000000..c736654 --- /dev/null +++ b/ExcelComponents/ExcelTable.Designer.cs @@ -0,0 +1,36 @@ +namespace ExcelComponents +{ + partial class ExcelTable + { + /// + /// Обязательная переменная конструктора. + /// + 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/ExcelComponents/ExcelTable.cs b/ExcelComponents/ExcelTable.cs new file mode 100644 index 0000000..951fa1a --- /dev/null +++ b/ExcelComponents/ExcelTable.cs @@ -0,0 +1,60 @@ +using ExcelComponents.Models; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ExcelComponents +{ + public partial class ExcelTable : Component + { + private readonly ExcelBuilder builder = new(); + public ExcelTable() + { + InitializeComponent(); + } + + public ExcelTable(IContainer container) + { + container.Add(this); + + InitializeComponent(); + } + private static bool ConfigIsCorrect(TableConfig config) + { + if (config == null) + { + return false; + } + if (string.IsNullOrEmpty(config.FilePath) || File.Exists(config.FilePath)) + { + return false; + } + int[] mergeIndexes = config.Merge.Keys.ToArray(); + Array.Sort(mergeIndexes); + for(int i = 0; i < mergeIndexes.Length - 1; i++) + { + if (mergeIndexes[i] + config.Merge[mergeIndexes[i]] >= mergeIndexes[i+1]) + { + return false; + } + } + return true; + } + public void GenTable(TableConfig config) + { + if(!ConfigIsCorrect(config)) + { + return; + } + builder.CreateDocument(); + builder.ConfigureColumns(config.ColWidth); + builder.InsertText(1, 1, config.Title); + builder.InsertTable(config.Merge, config.Headers, config.Props, config.Data); + builder.SaveDocument(config.FilePath); + } + } +} diff --git a/ExcelComponents/Models/BigTextConfig.cs b/ExcelComponents/Models/BigTextConfig.cs new file mode 100644 index 0000000..ed28a75 --- /dev/null +++ b/ExcelComponents/Models/BigTextConfig.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ExcelComponents.Models +{ + public class BigTextConfig : ExcelConfig + { + public string[] Text { get; set; } + public BigTextConfig() + { + Text = Array.Empty(); + } + } +} diff --git a/ExcelComponents/Models/ChartLegendPosition.cs b/ExcelComponents/Models/ChartLegendPosition.cs new file mode 100644 index 0000000..05ad607 --- /dev/null +++ b/ExcelComponents/Models/ChartLegendPosition.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ExcelComponents.Models +{ + public enum ChartLegendPosition + { + Top = 1, + Bottom = 2, + Left = 3, + Right = 4 + } +} diff --git a/ExcelComponents/Models/ExcelCellStyle.cs b/ExcelComponents/Models/ExcelCellStyle.cs new file mode 100644 index 0000000..3b5a07f --- /dev/null +++ b/ExcelComponents/Models/ExcelCellStyle.cs @@ -0,0 +1,92 @@ +using OfficeOpenXml.Style; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms.VisualStyles; + +namespace ExcelComponents.Models +{ + public class ExcelCellStyle + { + public bool WrapText {get; set;} + public ExcelHorizontalAlignment HorizontalAlignment { get; set;} + public ExcelVerticalAlignment VerticalAlignment { get; set;} + public bool NoBorder { get; set;} + private ExcelBorderStyle topBorderStyle; + public ExcelBorderStyle TopBorderStyle { + get + { + if (NoBorder) + { + return ExcelBorderStyle.None; + } + return topBorderStyle; + } + set + { + topBorderStyle = value; + } + } + private ExcelBorderStyle bottomBorderStyle; + public ExcelBorderStyle BottomBorderStyle + { + get + { + if (NoBorder) + { + return ExcelBorderStyle.None; + } + return bottomBorderStyle; + } + set + { + bottomBorderStyle = value; + } + } + private ExcelBorderStyle leftBorderStyle; + public ExcelBorderStyle LeftBorderStyle + { + get + { + if (NoBorder) + { + return ExcelBorderStyle.None; + } + return leftBorderStyle; + } + set + { + leftBorderStyle = value; + } + } + private ExcelBorderStyle rightBorderStyle; + public ExcelBorderStyle RightBorderStyle + { + get + { + if (NoBorder) + { + return ExcelBorderStyle.None; + } + return rightBorderStyle; + } + set + { + rightBorderStyle = value; + } + } + public ExcelCellStyle() + { + WrapText = false; + NoBorder = true; + HorizontalAlignment = ExcelHorizontalAlignment.Center; + VerticalAlignment = ExcelVerticalAlignment.Center; + topBorderStyle = ExcelBorderStyle.Thin; + bottomBorderStyle = ExcelBorderStyle.Thin; + leftBorderStyle = ExcelBorderStyle.Thin; + rightBorderStyle = ExcelBorderStyle.Thin; + } + } +} diff --git a/ExcelComponents/Models/ExcelConfig.cs b/ExcelComponents/Models/ExcelConfig.cs new file mode 100644 index 0000000..3a177ca --- /dev/null +++ b/ExcelComponents/Models/ExcelConfig.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Security.Policy; +using System.Text; +using System.Threading.Tasks; + +namespace ExcelComponents.Models +{ + public class ExcelConfig + { + public string FilePath { get; set; } + public string Title { get; set; } + public ExcelConfig() + { + FilePath = string.Empty; + Title = string.Empty; + } + } +} diff --git a/ExcelComponents/Models/LinearChartConfig.cs b/ExcelComponents/Models/LinearChartConfig.cs new file mode 100644 index 0000000..c8f4311 --- /dev/null +++ b/ExcelComponents/Models/LinearChartConfig.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ExcelComponents.Models +{ + public class LinearChartConfig : ExcelConfig + { + public string ChartTitle { get; set; } + public List<(string, double[])> Data {get; set;} + public string[] Labels { get; set; } + public ChartLegendPosition LegendPosition { get; set; } + public LinearChartConfig() + { + ChartTitle = string.Empty; + Data = new List<(string, double[])>(); + Labels = Array.Empty(); + LegendPosition = ChartLegendPosition.Right; + } + } +} diff --git a/ExcelComponents/Models/TableConfig.cs b/ExcelComponents/Models/TableConfig.cs new file mode 100644 index 0000000..ab09394 --- /dev/null +++ b/ExcelComponents/Models/TableConfig.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ExcelComponents.Models +{ + public class TableConfig : ExcelConfig + { + public string[] Headers { get; set; } + public double[] ColWidth { get; set; } + public T[] Data { get; set; } + public string[] Props { get; set; } + public Dictionary Merge { get; set; } + public TableConfig() + { + Headers = Array.Empty(); + ColWidth = Array.Empty(); + Data = Array.Empty(); + Merge = new(); + Props = Array.Empty(); + } + } +} diff --git a/TestForms/Employee.cs b/TestForms/Employee.cs new file mode 100644 index 0000000..d999497 --- /dev/null +++ b/TestForms/Employee.cs @@ -0,0 +1,16 @@ +namespace TestForms +{ + public class Employee + { + public int Id { get; set; } + public bool Status { get; set; } + public string FirstName { get; set; } = string.Empty; + public string LastName { get; set; } = string.Empty; + public int Age { get; set; } + public bool Children { get; set; } + public bool Car { get; set; } + public string Subdivision { get; set; } = string.Empty; + public string Post { get; set; } = string.Empty; + public double Bonus { get; set; } + } +} diff --git a/TestForms/Program.cs b/TestForms/Program.cs new file mode 100644 index 0000000..9803143 --- /dev/null +++ b/TestForms/Program.cs @@ -0,0 +1,17 @@ +namespace TestForms +{ + internal static class Program + { + /// + /// The main entry point for the application. + /// + [STAThread] + static void Main() + { + // To customize application configuration such as set high DPI settings or default font, + // see https://aka.ms/applicationconfiguration. + ApplicationConfiguration.Initialize(); + Application.Run(new TestForm()); + } + } +} \ No newline at end of file diff --git a/TestForms/TestForm.Designer.cs b/TestForms/TestForm.Designer.cs new file mode 100644 index 0000000..adac6d1 --- /dev/null +++ b/TestForms/TestForm.Designer.cs @@ -0,0 +1,177 @@ +namespace TestForms +{ + partial class TestForm + { + /// + /// 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() + { + components = new System.ComponentModel.Container(); + textBoxTitle = new TextBox(); + ButtonBigText = new Button(); + saveFileDialog = new SaveFileDialog(); + bigTextExcel = new ExcelComponents.BigTextExcel(components); + excelTable = new ExcelComponents.ExcelTable(components); + ButtonTable = new Button(); + richTextBox = new RichTextBox(); + label1 = new Label(); + label2 = new Label(); + label3 = new Label(); + ButtonChart = new Button(); + excelLinearChart = new ExcelComponents.ExcelLinearChart(components); + textBoxChartTitle = new TextBox(); + label4 = new Label(); + SuspendLayout(); + // + // textBoxTitle + // + textBoxTitle.Location = new Point(12, 45); + textBoxTitle.Name = "textBoxTitle"; + textBoxTitle.Size = new Size(148, 27); + textBoxTitle.TabIndex = 15; + // + // ButtonBigText + // + ButtonBigText.Location = new Point(12, 103); + ButtonBigText.Name = "ButtonBigText"; + ButtonBigText.Size = new Size(148, 29); + ButtonBigText.TabIndex = 16; + ButtonBigText.Text = "Create Big Text"; + ButtonBigText.UseVisualStyleBackColor = true; + ButtonBigText.Click += ButtonBigText_Click; + // + // saveFileDialog + // + saveFileDialog.FileName = "output.xlsx"; + // + // ButtonTable + // + ButtonTable.Location = new Point(12, 138); + ButtonTable.Name = "ButtonTable"; + ButtonTable.Size = new Size(148, 29); + ButtonTable.TabIndex = 18; + ButtonTable.Text = "Сreate Table"; + ButtonTable.UseVisualStyleBackColor = true; + ButtonTable.Click += ButtonTable_Click; + // + // richTextBox + // + richTextBox.Location = new Point(185, 45); + richTextBox.Name = "richTextBox"; + richTextBox.Size = new Size(432, 104); + richTextBox.TabIndex = 19; + richTextBox.Text = "Всё ускоряющаяся эволюция\n компьютерных технологий предъявила \nжёсткие\n требования к производителям как собственно вычислительной техники, так и\n периферийных устройств."; + // + // label1 + // + label1.AutoSize = true; + label1.Location = new Point(12, 22); + label1.Name = "label1"; + label1.Size = new Size(38, 20); + label1.TabIndex = 20; + label1.Text = "Title"; + // + // label2 + // + label2.AutoSize = true; + label2.Location = new Point(12, 80); + label2.Name = "label2"; + label2.Size = new Size(83, 20); + label2.TabIndex = 21; + label2.Text = "Some work"; + // + // label3 + // + label3.AutoSize = true; + label3.Location = new Point(185, 22); + label3.Name = "label3"; + label3.Size = new Size(69, 20); + label3.TabIndex = 22; + label3.Text = "BIG TEXT"; + // + // ButtonChart + // + ButtonChart.Location = new Point(12, 173); + ButtonChart.Name = "ButtonChart"; + ButtonChart.Size = new Size(148, 29); + ButtonChart.TabIndex = 23; + ButtonChart.Text = "Create chart"; + ButtonChart.UseVisualStyleBackColor = true; + ButtonChart.Click += ButtonChart_Click; + // + // textBoxChartTitle + // + textBoxChartTitle.Location = new Point(185, 175); + textBoxChartTitle.Name = "textBoxChartTitle"; + textBoxChartTitle.Size = new Size(123, 27); + textBoxChartTitle.TabIndex = 24; + // + // label4 + // + label4.AutoSize = true; + label4.Location = new Point(185, 152); + label4.Name = "label4"; + label4.Size = new Size(73, 20); + label4.TabIndex = 25; + label4.Text = "ChartTitle"; + // + // TestForm + // + AutoScaleDimensions = new SizeF(8F, 20F); + AutoScaleMode = AutoScaleMode.Font; + ClientSize = new Size(632, 360); + Controls.Add(label4); + Controls.Add(textBoxChartTitle); + Controls.Add(ButtonChart); + Controls.Add(label3); + Controls.Add(label2); + Controls.Add(label1); + Controls.Add(richTextBox); + Controls.Add(ButtonTable); + Controls.Add(ButtonBigText); + Controls.Add(textBoxTitle); + Name = "TestForm"; + Text = "TestForm"; + ResumeLayout(false); + PerformLayout(); + } + + #endregion + private TextBox textBoxTitle; + private Button ButtonBigText; + private SaveFileDialog saveFileDialog; + private ExcelComponents.BigTextExcel bigTextExcel; + private ExcelComponents.ExcelTable excelTable; + private Button ButtonTable; + private RichTextBox richTextBox; + private Label label1; + private Label label2; + private Label label3; + private Button ButtonChart; + private ExcelComponents.ExcelLinearChart excelLinearChart; + private TextBox textBoxChartTitle; + private Label label4; + } +} \ No newline at end of file diff --git a/TestForms/TestForm.cs b/TestForms/TestForm.cs new file mode 100644 index 0000000..f2b7cb2 --- /dev/null +++ b/TestForms/TestForm.cs @@ -0,0 +1,118 @@ +using CustomComponents.Objects; +using ExcelComponents.Models; +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; + +namespace TestForms +{ + public partial class TestForm : Form + { + public TestForm() + { + + InitializeComponent(); + + } + + private void ButtonBigText_Click(object sender, EventArgs e) + { + if (saveFileDialog.ShowDialog() == DialogResult.OK && !string.IsNullOrEmpty(textBoxTitle.Text)) + { + bigTextExcel.BigTextGen(new BigTextConfig() + { + FilePath = saveFileDialog.FileName, + Title = textBoxTitle.Text, + Text = richTextBox.Lines + }); + } + } + + private void ButtonTable_Click(object sender, EventArgs e) + { + if (saveFileDialog.ShowDialog() == DialogResult.OK && !string.IsNullOrEmpty(textBoxTitle.Text)) + { + string[] headers = new[] + { + "Идент", "Статус", "Личные данные", + "Имя", "Фамилия", "Возраст", + "Дети", "Машина", "Работа", + "Подразделение", "Должность", "Премия" + }; + double[] colWidth = new double[] { 10, 10, 15, 15, 15, 10, 10, 15, 15, 10 }; + Dictionary merge = new() { [7] = 2, [2] = 3 }; + Employee[] data = new Employee[] + { + new Employee() + { + Id = 1, + Status = false, + FirstName = "First name 1", + LastName = "Last name 1", + Age = 20, + Children = true, + Car = false, + Subdivision = "Subdivision 1", + Post = "Post 1", + Bonus = 0.0 + }, + new Employee() + { + Id = 2, + Status = false, + FirstName = "First name 2", + LastName = "Last name 2", + Age = 21, + Children = false, + Car = true, + Subdivision = "Subdivision 2", + Post = "Post 2", + Bonus = 2.0 + }, + }; + string[] props = new string[] + { + "Id", "Status", "FirstName", + "LastName", "Age", "Children", + "Car", "Subdivision", "Post", "Bonus" + }; + excelTable.GenTable(new TableConfig() + { + Title = textBoxTitle.Text, + FilePath = saveFileDialog.FileName, + ColWidth = colWidth, + Headers = headers, + Data = data, + Props = props, + Merge = merge + }); + } + } + + private void ButtonChart_Click(object sender, EventArgs e) + { + if (saveFileDialog.ShowDialog() == DialogResult.OK && !string.IsNullOrEmpty(textBoxTitle.Text) && !string.IsNullOrEmpty(textBoxChartTitle.Text)) + { + excelLinearChart.GenChart(new LinearChartConfig() + { + Title = textBoxTitle.Text, + FilePath = saveFileDialog.FileName, + ChartTitle = textBoxChartTitle.Text, + Data = new List<(string, double[])> + { + ("header1", new double[] { 5.5, 4, 3, 2.7, 1 }), + ("header2", new double[] { 1.2, 2.1, 3.2, 4, 5 }) + }, + Labels = new[] { "pepsi", "cola", "fanta", "idk", "pchel" }, + LegendPosition = ChartLegendPosition.Bottom + }); + } + } + } +} diff --git a/TestForms/TestForm.resx b/TestForms/TestForm.resx new file mode 100644 index 0000000..b364930 --- /dev/null +++ b/TestForms/TestForm.resx @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + 17, 17 + + + 171, 17 + + + 308, 17 + + + 431, 17 + + \ No newline at end of file diff --git a/TestForms/TestForms.csproj b/TestForms/TestForms.csproj new file mode 100644 index 0000000..d271901 --- /dev/null +++ b/TestForms/TestForms.csproj @@ -0,0 +1,16 @@ + + + + WinExe + net6.0-windows + enable + true + enable + + + + + + + + \ No newline at end of file