Лабораторная работа 2

This commit is contained in:
danilafilippov7299 2024-11-05 23:05:50 +04:00
parent 88184c5e6d
commit 8d8d704a13
7 changed files with 515 additions and 0 deletions

View File

@ -32,6 +32,7 @@
this.userControl11 = new WinFormsLibrary1.CheckedListBoxControl();
this.dataControl1 = new WinFormsLibrary1.DataControl();
this.treeViewControl1 = new WinFormsLibrary1.TreeViewControl();
this.excel21 = new WinFormsLibrary1.ExcelTable(this.components);
this.SuspendLayout();
//
// userControl11
@ -80,5 +81,8 @@
private WinFormsLibrary1.CheckedListBoxControl userControl11;
private WinFormsLibrary1.DataControl dataControl1;
private WinFormsLibrary1.TreeViewControl treeViewControl1;
private WinFormsLibrary1.ExcelImages excelComponent1;
private WinFormsLibrary1.ExcelTable excel22;
private WinFormsLibrary1.ExcelTable excel21;
}
}

View File

@ -0,0 +1,36 @@
namespace WinFormsLibrary1
{
partial class ExcelImages
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
}
#endregion
}
}

View File

@ -0,0 +1,80 @@
using System.ComponentModel;
using OfficeOpenXml;
namespace WinFormsLibrary1
{
public partial class ExcelImages : Component
{
public ExcelImages()
{
InitializeComponent();
}
public ExcelImages(IContainer container)
{
container.Add(this);
InitializeComponent();
}
public void CreateDocument(
string filePath,
string documentTitle,
List<Image> images)
{
if (string.IsNullOrWhiteSpace(filePath))
{
throw new ArgumentException("Путь к файлу не может быть пустым.", nameof(filePath));
}
if (string.IsNullOrWhiteSpace(documentTitle))
{
throw new ArgumentException("Название документа не может быть пустым.", nameof(documentTitle));
}
if (images == null || images.Count == 0)
{
throw new ArgumentException("Массив изображений не может быть пустым.", nameof(images));
}
using (var package = new ExcelPackage())
{
var worksheet = package.Workbook.Worksheets.Add(documentTitle);
worksheet.Cells[1, 1].Value = documentTitle;
worksheet.Cells[1, 1].Style.Font.Bold = true;
worksheet.Cells[1, 1].Style.Font.Size = 16;
double row = 2;
foreach (var image in images)
{
var excelImage = worksheet.Drawings.AddPicture($"Image{(int)(row - 1)}", new MemoryStream(ImageToByteArray(image)));
excelImage.SetPosition((int)(row - 1), 0, 0, 0);
excelImage.SetSize(image.Width, image.Height);
row += (int)(image.Height/ PointsToPixels(worksheet.Row(1).Height));
}
FileInfo file = new FileInfo(filePath);
package.SaveAs(file);
}
}
private byte[] ImageToByteArray(Image image)
{
using (var ms = new MemoryStream())
{
image.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
return ms.ToArray();
}
}
// Метод для перевода пунктов в пиксели
static double PointsToPixels(double points)
{
return points * (96.0 / 72.0); // Стандартный DPI для экранов 96 пикселей на дюйм, а 1 пункт = 1/72 дюйма
}
}
}

View File

@ -0,0 +1,36 @@
namespace WinFormsLibrary1
{
partial class ExcelTable
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
}
#endregion
}
}

View File

