using RodionovLibrary.NonVisualComponents.HelperEnums; using RodionovLibrary.NonVisualComponents.HelperModels; using Word = Microsoft.Office.Interop.Word; using Excel = Microsoft.Office.Interop.Excel; using System.ComponentModel; namespace RodionovLibrary.NonVisualComponents { public partial class WordDiagramComponent : Component { public WordDiagramComponent() { InitializeComponent(); } public WordDiagramComponent(IContainer container) { container.Add(this); InitializeComponent(); } public void CreateDiagramDocument(WordDiagramInfo diagramInfo) { ValidateDiagramInfo(diagramInfo); var wordApp = new Word.Application(); var document = wordApp.Documents.Add(); AddTitle(document, diagramInfo.DocumentTitle); AddChart(document, diagramInfo); document.SaveAs2(diagramInfo.FileName); wordApp.Quit(); } private void AddTitle(Word.Document document, string title) { var paragraph = document.Paragraphs.Add(); paragraph.Range.Text = title; paragraph.Range.Font.Size = 24; paragraph.Range.Font.Bold = 1; paragraph.Alignment = Word.WdParagraphAlignment.wdAlignParagraphCenter; paragraph.Range.InsertParagraphAfter(); } private void AddChart(Word.Document document, WordDiagramInfo diagramInfo) { var paragraph = document.Paragraphs.Add(); var chartShape = document.InlineShapes.AddChart2(-1, (Microsoft.Office.Core.XlChartType)Excel.XlChartType.xlLine, paragraph.Range); var chart = chartShape.Chart; chart.HasTitle = true; chart.ChartTitle.Text = diagramInfo.DiagramTitle; var chartSeriesCollection = chart.SeriesCollection(); for (int i = chartSeriesCollection.Count; i >= 1; i--) { chartSeriesCollection.Item(i).Delete(); } var categoriesX = diagramInfo.CategoriesX.ToArray(); for (int i = 0; i < diagramInfo.SeriesParameters.Count; i++) { var seriesInfo = diagramInfo.SeriesParameters[i]; var series = chartSeriesCollection.NewSeries(); series.Name = seriesInfo.SeriesName; series.Values = seriesInfo.ValuesY.ToArray(); series.XValues = categoriesX; SetSeriesColor(series, seriesInfo.Color); series.MarkerStyle = Excel.XlMarkerStyle.xlMarkerStyleCircle; series.MarkerSize = 5; } chart.HasLegend = true; chart.Legend.Position = diagramInfo.LegendLayout switch { DiagramLegendLayout.Left => Word.XlLegendPosition.xlLegendPositionLeft, DiagramLegendLayout.Top => Word.XlLegendPosition.xlLegendPositionTop, DiagramLegendLayout.Right => Word.XlLegendPosition.xlLegendPositionRight, DiagramLegendLayout.Bottom => Word.XlLegendPosition.xlLegendPositionBottom, _ => Word.XlLegendPosition.xlLegendPositionBottom, }; chart.ChartData.Workbook.Application.Quit(); } private void SetSeriesColor(dynamic series, Color color) { series.Format.Line.ForeColor.RGB = ColorTranslator.ToOle(color); series.Format.Fill.ForeColor.RGB = ColorTranslator.ToOle(color); } private void ValidateDiagramInfo(WordDiagramInfo diagramInfo) { if (string.IsNullOrEmpty(diagramInfo.FileName) || string.IsNullOrEmpty(diagramInfo.DocumentTitle) || string.IsNullOrEmpty(diagramInfo.DiagramTitle) || diagramInfo.CategoriesX == null || diagramInfo.CategoriesX.Count == 0 || diagramInfo.SeriesParameters == null || diagramInfo.SeriesParameters.Count == 0) { throw new ArgumentException("Не все данные для диаграммы заполнены"); } foreach (var series in diagramInfo.SeriesParameters) { if (string.IsNullOrEmpty(series.SeriesName)) { throw new ArgumentException("Название серии не может быть пустым"); } if (series.ValuesY == null || series.ValuesY.Count == 0) { throw new ArgumentException($"Список значений оси Y для серии '{series.SeriesName}' не заполнен"); } if (diagramInfo.CategoriesX.Count != series.ValuesY.Count) { throw new ArgumentException($"Количество категорий оси X и значений оси Y для серии '{series.SeriesName}' не совпадает"); } } } } }