170 lines
5.8 KiB
C#
170 lines
5.8 KiB
C#
using System.Globalization;
|
|
using System.Linq;
|
|
using QuestPDF.Drawing;
|
|
using QuestPDF.Fluent;
|
|
using QuestPDF.Helpers;
|
|
using QuestPDF.Infrastructure;
|
|
|
|
namespace BenchtopPDF
|
|
{
|
|
public class SheetDocument : IDocument
|
|
{
|
|
public static Image LogoImage { get; } = Image.FromFile("BenchTopLogo.jpg");
|
|
|
|
public Sheet Model { get; }
|
|
|
|
public SheetDocument(Sheet model)
|
|
{
|
|
Model = model;
|
|
}
|
|
|
|
public DocumentMetadata GetMetadata() => DocumentMetadata.Default;
|
|
public DocumentSettings GetSettings()
|
|
{
|
|
return new DocumentSettings();
|
|
}
|
|
|
|
public void Compose(IDocumentContainer container)
|
|
{
|
|
container
|
|
.Page(page =>
|
|
{
|
|
page.Margin(50);
|
|
|
|
page.Header().Element(ComposeHeader);
|
|
page.Content().Element(ComposeContent);
|
|
|
|
page.Footer().AlignCenter().Text(text =>
|
|
{
|
|
text.CurrentPageNumber();
|
|
text.Span(" / ");
|
|
text.TotalPages();
|
|
});
|
|
});
|
|
}
|
|
|
|
void ComposeHeader(IContainer container)
|
|
{
|
|
container.Row(row =>
|
|
{
|
|
row.RelativeItem().Column(column =>
|
|
{
|
|
column
|
|
.Item().Text("Certificate Of Calibration")
|
|
.FontSize(20).SemiBold().FontColor(Colors.Blue.Medium);
|
|
|
|
column.Item().Text(text =>
|
|
{
|
|
text.Span("Issue date: ").SemiBold();
|
|
text.Span($"{Model.IssueDate:d}");
|
|
});
|
|
});
|
|
|
|
row.ConstantItem(175).Image(LogoImage);
|
|
});
|
|
}
|
|
|
|
void ComposeContent(IContainer container)
|
|
{
|
|
container.PaddingVertical(40).Column(column =>
|
|
{
|
|
column.Spacing(20);
|
|
|
|
column.Item().Row(row =>
|
|
{
|
|
row.RelativeItem().Component(new AddressComponent("From", Model.SellerAddress));
|
|
row.ConstantItem(50);
|
|
row.RelativeItem().Component(new AddressComponent("For", Model.CustomerAddress));
|
|
});
|
|
|
|
column.Item().Element(ComposeTable);
|
|
|
|
var totalPrice = Model.Items.Sum(x => x.Price * x.Quantity);
|
|
column.Item().PaddingRight(5).AlignRight().Text($"Grand total: {totalPrice:C}").SemiBold();
|
|
|
|
if (!string.IsNullOrWhiteSpace(Model.Comments))
|
|
column.Item().PaddingTop(25).Element(ComposeComments);
|
|
});
|
|
}
|
|
|
|
void ComposeTable(IContainer container)
|
|
{
|
|
var headerStyle = TextStyle.Default.SemiBold();
|
|
|
|
container.Table(table =>
|
|
{
|
|
table.ColumnsDefinition(columns =>
|
|
{
|
|
columns.ConstantColumn(25);
|
|
columns.RelativeColumn(3);
|
|
columns.RelativeColumn();
|
|
columns.RelativeColumn();
|
|
columns.RelativeColumn();
|
|
});
|
|
|
|
table.Header(header =>
|
|
{
|
|
header.Cell().Text("#");
|
|
header.Cell().Text("Product").Style(headerStyle);
|
|
header.Cell().AlignRight().Text("Unit price").Style(headerStyle);
|
|
header.Cell().AlignRight().Text("Quantity").Style(headerStyle);
|
|
header.Cell().AlignRight().Text("Total").Style(headerStyle);
|
|
|
|
header.Cell().ColumnSpan(5).PaddingTop(5).BorderBottom(1).BorderColor(Colors.Black);
|
|
});
|
|
|
|
foreach (var item in Model.Items)
|
|
{
|
|
var index = Model.Items.IndexOf(item) + 1;
|
|
|
|
table.Cell().Element(CellStyle).Text($"{index}");
|
|
table.Cell().Element(CellStyle).Text(item.Name);
|
|
table.Cell().Element(CellStyle).AlignRight().Text($"{item.Price:C}");
|
|
table.Cell().Element(CellStyle).AlignRight().Text($"{item.Quantity}");
|
|
table.Cell().Element(CellStyle).AlignRight().Text($"{item.Price * item.Quantity:C}");
|
|
|
|
static IContainer CellStyle(IContainer container) => container.BorderBottom(1).BorderColor(Colors.Grey.Lighten2).PaddingVertical(5);
|
|
}
|
|
});
|
|
}
|
|
|
|
void ComposeComments(IContainer container)
|
|
{
|
|
container.ShowEntire().Background(Colors.Grey.Lighten3).Padding(10).Column(column =>
|
|
{
|
|
column.Spacing(5);
|
|
column.Item().Text("Comments").FontSize(14).SemiBold();
|
|
column.Item().Text(Model.Comments);
|
|
});
|
|
}
|
|
}
|
|
|
|
public class AddressComponent : IComponent
|
|
{
|
|
private string Title { get; }
|
|
private Address Address { get; }
|
|
|
|
public AddressComponent(string title, Address address)
|
|
{
|
|
Title = title;
|
|
Address = address;
|
|
}
|
|
|
|
public void Compose(IContainer container)
|
|
{
|
|
container.ShowEntire().Column(column =>
|
|
{
|
|
column.Spacing(2);
|
|
|
|
column.Item().Text(Title).SemiBold();
|
|
column.Item().PaddingBottom(5).LineHorizontal(1);
|
|
|
|
column.Item().Text(Address.CompanyName);
|
|
column.Item().Text(Address.Street);
|
|
column.Item().Text($"{Address.City}, {Address.State}");
|
|
column.Item().Text(Address.Email);
|
|
column.Item().Text(Address.Phone);
|
|
});
|
|
}
|
|
}
|
|
} |