diff --git a/TestView/Form1.Designer.cs b/TestView/Form1.Designer.cs index cb54318..24d0600 100644 --- a/TestView/Form1.Designer.cs +++ b/TestView/Form1.Designer.cs @@ -48,6 +48,8 @@ openFileDialog1 = new OpenFileDialog(); pdfTable1 = new ViewComponents.NotVisualComponents.PdfTable(components); buttonTestPdfTable = new Button(); + pieChartpdf1 = new ViewComponents.NotVisualComponents.PieChartPDF(components); + buttonChart = new Button(); SuspendLayout(); // // buttonAdd @@ -190,7 +192,7 @@ // // buttonPdfImages // - buttonPdfImages.Location = new Point(36, 393); + buttonPdfImages.Location = new Point(25, 434); buttonPdfImages.Name = "buttonPdfImages"; buttonPdfImages.Size = new Size(197, 29); buttonPdfImages.TabIndex = 15; @@ -205,19 +207,30 @@ // // buttonTestPdfTable // - buttonTestPdfTable.Location = new Point(409, 393); + buttonTestPdfTable.Location = new Point(282, 434); buttonTestPdfTable.Name = "buttonTestPdfTable"; - buttonTestPdfTable.Size = new Size(94, 29); + buttonTestPdfTable.Size = new Size(179, 29); buttonTestPdfTable.TabIndex = 16; - buttonTestPdfTable.Text = "button1"; + buttonTestPdfTable.Text = "Создать таблицу"; buttonTestPdfTable.UseVisualStyleBackColor = true; buttonTestPdfTable.Click += buttonTestPdfTable_Click; // + // buttonChart + // + buttonChart.Location = new Point(534, 434); + buttonChart.Name = "buttonChart"; + buttonChart.Size = new Size(171, 29); + buttonChart.TabIndex = 17; + buttonChart.Text = "Создать диаграмму"; + buttonChart.UseVisualStyleBackColor = true; + buttonChart.Click += buttonChart_Click; + // // Form1 // AutoScaleDimensions = new SizeF(8F, 20F); AutoScaleMode = AutoScaleMode.Font; ClientSize = new Size(899, 600); + Controls.Add(buttonChart); Controls.Add(buttonTestPdfTable); Controls.Add(buttonPdfImages); Controls.Add(myTreeView); @@ -261,5 +274,7 @@ private OpenFileDialog openFileDialog1; private ViewComponents.NotVisualComponents.PdfTable pdfTable1; private Button buttonTestPdfTable; + private ViewComponents.NotVisualComponents.PieChartPDF pieChartpdf1; + private Button buttonChart; } } \ No newline at end of file diff --git a/TestView/Form1.cs b/TestView/Form1.cs index cb110de..eca6350 100644 --- a/TestView/Form1.cs +++ b/TestView/Form1.cs @@ -137,7 +137,8 @@ namespace TestView List<(int, int)> merges = new List<(int, int)>(); merges.Add((2, 4)); - List heights = new List {10, 40, 20, 10, 10, 30, 10, 10, 10, 15, 24 }; + + List heights = new List { 10, 40, 60, 20, 25, 15, 20 }; string path = "C:\\Users\\xarla\\OneDrive\\\\test.pdf"; @@ -146,7 +147,22 @@ namespace TestView (false, ""), (false, " "), (false, " ") }; - if (pdfTable1.createTable(path, "test2", merges, heights, headers, books)) MessageBox.Show(""); + if (pdfTable1.createTable(new DataForPDFTable(path, "test2", heights, merges, headers, books))) MessageBox.Show(""); + } + + private void buttonChart_Click(object sender, EventArgs e) + { + string path = "C:\\Users\\xarla\\OneDrive\\\\chart.pdf"; + List<(double, string)> elements = new List<(double, string)> + { + (200, "̸ "), + (157, ""), + (344, " "), + (588, " "), + (286, " 2033") + }; + + if(pieChartpdf1.CreatePieChart(new DataForPDFPieChart(path, "", " ", DiagramLegendEnum.Top ," ", elements))) MessageBox.Show(""); } } } \ No newline at end of file diff --git a/TestView/Form1.resx b/TestView/Form1.resx index dc63100..21b5733 100644 --- a/TestView/Form1.resx +++ b/TestView/Form1.resx @@ -66,4 +66,7 @@ 317, 17 + + 438, 17 + \ No newline at end of file diff --git a/ViewComponents/NotVisualComponents/DataForPDFPieChart.cs b/ViewComponents/NotVisualComponents/DataForPDFPieChart.cs new file mode 100644 index 0000000..56358be --- /dev/null +++ b/ViewComponents/NotVisualComponents/DataForPDFPieChart.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ViewComponents.NotVisualComponents +{ + public class DataForPDFPieChart + { + public string FilePath = string.Empty; + public string DocumentTitle = string.Empty;//заголовок документа + public string ChartTitle = string.Empty;//заголовок диаграммы + public DiagramLegendEnum diagLegend; + public string LegendName = string.Empty; + public List<(double,string)> Items; + + public DataForPDFPieChart(string filePath, string documentTitle, string charttitle, DiagramLegendEnum diagLegend, string legendName, List<(double, string)> items) + { + FilePath = filePath; + DocumentTitle = documentTitle; + ChartTitle = charttitle; + this.diagLegend = diagLegend; + LegendName = legendName; + Items = items; + } + } +} diff --git a/ViewComponents/NotVisualComponents/DataForPDFTable.cs b/ViewComponents/NotVisualComponents/DataForPDFTable.cs new file mode 100644 index 0000000..124558c --- /dev/null +++ b/ViewComponents/NotVisualComponents/DataForPDFTable.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ViewComponents.NotVisualComponents +{ + public class DataForPDFTable + { + public string FilePath = string.Empty; + public string DocumentTitle = string.Empty; //заголовок документа + public List Heights; // высота строк + public List<(int, int)> Merges; // информаци о объединении ячеек + public List<(bool, string)> Headers; //заголовки шапки таблицы + public List Data; + public DataForPDFTable(string filePath, string documentTitle, List heights, List<(int, int)> merges, List<(bool, string)> headers, List data) + { + FilePath = filePath; + DocumentTitle = documentTitle; + Heights = heights; + Merges = merges; + Headers = headers; + Data = data; + } + } +} diff --git a/ViewComponents/NotVisualComponents/DiagramLegendEnum.cs b/ViewComponents/NotVisualComponents/DiagramLegendEnum.cs new file mode 100644 index 0000000..5e9e99c --- /dev/null +++ b/ViewComponents/NotVisualComponents/DiagramLegendEnum.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ViewComponents.NotVisualComponents +{ + public enum DiagramLegendEnum + { + Top = 0, + Bottom = 1, + Right = 2, + Left = 3, + } +} diff --git a/ViewComponents/NotVisualComponents/PdfTable.cs b/ViewComponents/NotVisualComponents/PdfTable.cs index 69fc980..89d62a7 100644 --- a/ViewComponents/NotVisualComponents/PdfTable.cs +++ b/ViewComponents/NotVisualComponents/PdfTable.cs @@ -26,12 +26,16 @@ namespace ViewComponents.NotVisualComponents InitializeComponent(); } - public bool createTable(string filepath, string header, List<(int, int)> merges, List heights, List<(bool, string)> headers, List items) + public bool createTable(DataForPDFTable dataForPDF) { //проверки - if (merges.Count == 0 || heights.Count == 0 || headers.Count == 0 || items.Count == 0) throw new ArgumentException("Недостаточно данных"); - int[] cellsArray = new int[heights.Count]; - foreach (var merge in merges) + if (dataForPDF.Merges.Count == 0 || dataForPDF.Heights.Count == 0 || dataForPDF.Headers.Count == 0 + || dataForPDF.Data.Count == 0 || string.IsNullOrEmpty(dataForPDF.FilePath) + || string.IsNullOrEmpty(dataForPDF.DocumentTitle)) throw new ArgumentException("Недостаточно данных"); + + int[] cellsArray = new int[dataForPDF.Heights.Count]; + + foreach (var merge in dataForPDF.Merges) { if (merge.Item1 >= merge.Item2) throw new ArgumentException("Неправильно заполнены объединения строк"); for (int i = merge.Item1; i < merge.Item2; i++) @@ -44,6 +48,9 @@ namespace ViewComponents.NotVisualComponents if (cell > 1) throw new ArgumentException("Объединения заходят друг на друга"); } + foreach ((bool, string) el in dataForPDF.Headers) + if (string.IsNullOrEmpty(el.Item2)) throw new ArgumentException("Элементы шапки не могут быть пустыми"); + //создание документа Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); @@ -61,7 +68,7 @@ namespace ViewComponents.NotVisualComponents //добавление заголовка var section = _document.AddSection(); - var paragraph = section.AddParagraph(header); + var paragraph = section.AddParagraph(dataForPDF.DocumentTitle); paragraph.Format.Alignment = ParagraphAlignment.Center; paragraph.Format.SpaceAfter = "2cm"; paragraph.Style = "NormalTitle"; @@ -73,7 +80,7 @@ namespace ViewComponents.NotVisualComponents Column column; - for (int i = 0; i < items.Count + 2; i++) + for (int i = 0; i < dataForPDF.Data.Count + 2; i++) { column = table.AddColumn(); column.Format.Alignment = ParagraphAlignment.Center; @@ -84,37 +91,37 @@ namespace ViewComponents.NotVisualComponents int mergeRange = 0; //размерность слияния int mergeIndex = 0; //стартовый индекс начала слияния Row row; - for (int i = 0; i < headers.Count; i++) + for (int i = 0; i < dataForPDF.Headers.Count; i++) { //если элемент шапки не группируется по строкам - if (headers[i].Item1 == false) + if (dataForPDF.Headers[i].Item1 == false) { //стилизация ячейки row = table.AddRow(); - row.Height = heights[i]; + row.Height = dataForPDF.Heights[i]; row.Format.Font.Bold = true; row.Format.Alignment = ParagraphAlignment.Center; - row.Cells[0].AddParagraph(headers[i].Item2); + row.Cells[0].AddParagraph(dataForPDF.Headers[i].Item2); row.Cells[0].VerticalAlignment = VerticalAlignment.Center; row.Cells[0].MergeRight = 1; - AddTheContent(items, table, row.Index, 2); + AddTheContent(dataForPDF.Data, table, row.Index, 2); mergeIndex++; } //если элемент шапки группируются по строкам - if (headers[i].Item1 == true) + if (dataForPDF.Headers[i].Item1 == true) { - mergeRange = merges.Find(x => x.Item1 == mergeIndex).Item2 - mergeIndex; - mergeIndex = merges.Find(x => x.Item1 == mergeIndex).Item2 + 1; + mergeRange = dataForPDF.Merges.Find(x => x.Item1 == mergeIndex).Item2 - mergeIndex; + mergeIndex = dataForPDF.Merges.Find(x => x.Item1 == mergeIndex).Item2 + 1; //стилизация ячейки. в этом блоке кода (до цикла) создаётся объединяющая ячейка row = table.AddRow(); - row.Height = heights[i]; + row.Height = dataForPDF.Heights[i]; row.Format.Alignment = ParagraphAlignment.Center; row.Format.Font.Bold = true; - row.Cells[0].AddParagraph(headers[i].Item2); + row.Cells[0].AddParagraph(dataForPDF.Headers[i].Item2); row.Cells[0].VerticalAlignment = VerticalAlignment.Center; row.Cells[0].MergeDown = mergeRange; @@ -122,18 +129,18 @@ namespace ViewComponents.NotVisualComponents for (int k = 0; k(items, table, row.Index, 2); + row.Cells[1].AddParagraph(dataForPDF.Headers[i].Item2); + AddTheContent(dataForPDF.Data, table, row.Index, 2); row.Cells[1].VerticalAlignment = VerticalAlignment.Center; row = table.AddRow(); - row.Height = heights[i]; + row.Height = dataForPDF.Heights[i]; row.Format.Font.Bold = true; row.Format.Alignment = ParagraphAlignment.Center; } i++; - row.Cells[1].AddParagraph(headers[i].Item2); - AddTheContent(items, table, row.Index, 2); + row.Cells[1].AddParagraph(dataForPDF.Headers[i].Item2); + AddTheContent(dataForPDF.Data, table, row.Index, 2); row.Cells[1].VerticalAlignment = VerticalAlignment.Center; } } @@ -141,7 +148,7 @@ namespace ViewComponents.NotVisualComponents PdfDocumentRenderer renderer = new PdfDocumentRenderer(true); renderer.Document = _document; renderer.RenderDocument(); - renderer.PdfDocument.Save(filepath); + renderer.PdfDocument.Save(dataForPDF.FilePath); return true; } diff --git a/ViewComponents/NotVisualComponents/PieChartPDF.Designer.cs b/ViewComponents/NotVisualComponents/PieChartPDF.Designer.cs new file mode 100644 index 0000000..1f870c0 --- /dev/null +++ b/ViewComponents/NotVisualComponents/PieChartPDF.Designer.cs @@ -0,0 +1,36 @@ +namespace ViewComponents.NotVisualComponents +{ + partial class PieChartPDF + { + /// + /// Обязательная переменная конструктора. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Освободить все используемые ресурсы. + /// + /// истинно, если управляемый ресурс должен быть удален; иначе ложно. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Код, автоматически созданный конструктором компонентов + + /// + /// Требуемый метод для поддержки конструктора — не изменяйте + /// содержимое этого метода с помощью редактора кода. + /// + private void InitializeComponent() + { + components = new System.ComponentModel.Container(); + } + + #endregion + } +} diff --git a/ViewComponents/NotVisualComponents/PieChartPDF.cs b/ViewComponents/NotVisualComponents/PieChartPDF.cs new file mode 100644 index 0000000..d387e53 --- /dev/null +++ b/ViewComponents/NotVisualComponents/PieChartPDF.cs @@ -0,0 +1,85 @@ +using MigraDoc.DocumentObjectModel; +using MigraDoc.DocumentObjectModel.Shapes.Charts; +using MigraDoc.Rendering; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ViewComponents.NotVisualComponents +{ + public partial class PieChartPDF : Component + { + public PieChartPDF() + { + InitializeComponent(); + } + + public PieChartPDF(IContainer container) + { + container.Add(this); + + InitializeComponent(); + } + + public bool CreatePieChart(DataForPDFPieChart dataForPDFPie) + { + // проверки + if (string.IsNullOrEmpty(dataForPDFPie.FilePath) || string.IsNullOrEmpty(dataForPDFPie.DocumentTitle) || string.IsNullOrEmpty(dataForPDFPie.ChartTitle) + || string.IsNullOrEmpty(dataForPDFPie.LegendName) + || dataForPDFPie.Items.Count == 0) throw new ArgumentException("Недостаточно данных"); + + Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); + + Document _document = new Document(); + var section = _document.AddSection(); + var paragraph = section.AddParagraph(dataForPDFPie.DocumentTitle); + paragraph.Format.Alignment = ParagraphAlignment.Center; + paragraph.Format.SpaceAfter = "2cm"; + + Chart chart = section.AddChart(ChartType.Pie2D); + chart.Width = Unit.FromCentimeter(16); + chart.Height = Unit.FromCentimeter(12); + chart.HeaderArea.AddParagraph(dataForPDFPie.ChartTitle); // заголовок диаграммы + + Series series = chart.SeriesCollection.AddSeries(); + series.Name = dataForPDFPie.LegendName; // название сериии + XSeries xseries = chart.XValues.AddXSeries(); + + foreach ((double, string) el in dataForPDFPie.Items) // заполнение серии + { + series.Add(el.Item1); + xseries.Add(el.Item2); + } + + switch (dataForPDFPie.diagLegend) // позиция легенды + { + case DiagramLegendEnum.Top: + chart.TopArea.AddLegend(); + break; + case DiagramLegendEnum.Bottom: + chart.BottomArea.AddLegend(); + break; + case DiagramLegendEnum.Right: + chart.RightArea.AddLegend(); + break; + case DiagramLegendEnum.Left: + chart.LeftArea.AddLegend(); + break; + } + + chart.DataLabel.Type = DataLabelType.Percent; + chart.DataLabel.Position = DataLabelPosition.OutsideEnd; + + PdfDocumentRenderer renderer = new PdfDocumentRenderer(true); + renderer.Document = _document; + renderer.RenderDocument(); + renderer.PdfDocument.Save(dataForPDFPie.FilePath); + + return true; + } + } +}