160 lines
5.0 KiB
C#
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();
|
|
}
|
|
}
|
|
}
|
|
}
|