From b4035d6b136f21c41f95ea3be2c08a8ba955c185 Mon Sep 17 00:00:00 2001 From: dyakonovr Date: Sun, 29 Sep 2024 21:12:45 +0400 Subject: [PATCH] lab2 --- WinFormsApp1/Form1.Designer.cs | 69 ++++++- WinFormsApp1/Form1.cs | 125 ++++++++++++- WinFormsApp1/Form1.resx | 3 + WinFormsLibrary1/Configs/Diagram/Location.cs | 16 ++ .../Configs/Diagram/PdfWithDiagramConfig.cs | 28 +++ .../Configs/Image/PdfWithImageConfig.cs | 23 +++ .../Configs/Table/PdfWithTableConfig.cs | 88 +++++++++ WinFormsLibrary1/CustomTextBox.Designer.cs | 8 +- WinFormsLibrary1/Models/Human.cs | 22 +++ WinFormsLibrary1/PdfWithDiagram.Designer.cs | 36 ++++ WinFormsLibrary1/PdfWithDiagram.cs | 117 ++++++++++++ WinFormsLibrary1/PdfWithImages.Designer.cs | 36 ++++ WinFormsLibrary1/PdfWithImages.cs | 177 ++++++++++++++++++ WinFormsLibrary1/PdfWithTable.Designer.cs | 36 ++++ WinFormsLibrary1/PdfWithTable.cs | 110 +++++++++++ WinFormsLibrary1/WinFormsLibrary1.csproj | 4 + 16 files changed, 891 insertions(+), 7 deletions(-) create mode 100644 WinFormsLibrary1/Configs/Diagram/Location.cs create mode 100644 WinFormsLibrary1/Configs/Diagram/PdfWithDiagramConfig.cs create mode 100644 WinFormsLibrary1/Configs/Image/PdfWithImageConfig.cs create mode 100644 WinFormsLibrary1/Configs/Table/PdfWithTableConfig.cs create mode 100644 WinFormsLibrary1/Models/Human.cs create mode 100644 WinFormsLibrary1/PdfWithDiagram.Designer.cs create mode 100644 WinFormsLibrary1/PdfWithDiagram.cs create mode 100644 WinFormsLibrary1/PdfWithImages.Designer.cs create mode 100644 WinFormsLibrary1/PdfWithImages.cs create mode 100644 WinFormsLibrary1/PdfWithTable.Designer.cs create mode 100644 WinFormsLibrary1/PdfWithTable.cs diff --git a/WinFormsApp1/Form1.Designer.cs b/WinFormsApp1/Form1.Designer.cs index 25c0bea..485317c 100644 --- a/WinFormsApp1/Form1.Designer.cs +++ b/WinFormsApp1/Form1.Designer.cs @@ -28,6 +28,7 @@ /// private void InitializeComponent() { + components = new System.ComponentModel.Container(); customCheckedListBox = new WinFormsLibrary1.CustomCheckedListBox(); addInListboxItemButton = new Button(); clearListboxButton = new Button(); @@ -46,6 +47,12 @@ addEmployeeButton = new Button(); departamentComboBox = new ComboBox(); getSelectedTreeItemButton = new Button(); + pdfWithImages1 = new WinFormsLibrary1.PdfWithImages(components); + listBoxImages = new ListBox(); + button1 = new Button(); + createPdfButton = new Button(); + pdfTableButton = new Button(); + pdfDiagramButton = new Button(); SuspendLayout(); // // customCheckedListBox @@ -213,11 +220,65 @@ getSelectedTreeItemButton.UseVisualStyleBackColor = true; getSelectedTreeItemButton.Click += getSelectedTreeItemButton_Click; // + // listBoxImages + // + listBoxImages.FormattingEnabled = true; + listBoxImages.ItemHeight = 15; + listBoxImages.Location = new Point(25, 398); + listBoxImages.Name = "listBoxImages"; + listBoxImages.Size = new Size(280, 124); + listBoxImages.TabIndex = 18; + // + // button1 + // + button1.Location = new Point(25, 528); + button1.Name = "button1"; + button1.Size = new Size(139, 23); + button1.TabIndex = 19; + button1.Text = "Выбрать изображения"; + button1.UseVisualStyleBackColor = true; + button1.Click += button1_Click; + // + // createPdfButton + // + createPdfButton.Location = new Point(170, 528); + createPdfButton.Name = "createPdfButton"; + createPdfButton.Size = new Size(135, 23); + createPdfButton.TabIndex = 20; + createPdfButton.Text = "Создать PDF"; + createPdfButton.UseVisualStyleBackColor = true; + createPdfButton.Click += createPdfButton_Click; + // + // pdfTableButton + // + pdfTableButton.Location = new Point(342, 398); + pdfTableButton.Name = "pdfTableButton"; + pdfTableButton.Size = new Size(152, 23); + pdfTableButton.TabIndex = 21; + pdfTableButton.Text = "Создать таблицу в PDF"; + pdfTableButton.UseVisualStyleBackColor = true; + pdfTableButton.Click += pdfTableButton_Click; + // + // pdfDiagramButton + // + pdfDiagramButton.Location = new Point(342, 427); + pdfDiagramButton.Name = "pdfDiagramButton"; + pdfDiagramButton.Size = new Size(152, 23); + pdfDiagramButton.TabIndex = 22; + pdfDiagramButton.Text = "Создать диаграмму"; + pdfDiagramButton.UseVisualStyleBackColor = true; + pdfDiagramButton.Click += pdfDiagramButton_Click; + // // Form1 // AutoScaleDimensions = new SizeF(7F, 15F); AutoScaleMode = AutoScaleMode.Font; - ClientSize = new Size(700, 407); + ClientSize = new Size(700, 566); + Controls.Add(pdfDiagramButton); + Controls.Add(pdfTableButton); + Controls.Add(createPdfButton); + Controls.Add(button1); + Controls.Add(listBoxImages); Controls.Add(getSelectedTreeItemButton); Controls.Add(departamentComboBox); Controls.Add(addEmployeeButton); @@ -263,5 +324,11 @@ private Button addEmployeeButton; private ComboBox departamentComboBox; private Button getSelectedTreeItemButton; + private WinFormsLibrary1.PdfWithImages pdfWithImages1; + private ListBox listBoxImages; + private Button button1; + private Button createPdfButton; + private Button pdfTableButton; + private Button pdfDiagramButton; } } diff --git a/WinFormsApp1/Form1.cs b/WinFormsApp1/Form1.cs index 23e0bd3..ded07d5 100644 --- a/WinFormsApp1/Form1.cs +++ b/WinFormsApp1/Form1.cs @@ -1,12 +1,24 @@ using System.Security.Cryptography.Xml; using WinFormsLibrary1; -using WinFormsLibrary1.Errors; +using WinFormsLibrary1.Configs.Diagram; +using WinFormsLibrary1.Configs.Image; using WinFormsLibrary1.Models; +using WinFormsLibrary1.Errors; +using WinFormsLibrary1.Configs.Diagram; +using WinFormsLibrary1.Configs.Table; +using PdfSharp.Pdf.Content.Objects; namespace WinFormsApp1 { public partial class Form1 : Form { + private PdfWithImages pdfWithImages = new PdfWithImages(); + private List selectedImages = new List(); + + private PdfWithTable pdfWithTable = new PdfWithTable(); + + private PdfWithDiagram pdfWithDiagram = new PdfWithDiagram(); + public Form1() { InitializeComponent(); @@ -106,5 +118,116 @@ namespace WinFormsApp1 nameTextBox.Text = employee.Name; departamentComboBox.SelectedItem = employee.Department; } + + // PDF WITH IMAGE + private void button1_Click(object sender, EventArgs e) + { + using OpenFileDialog openFileDialog = new OpenFileDialog + { + Multiselect = true, + Filter = "|*.jpg;*.jpeg;*.png;*.bmp" + }; + + if (openFileDialog.ShowDialog() == DialogResult.OK) + { + // + selectedImages.Clear(); + listBoxImages.Items.Clear(); + + // + foreach (string filePath in openFileDialog.FileNames) + { + selectedImages.Add(File.ReadAllBytes(filePath)); + listBoxImages.Items.Add(Path.GetFileName(filePath)); + } + } + } + + private void createPdfButton_Click(object sender, EventArgs e) + { + if (selectedImages.Count == 0) + { + MessageBox.Show(" !", "", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + // PDF- + var config = new PdfWithImageConfig + { + FilePath = "PdfWithImage.pdf", + Header = " ", + Images = selectedImages + }; + + // PDF + pdfWithImages.CreatePdf(config); + + MessageBox.Show("PDF !", "", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + + // PDF WITH TABLE + private void pdfTableButton_Click(object sender, EventArgs e) + { + PdfWithTableConfig config = new PdfWithTableConfig + { + FileName = "PdfWithTable.pdf", + DocumentTitle = " ", + RowHeights = new List { 1, 1, 1 }, + Headers = new Dictionary> + { + { " ", new List {"", ""} }, + { "", new List() } + }, + PropertiesPerRow = new List { "Name", "Surname", "Age" }, + Data = new List + { + new Human("", "", 30), + new Human("", "", 25), + new Human("", "", 35) + } + }; + + try + { + // PDF + pdfWithTable.CreatePdf(config); + MessageBox.Show("PDF- !", "", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + catch (Exception ex) + { + MessageBox.Show($" PDF: {ex.Message}", "", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + + // PDF TO DIAGRAM + private void pdfDiagramButton_Click(object sender, EventArgs e) + { + try + { + pdfWithDiagram.CreateDoc(new PdfWithDiagramConfig + { + FilePath = "PdfWithPieDiagram.pdf", + Header = "", + ChartTitle = " ", + LegendLocation = WinFormsLibrary1.Configs.Diagram.Location.Bottom, + Data = new Dictionary> + { + { + "Product A", new List<(string Name, double Value)> + { + ("1111", 30.0), + ("2", 20.0), + ("3", 50.0) + } + } + } + }); + MessageBox.Show("PDF !", ""); + } + catch (Exception ex) + { + MessageBox.Show($": {ex.Message}"); + } + } } } diff --git a/WinFormsApp1/Form1.resx b/WinFormsApp1/Form1.resx index af32865..ce966af 100644 --- a/WinFormsApp1/Form1.resx +++ b/WinFormsApp1/Form1.resx @@ -117,4 +117,7 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + 17, 17 + \ No newline at end of file diff --git a/WinFormsLibrary1/Configs/Diagram/Location.cs b/WinFormsLibrary1/Configs/Diagram/Location.cs new file mode 100644 index 0000000..6fe3f01 --- /dev/null +++ b/WinFormsLibrary1/Configs/Diagram/Location.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace WinFormsLibrary1.Configs.Diagram +{ + public enum Location + { + Left, + Right, + Top, + Bottom + } +} diff --git a/WinFormsLibrary1/Configs/Diagram/PdfWithDiagramConfig.cs b/WinFormsLibrary1/Configs/Diagram/PdfWithDiagramConfig.cs new file mode 100644 index 0000000..29b7a52 --- /dev/null +++ b/WinFormsLibrary1/Configs/Diagram/PdfWithDiagramConfig.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace WinFormsLibrary1.Configs.Diagram +{ + public class PdfWithDiagramConfig + { + public string FilePath { get; set; } + public string Header { get; set; } + public string ChartTitle { get; set; } + public Location LegendLocation { get; set; } + public Dictionary> Data { get; set; } + + public void CheckFields() + { + if (string.IsNullOrEmpty(FilePath)) + throw new ArgumentNullException(nameof(FilePath), "File path cannot be null or empty."); + if (string.IsNullOrEmpty(Header)) + throw new ArgumentNullException(nameof(Header), "Header cannot be null or empty."); + if (Data == null || !Data.Any()) + throw new ArgumentNullException(nameof(Data), "Data cannot be null or empty."); + } + } + +} diff --git a/WinFormsLibrary1/Configs/Image/PdfWithImageConfig.cs b/WinFormsLibrary1/Configs/Image/PdfWithImageConfig.cs new file mode 100644 index 0000000..735c8fe --- /dev/null +++ b/WinFormsLibrary1/Configs/Image/PdfWithImageConfig.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace WinFormsLibrary1.Configs.Image +{ + public class PdfWithImageConfig + { + public string FilePath { get; set; } + public string Header { get; set; } + public List Images { get; set; } + + public void CheckFields() + { + if (string.IsNullOrWhiteSpace(FilePath) || string.IsNullOrWhiteSpace(Header) || Images == null || Images.Count == 0) + { + throw new ArgumentException("Все поля должны быть заполнены."); + } + } + } +} diff --git a/WinFormsLibrary1/Configs/Table/PdfWithTableConfig.cs b/WinFormsLibrary1/Configs/Table/PdfWithTableConfig.cs new file mode 100644 index 0000000..737d5ba --- /dev/null +++ b/WinFormsLibrary1/Configs/Table/PdfWithTableConfig.cs @@ -0,0 +1,88 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace WinFormsLibrary1.Configs.Table +{ + public class PdfWithTableConfig + { + /// + /// Имя файла для сохранения PDF-документа. + /// + public string FileName { get; set; } + + /// + /// Заголовок документа PDF. + /// + public string DocumentTitle { get; set; } + + /// + /// Список высот строк таблицы в виде массива двойных значений. + /// + public List RowHeights { get; set; } + + /// + /// Заголовки таблицы, где ключ - имя обобщающего столбца, а значение - список заголовков для соответствующего столбца. + /// ВАЖНО: если строка не имеет обобщающего столбца, то заголовком будет ключ (список будет пустой) + /// + /// var Headers = new Dictionary + /// { + /// {"Личные данные", new List("Имя", "Фамилия")}, + /// {"Возраст", new List()}, + /// } + /// + /// ------------------------------ + /// | | Имя | + /// | Личные данные |------------| + /// | | Фамилия | + /// |----------------------------| + /// | Возраст | + /// ------------------------------ + /// + /// + public Dictionary> Headers { get; set; } + + /// + /// Список названий свойств, соответствующих данным, которые будут отображаться в строках таблицы. + /// + public List PropertiesPerRow { get; set; } + + /// + /// Данные для заполнения таблицы, представляющие собой список объектов типа T. + /// + public List Data { get; set; } + + /// + /// Проверяет корректность полей конфигурации. + /// Вызывает исключение, если какое-либо поле не соответствует требованиям. + /// + public void CheckFields() + { + if (string.IsNullOrWhiteSpace(FileName)) + throw new ArgumentException("Имя файла не может быть пустым.", nameof(FileName)); + + if (string.IsNullOrWhiteSpace(DocumentTitle)) + throw new ArgumentException("Название документа не может быть пустым.", nameof(DocumentTitle)); + + if (Headers == null || Headers.Count == 0) + throw new ArgumentException("Заголовки для шапки не могут быть пустыми.", nameof(Headers)); + + if (Data == null || Data.Count == 0) + throw new ArgumentException("Данные для таблицы не могут быть пустыми.", nameof(Data)); + + if (RowHeights == null || RowHeights.Count == 0) + throw new ArgumentException("Высоты строк не могут быть пустыми.", nameof(RowHeights)); + + if (PropertiesPerRow.Any(string.IsNullOrWhiteSpace)) + throw new ArgumentException("Список названий свойств не может содержать пустые строки.", nameof(PropertiesPerRow)); + + if (RowHeights.Count != PropertiesPerRow.Count) + throw new ArgumentException("Количество высот строк должно соответствовать количеству названий свойств.", nameof(RowHeights)); + + if (Data.Count != PropertiesPerRow.Count) + throw new ArgumentException("Количество данных должно соответствовать количеству названий свойств.", nameof(Data)); + } + } +} diff --git a/WinFormsLibrary1/CustomTextBox.Designer.cs b/WinFormsLibrary1/CustomTextBox.Designer.cs index 28a2018..59f9763 100644 --- a/WinFormsLibrary1/CustomTextBox.Designer.cs +++ b/WinFormsLibrary1/CustomTextBox.Designer.cs @@ -35,20 +35,18 @@ // textBox.Dock = DockStyle.Fill; textBox.Location = new Point(0, 0); - textBox.Margin = new Padding(3, 2, 3, 2); textBox.Name = "textBox"; - textBox.Size = new Size(81, 23); + textBox.Size = new Size(93, 27); textBox.TabIndex = 0; textBox.TextChanged += textBox1_TextChanged; // // CustomTextBox // - AutoScaleDimensions = new SizeF(7F, 15F); + AutoScaleDimensions = new SizeF(8F, 20F); AutoScaleMode = AutoScaleMode.Font; Controls.Add(textBox); - Margin = new Padding(3, 2, 3, 2); Name = "CustomTextBox"; - Size = new Size(81, 16); + Size = new Size(93, 21); ResumeLayout(false); PerformLayout(); } diff --git a/WinFormsLibrary1/Models/Human.cs b/WinFormsLibrary1/Models/Human.cs new file mode 100644 index 0000000..821f554 --- /dev/null +++ b/WinFormsLibrary1/Models/Human.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace WinFormsLibrary1.Models +{ + public class Human + { + public string Name { get; set; } + public string Surname { get; set; } + public int Age { get; set; } + public Human() { } + public Human(string name, string surname, int age) + { + Name = name; + Surname = surname; + Age = age; + } + } +} diff --git a/WinFormsLibrary1/PdfWithDiagram.Designer.cs b/WinFormsLibrary1/PdfWithDiagram.Designer.cs new file mode 100644 index 0000000..726d2d0 --- /dev/null +++ b/WinFormsLibrary1/PdfWithDiagram.Designer.cs @@ -0,0 +1,36 @@ +namespace WinFormsLibrary1 +{ + partial class PdfWithDiagram + { + /// + /// Обязательная переменная конструктора. + /// + 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/WinFormsLibrary1/PdfWithDiagram.cs b/WinFormsLibrary1/PdfWithDiagram.cs new file mode 100644 index 0000000..7568bfd --- /dev/null +++ b/WinFormsLibrary1/PdfWithDiagram.cs @@ -0,0 +1,117 @@ +using MigraDoc.DocumentObjectModel.Shapes; +using MigraDoc.DocumentObjectModel; +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; +using MigraDoc.DocumentObjectModel.Shapes.Charts; +using WinFormsLibrary1.Configs.Diagram; + +namespace WinFormsLibrary1 +{ + public partial class PdfWithDiagram : Component + { + public PdfWithDiagram() + { + InitializeComponent(); + } + + public PdfWithDiagram(IContainer container) + { + container.Add(this); + + InitializeComponent(); + } + + private Document _document; + private Chart _chart; + + private Document Document + { + get + { + if (_document == null) + { + _document = new Document(); + } + return _document; + } + } + + public void CreateHeader(string header) + { + var section = Document.AddSection(); + var paragraph = section.AddParagraph(header); + paragraph.Format.Font.Color = Colors.Black; + paragraph.Format.Font.Bold = true; + } + + private void ConfigChart(PdfWithDiagramConfig config) + { + ((Shape)_chart).Width = Unit.FromCentimeter(16.0); + ((Shape)_chart).Height = Unit.FromCentimeter(12.0); + _chart.TopArea.AddParagraph(config.ChartTitle); + _chart.XAxis.MajorTickMark = (TickMarkType)2; + _chart.YAxis.MajorTickMark = (TickMarkType)2; + _chart.YAxis.HasMajorGridlines = true; + _chart.PlotArea.LineFormat.Width = new Unit(1); + _chart.PlotArea.LineFormat.Visible = true; + switch (config.LegendLocation) + { + case Location.Left: + _chart.LeftArea.AddLegend(); + break; + case Location.Right: + _chart.RightArea.AddLegend(); + break; + case Location.Top: + _chart.TopArea.AddLegend(); + break; + case Location.Bottom: + _chart.BottomArea.AddLegend(); + break; + } + } + + public void CreatePieChart(PdfWithDiagramConfig config) + { + _chart = new Chart(ChartType.Pie2D); + foreach (var kvp in config.Data) + { + Series series = _chart.SeriesCollection.AddSeries(); + series.Name = kvp.Key; + series.Add(kvp.Value.Select(x => x.Value).ToArray()); // Используем Value для данных + } + _chart.XValues.AddXSeries().Add(config.Data.First().Value.Select(x => x.Name).ToArray()); // Используем Date для оси X + ConfigChart(config); + } + + public void SaveDoc(string filepath) + { + if (string.IsNullOrEmpty(filepath)) + throw new ArgumentNullException(nameof(filepath), "File path cannot be null or empty."); + if (_document == null) + throw new ArgumentNullException(nameof(_document), "Document is not created."); + if (_chart != null) + _document.LastSection.Add(_chart); + PdfDocumentRenderer documentRenderer = new PdfDocumentRenderer(true) + { + Document = _document + }; + documentRenderer.RenderDocument(); + documentRenderer.PdfDocument.Save(filepath); + } + + public void CreateDoc(PdfWithDiagramConfig config) + { + config.CheckFields(); + CreateHeader(config.Header); + CreatePieChart(config); + SaveDoc(config.FilePath); + } + } +} diff --git a/WinFormsLibrary1/PdfWithImages.Designer.cs b/WinFormsLibrary1/PdfWithImages.Designer.cs new file mode 100644 index 0000000..ff21e7c --- /dev/null +++ b/WinFormsLibrary1/PdfWithImages.Designer.cs @@ -0,0 +1,36 @@ +namespace WinFormsLibrary1 +{ + partial class PdfWithImages + { + /// + /// Обязательная переменная конструктора. + /// + 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/WinFormsLibrary1/PdfWithImages.cs b/WinFormsLibrary1/PdfWithImages.cs new file mode 100644 index 0000000..3dcad9a --- /dev/null +++ b/WinFormsLibrary1/PdfWithImages.cs @@ -0,0 +1,177 @@ +using MigraDoc.DocumentObjectModel; +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; +using WinFormsLibrary1.Configs.Image; + +namespace WinFormsLibrary1 +{ + public partial class PdfWithImages : Component + { + private Document _document = null; + + private Section _section = null; + + private List _images = null; + + private Document Document + { + get + { + if (_document == null) + { + _document = new Document(); + } + + return _document; + } + } + + private Section Section + { + get + { + if (_section == null) + { + _section = Document.AddSection(); + } + + return _section; + } + } + + private List Images + { + get + { + if (_images == null) + { + _images = new List(); + } + + return _images; + } + } + public PdfWithImages() + { + Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); + InitializeComponent(); + } + + public PdfWithImages(IContainer container) + { + container.Add(this); + Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); + InitializeComponent(); + } + public void CreatePdf(PdfWithImageConfig config) + { + config.CheckFields(); + CreateHeader(config.Header); + foreach (var image in config.Images) + { + CreateImage(image); + } + + SavePdf(config.FilePath); + } + + public void CreateHeader(string header) + { + var paragraph = Section.AddParagraph(header); + paragraph.Format.Font.Name = "Arial"; + paragraph.Format.Font.Bold = true; + paragraph.Format.Font.Size = 20; + paragraph.Format.SpaceAfter = 10; + } + + public void SavePdf(string filepath) + { + if (string.IsNullOrWhiteSpace(filepath)) + { + throw new ArgumentNullException("Имя файла не задано"); + } + + if (_document == null || _section == null) + { + throw new ArgumentNullException("Документ не сформирован, сохранять нечего"); + } + + var pdfRenderer = new PdfDocumentRenderer(true) + { + Document = _document, + }; + pdfRenderer.RenderDocument(); + pdfRenderer.Save(filepath); + } + + public void CreateImage(byte[] image) + { + if (image == null || image.Length == 0) + { + throw new ArgumentNullException("Картинка не загружена"); + } + + Images.Add(image); + + var imageFileName = Path.GetTempFileName(); + File.WriteAllBytes(imageFileName, image); + + var img = Section.AddImage(imageFileName); + img.Width = Unit.FromCentimeter(15); // Можно настроить ширину изображения + img.LockAspectRatio = true; + Section.AddParagraph(); + + + + + /*if (image == null || image.Length == 0) + { + throw new ArgumentNullException("Картинка не загружена"); + } + + Images.Add(image); + + // Создаём временный файл + var imageFileName = Path.GetTempFileName(); + File.WriteAllBytes(imageFileName, image); + + // Открываем изображение и проверяем его ориентацию + using (var img = System.Drawing.Image.FromFile(imageFileName)) + { + // Проверяем ориентацию и вращаем, если необходимо + if (Array.IndexOf(img.PropertyIdList, 274) > -1) + { + var orientation = (int)img.GetPropertyItem(274).Value[0]; + switch (orientation) + { + case 3: // Переворот на 180 градусов + img.RotateFlip(RotateFlipType.Rotate180FlipNone); + break; + case 6: // Поворот на 90 градусов вправо + img.RotateFlip(RotateFlipType.Rotate90FlipNone); + break; + case 8: // Поворот на 90 градусов влево + img.RotateFlip(RotateFlipType.Rotate270FlipNone); + break; + } + } + // Сохраняем отредактированное изображение + img.Save(imageFileName); + } + + // Вставляем изображение в PDF + var pdfImage = Section.AddImage(imageFileName); + pdfImage.Width = Unit.FromCentimeter(15); // Можно настроить ширину изображения + pdfImage.LockAspectRatio = true; + + // Добавляем пустую строку после изображения + Section.AddParagraph();*/ + } + } +} diff --git a/WinFormsLibrary1/PdfWithTable.Designer.cs b/WinFormsLibrary1/PdfWithTable.Designer.cs new file mode 100644 index 0000000..fdf30a3 --- /dev/null +++ b/WinFormsLibrary1/PdfWithTable.Designer.cs @@ -0,0 +1,36 @@ +namespace WinFormsLibrary1 +{ + partial class PdfWithTable + { + /// + /// Обязательная переменная конструктора. + /// + 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/WinFormsLibrary1/PdfWithTable.cs b/WinFormsLibrary1/PdfWithTable.cs new file mode 100644 index 0000000..ce8e4dc --- /dev/null +++ b/WinFormsLibrary1/PdfWithTable.cs @@ -0,0 +1,110 @@ +using MigraDoc.DocumentObjectModel; +using MigraDoc.DocumentObjectModel.IO; +using MigraDoc.DocumentObjectModel.Tables; +using MigraDoc.Rendering; +using PdfSharp.Pdf; +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Reflection; +using System.Text; +using WinFormsLibrary1.Configs.Table; + +namespace WinFormsLibrary1 +{ + public partial class PdfWithTable : Component + { + public void CreatePdf(PdfWithTableConfig config) + { + config.CheckFields(); + + // Создание документа + var document = new Document(); + var section = document.AddSection(); + + // Установка заголовка + var titleParagraph = section.AddParagraph(config.DocumentTitle); + titleParagraph.Format.Alignment = ParagraphAlignment.Center; + titleParagraph.Format.Font.Size = 16; + titleParagraph.Format.Font.Bold = true; + titleParagraph.Format.SpaceAfter = 20; + + // Создание таблицы + var table = section.AddTable(); + table.Borders.Width = 0.75; + + // Создание столбцов + for (int i = 0; i < config.Data.Count + 2; i++) + { + var column = table.AddColumn(Unit.FromCentimeter(3)); // Ширину можно настроить + column.Format.Alignment = ParagraphAlignment.Center; + } + + // Создание заголовков + for (int rowIndex = 0; rowIndex < config.PropertiesPerRow.Count; rowIndex++) + { + var row = table.AddRow(); + row.Height = Unit.FromCentimeter(config.RowHeights[rowIndex]); // Высота строки + + foreach (Cell cell in row.Cells) + { + cell.VerticalAlignment = VerticalAlignment.Center; + cell.Format.Alignment = ParagraphAlignment.Center; + } + } + + int rowNum = 0; + foreach (var kvp in config.Headers) + { + string key = kvp.Key; + List values = kvp.Value; + + if (values.Count == 0) + { + table.Rows[rowNum].Cells[0].AddParagraph(key); + table.Rows[rowNum].Cells[0].MergeRight = 1; + rowNum++; + } + + else + { + table.Rows[rowNum].Cells[0].AddParagraph(key); + table.Rows[rowNum].Cells[0].MergeDown = values.Count - 1; + + foreach (var value in values) + { + table.Rows[rowNum].Cells[1].AddParagraph(value); + rowNum++; + } + } + } + + + for (int colIndex = 0; colIndex < config.Data.Count; colIndex++) + { + for (int rowIndex = 0; rowIndex < config.PropertiesPerRow.Count; rowIndex++) + { + Type type = typeof(T); + PropertyInfo property = type.GetProperty(config.PropertiesPerRow[rowIndex]); + + if (property == null) + { + throw new ArgumentException($"Property with name {config.PropertiesPerRow[rowIndex]} doesn't exist in class {type.Name}"); + } + + table.Rows[rowIndex].Cells[colIndex + 2].AddParagraph(property.GetValue(config.Data[colIndex]).ToString()); + } + } + + + // Рендеринг документа в PDF + var pdfRenderer = new PdfDocumentRenderer(true) + { + Document = document + }; + pdfRenderer.RenderDocument(); + pdfRenderer.PdfDocument.Save(config.FileName); + } + } +} \ No newline at end of file diff --git a/WinFormsLibrary1/WinFormsLibrary1.csproj b/WinFormsLibrary1/WinFormsLibrary1.csproj index 060aa1c..257b5ba 100644 --- a/WinFormsLibrary1/WinFormsLibrary1.csproj +++ b/WinFormsLibrary1/WinFormsLibrary1.csproj @@ -7,4 +7,8 @@ enable + + + +