@ -0,0 +1,212 @@
using System.ComponentModel;
using OfficeOpenXml;
using OfficeOpenXml.Style;
namespace WinFormsLibrary1
{
public partial class ExcelTable : Component
{
public ExcelTable()
{
InitializeComponent();
}
public ExcelTable(IContainer container)
{
container.Add(this);
InitializeComponent();
}
// Публичный метод для создания Excel документа
public void GenerateExcel<T>(string filePath, string documentTitle,
List<MergeInfo> mergeInfo,
List<(string, string, string propertyName)> headerTitles, List<T> data)
{
if (string.IsNullOrEmpty(filePath) || string.IsNullOrEmpty(documentTitle) ||
mergeInfo == null || headerTitles == null || data == null)
{
throw new ArgumentException("Не все входные данные заполнены.");
}
// Проверка на заполненность шапки
ValidateHeaders(headerTitles);
// Проверки на корректность объединения ячеек и заполнения
ValidateMergedCells(mergeInfo, headerTitles.Count);
using (var package = new ExcelPackage())
{
var worksheet = package.Workbook.Worksheets.Add("Sheet1");
worksheet.Cells[1, 1].Value = documentTitle;
worksheet.Cells[1, 1, 1, headerTitles.Count].Merge = true;
worksheet.Cells[1, 1].Style.HorizontalAlignment = ExcelHorizontalAlignment.Center;
//Мержим заголовки по столбцам
for (int i = 1; i < headerTitles.Count; i++)
{
if (headerTitles[i].Item2 == headerTitles[i + 1].Item2)
{
int j;
for (j = i; j < headerTitles.Count; j++)
{
if (headerTitles[j].Item2 != headerTitles[j + 1].Item2) break;
}
mergeInfo.Add(new MergeInfo(2, i + 1, 2, j + 1));
i = j + 1;
}
}
// Заполняем шапку таблицы
for (int i = 0; i < headerTitles.Count; i++)
{
worksheet.Cells[2, i + 1].Value = headerTitles[i].Item2;
worksheet.Cells[3, i + 1].Value = headerTitles[i].Item1;
//Мержим заголовки по строкам
if (headerTitles[i].Item1 == headerTitles[i].Item2) mergeInfo.Add(new MergeInfo(2, i + 1, 3, i + 1));
}
// Применение объединений ячеек
foreach (var merge in mergeInfo)
{
worksheet.Cells[merge.StartRow, merge.StartColumn, merge.EndRow, merge.EndColumn].Merge = true;
}
// Установка высоты строк
for (int i = 0; i < data.Count; i++)
{
}
// Заполнение данных таблицы
for (int rowIndex = 0; rowIndex < data.Count; rowIndex++)
{
var rowData = data[rowIndex];
for (int colIndex = 0; colIndex < headerTitles.Count; colIndex++)
{
// Используем сопоставление полей/свойств объекта
string propertyName = headerTitles[colIndex].propertyName;
var property = rowData.GetType().GetProperty(propertyName);
if (property == null)
throw new ArgumentException($"Свойство {property} не найдено в классе {propertyName}.");
worksheet.Cells[rowIndex + 4, colIndex + 1].Value = property.GetValue(rowData);
}
string propertyName2 = "height";
var propertyHeight = rowData.GetType().GetProperty(propertyName2);
if (propertyHeight == null)
throw new ArgumentException($"Свойство {propertyHeight} не найдено в классе {propertyName2}.");
worksheet.Row(rowIndex + 4).Height = (double)propertyHeight.GetValue(rowData);
}
// Сохранение файла
var file = new FileInfo(filePath);
package.SaveAs(file);
}
}
public class Person
{
public int ID { get; set; } // Идентификатор
public string status { get; set; }
public string name { get; set; }
public string fio { get; set; }
public int Age { get; set; }
public string vos { get; set; }
public string kids { get; set; }
public string dol { get; set; }
public string pod { get; set; }
public int prem { get; set; }
public int height { get; set; }
public Person(int height, int id, string status, string name, string fio, int Age, string vos, string kids, string dol, string pod, int prem)
{
this.height = height;
this.ID = id;
this.status = status;
this.name = name;
this.fio = fio;
this.Age = Age;
this.vos = vos;
this.kids = kids;
this.dol = dol;
this.pod = pod;
this.prem = prem;
}
}
// Метод для проверки на заполненность шапки
private void ValidateHeaders(List<(string, string, string)> headerInfo)
{
foreach (var header in headerInfo)
{
if (string.IsNullOrWhiteSpace(header.Item1) || string.IsNullOrWhiteSpace(header.Item2))
{
throw new ArgumentException("Все ячейки шапки должны быть заполнены.");
}
}
}
// Метод для проверки наложения объединенных ячеек
private void ValidateMergedCells(List<MergeInfo> mergeInfo, int headerColumnsCount)
{
foreach (var merge in mergeInfo)
{
if (merge.StartColumn > headerColumnsCount || merge.EndColumn > headerColumnsCount)
{
throw new ArgumentException("Объединенные ячейки выходят за пределы шапки.");
}
// Дополнительные проверки можно добавить здесь
}
// Проверка на наложение объединенных ячеек
for (int i = 0; i < mergeInfo.Count; i++)
{
var currentMerge = mergeInfo[i];
for (int j = i + 1; j < mergeInfo.Count; j++)
{
var otherMerge = mergeInfo[j];
// Проверка пересечения по строкам и столбцам
bool isOverlapping =
currentMerge.StartRow <= otherMerge.EndRow && currentMerge.EndRow >= otherMerge.StartRow &&
currentMerge.StartColumn <= otherMerge.EndColumn && currentMerge.EndColumn >= otherMerge.StartColumn;
if (isOverlapping)
{
throw new ArgumentException($"Объединенные ячейки пересекаются: [{currentMerge.StartRow},{currentMerge.StartColumn}] - [{currentMerge.EndRow},{currentMerge.EndColumn}] и [{otherMerge.StartRow},{otherMerge.StartColumn}] - [{otherMerge.EndRow},{otherMerge.EndColumn}].");
}
}
}
}
}
}
// Класс для информации об объединении ячеек
public class MergeInfo
{
public int StartRow { get; set; }
public int StartColumn { get; set; }
public int EndRow { get; set; }
public int EndColumn { get; set; }
public MergeInfo(int startRow, int startColumn, int endRow, int endColumn)
{
StartRow = startRow;
StartColumn = startColumn;
EndRow = endRow;
EndColumn = endColumn;
}
}

