В процессе

This commit is contained in:
Владимир Данилов 2024-10-16 14:03:22 +04:00
parent 9b30023ed6
commit 4d673aa1dc
20 changed files with 378 additions and 0 deletions

View File

@ -7,4 +7,8 @@
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="PdfSharp.MigraDoc.Standard" Version="1.51.15" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,36 @@
namespace Components.NonVisual
{
partial class HeaderedTablePDF
{
/// <summary>
/// Обязательная переменная конструктора.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Освободить все используемые ресурсы.
/// </summary>
/// <param name="disposing">истинно, если управляемый ресурс должен быть удален; иначе ложно.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Код, автоматически созданный конструктором компонентов
/// <summary>
/// Требуемый метод для поддержки конструктора — не изменяйте
/// содержимое этого метода с помощью редактора кода.
/// </summary>
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
}
#endregion
}
}

View File

@ -0,0 +1,96 @@
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;
using Components.SaveToPdfHelpers;
namespace Components.NonVisual
{
public partial class HeaderedTablePDF : Component
{
public HeaderedTablePDF()
{
InitializeComponent();
System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);
}
public HeaderedTablePDF(IContainer container)
{
container.Add(this);
InitializeComponent();
}
public void GeneratePDFWithHead<T>(PDFTableSettings<T> settings)
{
if (settings == null ||
string.IsNullOrEmpty(settings.FilePath) ||
string.IsNullOrEmpty(settings.DocumentTitle) ||
settings.Columns == null || settings.Columns.Count == 0 ||
settings.DataList == null)
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;
// столбцы
foreach (var (_, width, _, _) in settings.Columns)
{
Column column = table.AddColumn(Unit.FromCentimeter(width));
column.Format.Alignment = ParagraphAlignment.Center;
}
// заголовки
Row headerRow = table.AddRow();
headerRow.Height = Unit.FromCentimeter(settings.HeaderRowHeight);
for (int columnIndex = 0; columnIndex < settings.Columns.Count; columnIndex++)
{
var (headerTitle, _, _, _) = settings.Columns[columnIndex];
headerRow.Cells[columnIndex].AddParagraph(headerTitle);
headerRow.Cells[columnIndex].Format.Font.Bold = true;
headerRow.Cells[columnIndex].Format.Alignment = ParagraphAlignment.Center;
}
// данные
foreach (var dataItem in settings.DataList)
{
Row row = table.AddRow();
row.Height = Unit.FromCentimeter(settings.DataRowHeight);
for (int columnIndex = 0; columnIndex < settings.Columns.Count; columnIndex++)
{
var (_, _, propertyName, _) = settings.Columns[columnIndex];
PropertyInfo propertyInfo = typeof(T).GetProperty(propertyName);
if (propertyInfo == null)
throw new ArgumentException($"Свойство {propertyName} не найдено в классе {typeof(T).Name}.");
object value = propertyInfo.GetValue(dataItem);
if (columnIndex == 0)
{
row.Cells[columnIndex].Format.Font.Bold = true;
}
row.Cells[columnIndex].AddParagraph(value != null ? value.ToString() : "");
}
}
section.Add(table);
PdfDocumentRenderer renderer = new PdfDocumentRenderer(true) { Document = document };
renderer.RenderDocument();
renderer.Save(settings.FilePath);
}
}
}

View File

@ -0,0 +1,36 @@
namespace Components.NonVisual
{
partial class HistogramPDF
{
/// <summary>
/// Обязательная переменная конструктора.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Освободить все используемые ресурсы.
/// </summary>
/// <param name="disposing">истинно, если управляемый ресурс должен быть удален; иначе ложно.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Код, автоматически созданный конструктором компонентов
/// <summary>
/// Требуемый метод для поддержки конструктора — не изменяйте
/// содержимое этого метода с помощью редактора кода.
/// </summary>
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
}
#endregion
}
}

View File

@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Components.NonVisual
{
public partial class HistogramPDF : Component
{
public HistogramPDF()
{
InitializeComponent();
}
public HistogramPDF(IContainer container)
{
container.Add(this);
InitializeComponent();
}
}
}

View File

@ -0,0 +1,36 @@
namespace Components.NonVisual
{
partial class TablePDF
{
/// <summary>
/// Обязательная переменная конструктора.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Освободить все используемые ресурсы.
/// </summary>
/// <param name="disposing">истинно, если управляемый ресурс должен быть удален; иначе ложно.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Код, автоматически созданный конструктором компонентов
/// <summary>
/// Требуемый метод для поддержки конструктора — не изменяйте
/// содержимое этого метода с помощью редактора кода.
/// </summary>
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
}
#endregion
}
}

View File

@ -0,0 +1,75 @@
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.Text;
using System.Threading.Tasks;
using Document = MigraDoc.DocumentObjectModel.Document;
using Components.SaveToPdfHelpers;
namespace Components.NonVisual
{
public partial class TablePDF : Component
{
public TablePDF()
{
InitializeComponent();
System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);
}
public TablePDF(IContainer container)
{
container.Add(this);
InitializeComponent();
}
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(pdfData.DocumentTitle, TextFormat.Bold);
title.Format.Alignment = ParagraphAlignment.Center;
section.AddParagraph();
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));
}
table.Borders.Width = 0.75;
table.Borders.Color = Colors.Black;
for (int i = 0; i < tableData.GetLength(0); i++)
{
Row row = table.AddRow();
for (int j = 0; j < tableData.GetLength(1); j++)
{
row.Cells[j].AddParagraph(tableData[i, j]);
}
}
section.AddParagraph();
}
PdfDocumentRenderer pdfRenderer = new PdfDocumentRenderer(true);
pdfRenderer.Document = document;
pdfRenderer.RenderDocument();
pdfRenderer.PdfDocument.Save(pdfData.FileName);
}
}
}

View File

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Components.SaveToPdfHelpers
{
public class ChartData
{
public string SeriesName { get; set; } = string.Empty;
public Dictionary<string, double>? Data { get; set; } // Ключ — категория, значение — значение для гистограммы
}
}

View File

@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Components.SaveToPdfHelpers
{
public enum LegendPositions
{
Top,
Bottom,
Left,
Right
}
}

View File

@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Components.SaveToPdfHelpers
{
public class PDFTableSettings<T>
{
public string FilePath { get; set; } = string.Empty;
public string DocumentTitle { get; set; } = string.Empty;
public List<(string HeaderTitle, float Width, string PropertyName, int ColumnIndex)> Columns { get; set; }
public float HeaderRowHeight { get; set; }
public float DataRowHeight { get; set; }
public List<T>? DataList { get; set; }
}
}

View File

@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Components.SaveToPdfHelpers
{
public class PdfDocumentData
{
public string FileName { get; set; }
public string DocumentTitle { get; set; }
public List<string[,]> Tables { get; set; }
public PdfDocumentData(string fileName, string documentTitle, List<string[,]> tables)
{
FileName = fileName ?? throw new ArgumentNullException(nameof(fileName));
DocumentTitle = documentTitle ?? throw new ArgumentNullException(nameof(documentTitle));
Tables = tables ?? throw new ArgumentNullException(nameof(tables));
}
}
}