using System.ComponentModel; using Excel = Microsoft.Office.Interop.Excel; namespace Components { public partial class ComponentExcelWithPieDiagram : Component { public ComponentExcelWithPieDiagram() { InitializeComponent(); } public ComponentExcelWithPieDiagram(IContainer container) : this() { container.Add(this); } public enum LegendPosition { Top, Bottom, Left, Right } public class ChartData { [DisplayName("Серия")] public string SeriesName { get; set; } [DisplayName("Значение")] public double SeriesValue { get; set; } } private void CheckInputValues( string filePath, string fileTitle, string chartTitle, LegendPosition legendPosition, List data) { if (string.IsNullOrEmpty(filePath)) { throw new ArgumentNullException(nameof(filePath)); } if (string.IsNullOrEmpty(fileTitle)) { throw new ArgumentNullException(nameof(fileTitle)); } if (string.IsNullOrEmpty(chartTitle)) { throw new ArgumentNullException(nameof(chartTitle)); } double chartSum = 0; foreach (var item in data) { if (!string.IsNullOrEmpty(item.SeriesName)) { chartSum += item.SeriesValue; } else { throw new ArgumentNullException("Series name is null or empty"); } if (item.SeriesValue == 0 || item.SeriesValue > 100) { throw new ArgumentOutOfRangeException("Series value is out of range"); } } if (chartSum > 100) { throw new ArgumentOutOfRangeException("Series values sum is out of range"); } } public void CreateExcelWithPieChart( string filePath, string fileTitle, string chartTitle, LegendPosition legendPosition, List data) { CheckInputValues(filePath, fileTitle, chartTitle, legendPosition, data); Excel.Application excelApp = new Excel.Application(); Excel.Workbook workbook = excelApp.Workbooks.Add(); Excel.Worksheet worksheet = workbook.Sheets[1]; worksheet.Cells[1, 1] = fileTitle; int dataStartRow = 3; for (int i = 0; i < data.Count; i++) { worksheet.Cells[dataStartRow + i, 1] = data[i].SeriesName; worksheet.Cells[dataStartRow + i, 2] = data[i].SeriesValue; } Excel.ChartObjects chartObjects = (Excel.ChartObjects)worksheet.ChartObjects(); Excel.ChartObject chartObject = chartObjects.Add(300, 50, 400, 300); Excel.Chart chart = chartObject.Chart; chart.ChartType = Excel.XlChartType.xlPie; Excel.Range chartRange = worksheet.get_Range("A3", $"B{dataStartRow + data.Count - 1}"); chart.SetSourceData(chartRange); chart.HasTitle = true; chart.ChartTitle.Text = chartTitle; SetLegendPosition(chart, legendPosition); workbook.SaveAs(filePath); workbook.Close(); excelApp.Quit(); ReleaseObject(worksheet); ReleaseObject(workbook); ReleaseObject(excelApp); } private void SetLegendPosition(Excel.Chart chart, LegendPosition legendPosition) { chart.HasLegend = true; switch (legendPosition) { case LegendPosition.Top: chart.Legend.Position = Excel.XlLegendPosition.xlLegendPositionTop; break; case LegendPosition.Bottom: chart.Legend.Position = Excel.XlLegendPosition.xlLegendPositionBottom; break; case LegendPosition.Left: chart.Legend.Position = Excel.XlLegendPosition.xlLegendPositionLeft; break; case LegendPosition.Right: chart.Legend.Position = Excel.XlLegendPosition.xlLegendPositionRight; break; } } private void ReleaseObject(object obj) { try { if (obj != null) { System.Runtime.InteropServices.Marshal.ReleaseComObject(obj); obj = null; } } catch (Exception ex) { obj = null; Console.WriteLine("Error releasing object: " + ex.ToString()); } finally { GC.Collect(); } } } }