View File

@ -0,0 +1,36 @@
namespace WinFormsLibrary1
{
partial class PieChart
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
}
#endregion
}
}

View File

@ -0,0 +1,111 @@
using System.ComponentModel;
using OfficeOpenXml;
using OfficeOpenXml.Drawing.Chart;
namespace WinFormsLibrary1
{
public partial class PieChart : Component
{
public PieChart()
{
InitializeComponent();
}
public PieChart(IContainer container)
{
container.Add(this);
InitializeComponent();
}
// Публичный метод для создания Excel-документа с круговой диаграммой
public void CreateExcelWithPieChart(string filePath, string documentTitle,
string chartTitle, LegendPosition legendPosition, List<PieChartData> chartData)
{
if (string.IsNullOrEmpty(filePath) || string.IsNullOrEmpty(documentTitle) || string.IsNullOrEmpty(chartTitle) || chartData == null || chartData.Count == 0)
{
throw new ArgumentException("Все входные данные должны быть заполнены.");
}
using (var package = new ExcelPackage())
{
var worksheet = package.Workbook.Worksheets.Add("ChartSheet");
// Устанавливаем заголовок документа
worksheet.Cells[1, 1].Value = documentTitle;
worksheet.Cells[1, 1, 1, 2].Merge = true;
worksheet.Cells[1, 1].Style.Font.Size = 16;
worksheet.Cells[1, 1].Style.Font.Bold = true;
// Записываем данные для диаграммы в ячейки
int row = 3;
worksheet.Cells[row, 1].Value = "Series";
worksheet.Cells[row, 2].Value = "Value";
foreach (var data in chartData)
{
row++;
worksheet.Cells[row, 1].Value = data.SeriesName;
worksheet.Cells[row, 2].Value = data.Value;
}
// Создаем круговую диаграмму
var pieChart = worksheet.Drawings.AddChart(chartTitle, eChartType.Pie) as ExcelPieChart;
// Устанавливаем диапазоны данных для диаграммы
pieChart.Series.Add(worksheet.Cells[4, 2, row, 2], worksheet.Cells[4, 1, row, 1]);
// Заголовок диаграммы
pieChart.Title.Text = chartTitle;
// Установка положения легенды
switch (legendPosition)
{
case LegendPosition.Top:
pieChart.Legend.Position = eLegendPosition.Top;
break;
case LegendPosition.Bottom:
pieChart.Legend.Position = eLegendPosition.Bottom;
break;
case LegendPosition.Left:
pieChart.Legend.Position = eLegendPosition.Left;
break;
case LegendPosition.Right:
pieChart.Legend.Position = eLegendPosition.Right;
break;
case LegendPosition.None:
pieChart.Legend.Remove();
break;
}
// Сохранение файла
var file = new FileInfo(filePath);
package.SaveAs(file);
}
}
}
public class PieChartData
{
public string SeriesName { get; set; } // Название серии
public double Value { get; set; } // Значение
public PieChartData(string seriesName, double value)
{
SeriesName = seriesName ?? throw new ArgumentNullException(nameof(seriesName));
Value = value;
}
}
// Перечисление для позиции легенды
public enum LegendPosition
{
Top,
Bottom,
Left,
Right,
None
}
}