diff --git a/KopLab1/FormLibrary/ComponentHistogramToPdf.Designer.cs b/KopLab1/FormLibrary/ComponentHistogramToPdf.Designer.cs new file mode 100644 index 0000000..dd57dd7 --- /dev/null +++ b/KopLab1/FormLibrary/ComponentHistogramToPdf.Designer.cs @@ -0,0 +1,36 @@ +namespace FormLibrary +{ + partial class ComponentHistogramToPdf + { + /// + /// Обязательная переменная конструктора. + /// + 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/KopLab1/FormLibrary/ComponentHistogramToPdf.cs b/KopLab1/FormLibrary/ComponentHistogramToPdf.cs new file mode 100644 index 0000000..0321175 --- /dev/null +++ b/KopLab1/FormLibrary/ComponentHistogramToPdf.cs @@ -0,0 +1,88 @@ +using FormLibrary.HelperClasses; +using MigraDoc.DocumentObjectModel; +using MigraDoc.DocumentObjectModel.Shapes; +using MigraDoc.DocumentObjectModel.Shapes.Charts; +using MigraDoc.Rendering; +using OxyPlot.Series; +using OxyPlot; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using OxyPlot.WindowsForms; + +namespace FormLibrary +{ + public partial class ComponentHistogramToPdf : Component + { + public ComponentHistogramToPdf() + { + InitializeComponent(); + } + + public ComponentHistogramToPdf(IContainer container) + { + container.Add(this); + + InitializeComponent(); + } + public void CreateHistogramPdf(string filePath, string documentTitle, string chartTitle, LegendPosition legendPosition, List chartData) + { + // Проверка на заполненность входных данных + if (string.IsNullOrEmpty(filePath)) + throw new ArgumentException("Путь к файлу не может быть пустым."); + if (string.IsNullOrEmpty(documentTitle)) + throw new ArgumentException("Название документа не может быть пустым."); + if (string.IsNullOrEmpty(chartTitle)) + throw new ArgumentException("Заголовок диаграммы не может быть пустым."); + if (chartData == null || chartData.Count == 0) + throw new ArgumentException("Набор данных не может быть пустым."); + + foreach (var data in chartData) + { + if (string.IsNullOrEmpty(data.SeriesName) || data.Data == null || data.Data.Count == 0) + throw new ArgumentException($"Набор данных для серии '{data.SeriesName}' некорректен."); + } + + // Создание графика + var plotModel = new PlotModel { Title = chartTitle }; + foreach (var data in chartData) + { + var barSeries = new BarSeries { Title = data.SeriesName }; + foreach (var item in data.Data) + { + barSeries.Items.Add(new BarItem(item.Value)); + } + plotModel.Series.Add(barSeries); + } + + // Сохранение графика в изображение + var pngExporter = new PngExporter { Width = 600, Height = 400}; + using (var stream = new MemoryStream()) + { + pngExporter.Export(plotModel, stream); + File.WriteAllBytes("chart.png", stream.ToArray()); + } + + // Создание документа + Document document = new Document(); + document.Info.Title = documentTitle; + document.Info.Subject = "Гистограмма"; + + Section section = document.AddSection(); + section.AddParagraph(chartTitle, "Heading1"); + + // Вставка изображения в PDF + var image = section.AddImage("chart.png"); + image.Width = Unit.FromCentimeter(15); + + // Сохранение документа в PDF + PdfDocumentRenderer renderer = new PdfDocumentRenderer(true) { Document = document }; + renderer.RenderDocument(); + renderer.PdfDocument.Save(filePath); + + // Удалите временное изображение, если необходимо + File.Delete("chart.png"); + } + + } +} diff --git a/KopLab1/FormLibrary/FormLibrary.csproj b/KopLab1/FormLibrary/FormLibrary.csproj index 7fbd9ef..8a64cb8 100644 --- a/KopLab1/FormLibrary/FormLibrary.csproj +++ b/KopLab1/FormLibrary/FormLibrary.csproj @@ -8,6 +8,9 @@ + + + diff --git a/KopLab1/FormLibrary/HelperClasses/ChartData.cs b/KopLab1/FormLibrary/HelperClasses/ChartData.cs new file mode 100644 index 0000000..2abfa48 --- /dev/null +++ b/KopLab1/FormLibrary/HelperClasses/ChartData.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FormLibrary.HelperClasses +{ + public class ChartData + { + public string SeriesName { get; set; } + public Dictionary Data { get; set; } // Ключ — категория, значение — значение для гистограммы + } + +} diff --git a/KopLab1/FormLibrary/HelperClasses/LegendPosition.cs b/KopLab1/FormLibrary/HelperClasses/LegendPosition.cs new file mode 100644 index 0000000..b4d4996 --- /dev/null +++ b/KopLab1/FormLibrary/HelperClasses/LegendPosition.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FormLibrary.HelperClasses +{ + public enum LegendPosition + { + Top, + Bottom, + Left, + Right + } +} diff --git a/KopLab1/FormLibrary/HelperClasses/PDFTableSettings.cs b/KopLab1/FormLibrary/HelperClasses/PDFTableSettings.cs new file mode 100644 index 0000000..07ef99a --- /dev/null +++ b/KopLab1/FormLibrary/HelperClasses/PDFTableSettings.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FormLibrary.HelperClasses +{ + public class PDFTableSettings + { + public string FilePath { get; set; } + public string DocumentTitle { get; set; } + public List HeaderTitles { get; set; } + public List ColumnWidths { get; set; } + public float HeaderRowHeight { get; set; } + public float DataRowHeight { get; set; } + public List DataList { get; set; } + public Dictionary ColumnPropertyMappings { get; set; } + } + +} diff --git a/KopLab1/FormLibrary/HelperClasses/PdfDocumentData.cs b/KopLab1/FormLibrary/HelperClasses/PdfDocumentData.cs new file mode 100644 index 0000000..f7ad35e --- /dev/null +++ b/KopLab1/FormLibrary/HelperClasses/PdfDocumentData.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace FormLibrary.HelperClasses +{ + public class PdfDocumentData + { + public string FileName { get; set; } + public string DocumentTitle { get; set; } + public List Tables { get; set; } + + public PdfDocumentData(string fileName, string documentTitle, List tables) + { + FileName = fileName ?? throw new ArgumentNullException(nameof(fileName)); + DocumentTitle = documentTitle ?? throw new ArgumentNullException(nameof(documentTitle)); + Tables = tables ?? throw new ArgumentNullException(nameof(tables)); + } + } + +} diff --git a/KopLab1/FormLibrary/PDFTable.cs b/KopLab1/FormLibrary/PDFTable.cs index 3f8c9f9..d46223a 100644 --- a/KopLab1/FormLibrary/PDFTable.cs +++ b/KopLab1/FormLibrary/PDFTable.cs @@ -1,4 +1,5 @@ -using MigraDoc.DocumentObjectModel; +using FormLibrary.HelperClasses; +using MigraDoc.DocumentObjectModel; using MigraDoc.DocumentObjectModel.Tables; using MigraDoc.Rendering; using System.ComponentModel; @@ -22,41 +23,34 @@ namespace FormLibrary InitializeComponent(); } - // Публичный метод для генерации PDF-документа - public void GeneratePdf(string fileName, string documentTitle, List tables) - { - // Проверка на корректность входных данных - if (string.IsNullOrWhiteSpace(fileName)) throw new ArgumentException("Имя файла не может быть пустым."); - if (string.IsNullOrWhiteSpace(documentTitle)) throw new ArgumentException("Название документа не может быть пустым."); - if (tables == null || tables.Count == 0) throw new ArgumentException("Необходимо передать хотя бы одну таблицу."); - // Создание документа + public void GeneratePdf(PdfDocumentData pdfData) + { + if (string.IsNullOrWhiteSpace(pdfData.FileName)) throw new ArgumentException("Имя файла не может быть пустым."); + if (string.IsNullOrWhiteSpace(pdfData.DocumentTitle)) throw new ArgumentException("Название документа не может быть пустым."); + if (pdfData.Tables == null || pdfData.Tables.Count == 0) throw new ArgumentException("Необходимо передать хотя бы одну таблицу."); + Document document = new Document(); Section section = document.AddSection(); - // Установка заголовка документа Paragraph title = section.AddParagraph(); - title.AddFormattedText(documentTitle, TextFormat.Bold); + title.AddFormattedText(pdfData.DocumentTitle, TextFormat.Bold); title.Format.Alignment = ParagraphAlignment.Center; - section.AddParagraph(); // Пустая строка + section.AddParagraph(); - // Обработка таблиц - foreach (var tableData in tables) + foreach (var tableData in pdfData.Tables) { - // Создание таблицы Table table = section.AddTable(); int columnsCount = tableData.GetLength(1); - // Определение колонок for (int i = 0; i < columnsCount; i++) { - Column column = table.AddColumn(Unit.FromCentimeter(3)); // Ширина колонки 3 см + Column column = table.AddColumn(Unit.FromCentimeter(3)); } - // Настройка границ таблицы - table.Borders.Width = 0.75; // Толщина границ таблицы - table.Borders.Color = Colors.Black; // Цвет границ таблицы - // Добавление строк и ячеек + table.Borders.Width = 0.75; + table.Borders.Color = Colors.Black; + for (int i = 0; i < tableData.GetLength(0); i++) { Row row = table.AddRow(); @@ -66,14 +60,13 @@ namespace FormLibrary } } - section.AddParagraph(); // Пустая строка после таблицы + section.AddParagraph(); } - - // Сохранение документа PdfDocumentRenderer pdfRenderer = new PdfDocumentRenderer(true); pdfRenderer.Document = document; pdfRenderer.RenderDocument(); - pdfRenderer.PdfDocument.Save(fileName); + pdfRenderer.PdfDocument.Save(pdfData.FileName); } + } } diff --git a/KopLab1/FormLibrary/PDFTableCustom.Designer.cs b/KopLab1/FormLibrary/PDFTableCustom.Designer.cs new file mode 100644 index 0000000..9cf32a3 --- /dev/null +++ b/KopLab1/FormLibrary/PDFTableCustom.Designer.cs @@ -0,0 +1,36 @@ +namespace FormLibrary +{ + partial class PDFTableCustom + { + /// + /// Обязательная переменная конструктора. + /// + 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/KopLab1/FormLibrary/PDFTableCustom.cs b/KopLab1/FormLibrary/PDFTableCustom.cs new file mode 100644 index 0000000..5786758 --- /dev/null +++ b/KopLab1/FormLibrary/PDFTableCustom.cs @@ -0,0 +1,92 @@ +using FormLibrary.HelperClasses; +using MigraDoc.DocumentObjectModel.Tables; +using MigraDoc.DocumentObjectModel; +using MigraDoc.Rendering; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Diagnostics; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; + +namespace FormLibrary +{ + public partial class PDFTableCustom : Component + { + public PDFTableCustom() + { + InitializeComponent(); + System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance); + } + + public PDFTableCustom(IContainer container) + { + container.Add(this); + + InitializeComponent(); + } + public void GeneratePDFWithHead(PDFTableSettings settings) + { + if (settings == null || + string.IsNullOrEmpty(settings.FilePath) || + string.IsNullOrEmpty(settings.DocumentTitle) || + settings.HeaderTitles == null || settings.HeaderTitles.Count == 0 || + settings.ColumnWidths == null || settings.DataList == null || + settings.ColumnPropertyMappings == null) + throw new ArgumentException("Заполнены не все необходимые данные для генерации документа."); + + if (settings.HeaderTitles.Count != settings.ColumnWidths.Count) + throw new ArgumentException("Количество заголовков должно совпадать с количеством ширин столбцов."); + + + Document document = new Document(); + Section section = document.AddSection(); + section.AddParagraph(settings.DocumentTitle, "Heading1"); + + Table table = new Table(); + table.Borders.Width = 0.75; + + // столбцы + for (int i = 0; i < settings.ColumnWidths.Count; i++) + { + Column column = table.AddColumn(Unit.FromCentimeter(settings.ColumnWidths[i])); + column.Format.Alignment = ParagraphAlignment.Center; + } + + // заголовки + Row headerRow = table.AddRow(); + headerRow.Height = Unit.FromCentimeter(settings.HeaderRowHeight); + for (int i = 0; i < settings.HeaderTitles.Count; i++) + { + headerRow.Cells[i].AddParagraph(settings.HeaderTitles[i]); + headerRow.Cells[i].Format.Font.Bold = true; + headerRow.Cells[i].Format.Alignment = ParagraphAlignment.Center; + } + + // данные + foreach (var dataItem in settings.DataList) + { + Row row = table.AddRow(); + row.Height = Unit.FromCentimeter(settings.DataRowHeight); + + foreach (var columnMapping in settings.ColumnPropertyMappings) + { + PropertyInfo propertyInfo = typeof(T).GetProperty(columnMapping.Value); + if (propertyInfo == null) + throw new ArgumentException($"Свойство {columnMapping.Value} не найдено в классе {typeof(T).Name}."); + + object value = propertyInfo.GetValue(dataItem); + row.Cells[columnMapping.Key].AddParagraph(value != null ? value.ToString() : ""); + } + } + + section.Add(table); + + PdfDocumentRenderer renderer = new PdfDocumentRenderer(true) { Document = document }; + renderer.RenderDocument(); + renderer.Save(settings.FilePath); + } + } +} diff --git a/KopLab1/Forms/MainForm.Designer.cs b/KopLab1/Forms/MainForm.Designer.cs index 48b0130..0b792f3 100644 --- a/KopLab1/Forms/MainForm.Designer.cs +++ b/KopLab1/Forms/MainForm.Designer.cs @@ -42,6 +42,11 @@ button7 = new Button(); pdfTable1 = new FormLibrary.PDFTable(components); button8 = new Button(); + pdfTableCustom1 = new FormLibrary.PDFTableCustom(components); + button9 = new Button(); + button10 = new Button(); + button11 = new Button(); + componentHistogramToPdf1 = new FormLibrary.ComponentHistogramToPdf(components); SuspendLayout(); // // customListBox1 @@ -153,11 +158,41 @@ button8.UseVisualStyleBackColor = true; button8.Click += GeneratePdfButton_Click; // + // button9 + // + button9.Location = new Point(189, 481); + button9.Name = "button9"; + button9.Size = new Size(139, 23); + button9.TabIndex = 12; + button9.Text = "Create customPDF"; + button9.UseVisualStyleBackColor = true; + button9.Click += btnGeneratePDF_Click; + // + // button10 + // + button10.Location = new Point(0, 0); + button10.Name = "button10"; + button10.Size = new Size(75, 23); + button10.TabIndex = 0; + // + // button11 + // + button11.Location = new Point(347, 481); + button11.Name = "button11"; + button11.Size = new Size(139, 23); + button11.TabIndex = 13; + button11.Text = "Create customPDF"; + button11.UseVisualStyleBackColor = true; + button11.Click += btnGenerateHistogrammPdf_Click; + // // MainForm // AutoScaleDimensions = new SizeF(7F, 15F); AutoScaleMode = AutoScaleMode.Font; ClientSize = new Size(944, 625); + Controls.Add(button11); + Controls.Add(button10); + Controls.Add(button9); Controls.Add(button8); Controls.Add(button7); Controls.Add(button6); @@ -191,5 +226,10 @@ private Button button7; private FormLibrary.PDFTable pdfTable1; private Button button8; + private FormLibrary.PDFTableCustom pdfTableCustom1; + private Button button9; + private Button button10; + private Button button11; + private FormLibrary.ComponentHistogramToPdf componentHistogramToPdf1; } } \ No newline at end of file diff --git a/KopLab1/Forms/MainForm.cs b/KopLab1/Forms/MainForm.cs index f5af8fd..6007219 100644 --- a/KopLab1/Forms/MainForm.cs +++ b/KopLab1/Forms/MainForm.cs @@ -130,39 +130,92 @@ namespace Forms { try { - // Создаем экземпляр компонента для генерации PDF + var pdfData = new PdfDocumentData( + "G:\\Отчет1.pdf", + "Название документа", + new List + { + new string[,] + { + { "Ячейка 1", "Ячейка 2", "Ячейка 3" }, + { "Ячейка 4", "Ячейка 5", "Ячейка 6" } + }, + new string[,] + { + { "Ячейка 1", "Ячейка 2" }, + { "Ячейка 1", "Ячейка 2" } + } + }); + var documentGenerator = new PDFTable(); + documentGenerator.GeneratePdf(pdfData); - // Пример таблиц - var tables = new List - { - new string[,] - { - { "test 1", "test 2", "test 3" }, - { "test 4", "test 5", "test 6" } - }, - new string[,] - { - { "test 1", "test 2" }, - { "test 1", "test 2" } - } - }; - - // Вызываем метод для создания PDF - string filePath = "G:\\Отчет.pdf"; - string documentTitle = "test name"; - - documentGenerator.GeneratePdf(filePath, documentTitle, tables); - - // Уведомляем пользователя MessageBox.Show("PDF-документ успешно создан!", "Успех", MessageBoxButtons.OK, MessageBoxIcon.Information); } catch (Exception ex) { - // Обрабатываем ошибки MessageBox.Show($"Произошла ошибка: {ex.Message}", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); } } + private void btnGeneratePDF_Click(object sender, EventArgs e) + { + // Создание объекта настроек + var settings = new PDFTableSettings + { + FilePath = "G:\\Отчет2.pdf", + DocumentTitle = "Отчет по студентам", + HeaderTitles = new List { "Группа", "ФИО", "Курс" }, + ColumnWidths = new List { 4.0f, 6.0f, 2.0f }, + HeaderRowHeight = 1.0f, + DataRowHeight = 1.0f, + DataList = new List + { + new Student { Group = "Пибд-33", FullName = "Иван Иванов", Course = 3 }, + new Student { Group = "Пибд-33", FullName = "Петр Петров", Course = 2 }, + new Student { Group = "Пибд-34", FullName = "Алексей Сидоров", Course = 4 } + }, + ColumnPropertyMappings = new Dictionary + { + { 0, nameof(Student.Group) }, + { 1, nameof(Student.FullName) }, + { 2, nameof(Student.Course) } + } + }; + try + { + pdfTableCustom1.GeneratePDFWithHead(settings); + MessageBox.Show("PDF-документ успешно создан!", "Успех", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + catch (Exception ex) + { + MessageBox.Show($"Ошибка: {ex.Message}"); + } + } + private void btnGenerateHistogrammPdf_Click(object sender, EventArgs e) + { + try + { + var histogramGenerator = new ComponentHistogramToPdf(); + + var chartData = new List + { + new ChartData { SeriesName = "Серия 1", Data = new Dictionary { { "Категория 1", 5 }, { "Категория 2", 10 } } }, + new ChartData { SeriesName = "Серия 2", Data = new Dictionary { { "Категория 1", 3 }, { "Категория 2", 8 } } } + }; + + // Укажите путь, куда хотите сохранить PDF + string filePath = "G:\\Гистограмма.pdf"; + + // Генерация PDF + histogramGenerator.CreateHistogramPdf(filePath, "Название документа", "Заголовок диаграммы", LegendPosition.Top, chartData); + + MessageBox.Show("PDF успешно сгенерирован!", "Успех", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + catch (Exception ex) + { + MessageBox.Show($"Ошибка: {ex.Message}", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } } } diff --git a/KopLab1/Forms/MainForm.resx b/KopLab1/Forms/MainForm.resx index cd97873..9c89390 100644 --- a/KopLab1/Forms/MainForm.resx +++ b/KopLab1/Forms/MainForm.resx @@ -120,4 +120,10 @@ 17, 17 + + 122, 17 + + + 269, 17 + \ No newline at end of file diff --git a/KopLab1/Forms/Program.cs b/KopLab1/Forms/Program.cs index ff6d1a9..a71be2f 100644 --- a/KopLab1/Forms/Program.cs +++ b/KopLab1/Forms/Program.cs @@ -1,3 +1,5 @@ +using System.Text; + namespace Forms { internal static class Program @@ -10,6 +12,7 @@ namespace Forms { // To customize application configuration such as set high DPI settings or default font, // see https://aka.ms/applicationconfiguration. + Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); ApplicationConfiguration.Initialize(); Application.Run(new MainForm()); }