PIbd-31_PotapovNS_COP_20/WinFormSolution/Components/ComponentExcelWithPieDiagram.cs

160 lines
5.0 KiB
C#

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<ChartData> 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<ChartData> 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();
}
}
}
}