Compare commits

..

1 Commits

Author SHA1 Message Date
Marcin Ziąbek 9a6b11ab85 Updated examples and readme 2022-01-30 22:52:56 +01:00
10 changed files with 136 additions and 172 deletions
-61
View File
@@ -1,61 +0,0 @@
using System.Linq;
using NUnit.Framework;
using QuestPDF.Examples.Engine;
using QuestPDF.Fluent;
using QuestPDF.Helpers;
using QuestPDF.Infrastructure;
namespace QuestPDF.Examples
{
internal class MyComponent : IComponent
{
public ISlot Header { get; set; }
public ISlot<string> Content { get; set; }
public void Compose(IContainer container)
{
container
.Column(column =>
{
column.Item().Slot(Header);
foreach (var i in Enumerable.Range(1, 10))
column.Item().Slot(Content, i.ToString());
});
}
}
public class ComponentExamples
{
[Test]
public void ComplexLayout()
{
RenderingTest
.Create()
.PageSize(PageSizes.A4)
.ProducePdf()
.ShowResults()
.Render(content =>
{
content
.Padding(10)
.Border(1)
.BorderColor(Colors.Grey.Medium)
.Component<MyComponent>(component =>
{
component
.Slot(x => x.Header)
.Text("This is my text");
component.Slot(x => x.Content, (input, container) =>
{
container
.Background(Placeholders.BackgroundColor())
.Padding(5)
.Text(input);
});
});
});
}
}
}
+22 -15
View File
@@ -3,6 +3,7 @@ using NUnit.Framework;
using QuestPDF.Examples.Engine;
using QuestPDF.Fluent;
using QuestPDF.Helpers;
using QuestPDF.Infrastructure;
namespace QuestPDF.Examples
{
@@ -14,16 +15,20 @@ namespace QuestPDF.Examples
RenderingTest
.Create()
.PageSize(PageSizes.A5)
.ProducePdf()
.ProduceImages()
.ShowResults()
.Render(container =>
{
container.Padding(25).Column(column =>
{
column.Item().Text("Above text");
column.Item().PaddingVertical(10).LineHorizontal(1).LineColor(Colors.Blue.Accent1);
column.Item().Text("Below text");
});
container
.Padding(15)
.MinimalBox()
.DefaultTextStyle(TextStyle.Default.Size(16))
.Column(column =>
{
column.Item().Text("Above text");
column.Item().PaddingVertical(5).LineHorizontal(1).LineColor(Colors.Grey.Medium);
column.Item().Text("Below text");
});
});
}
@@ -33,17 +38,19 @@ namespace QuestPDF.Examples
RenderingTest
.Create()
.PageSize(PageSizes.A5)
.ProducePdf()
.ProduceImages()
.ShowResults()
.Render(container =>
{
container.Padding(25).Inlined(inlined =>
{
inlined.Spacing(5);
inlined.Item().Text("Above text");
inlined.Item().LineVertical(1).LineColor(Colors.Blue.Accent1);
inlined.Item().Text("Below text");
});
container
.Padding(15)
.DefaultTextStyle(TextStyle.Default.Size(16))
.Row(row =>
{
row.AutoItem().Text("Left text");
row.AutoItem().PaddingHorizontal(10).LineVertical(1).LineColor(Colors.Grey.Medium);
row.AutoItem().Text("Right text");
});
});
}
}
+4 -4
View File
@@ -15,7 +15,7 @@ namespace QuestPDF.Examples
RenderingTest
.Create()
.PageSize(PageSizes.A4)
.ProducePdf()
.ProduceImages()
.ShowResults()
.Render(container =>
{
@@ -23,15 +23,15 @@ namespace QuestPDF.Examples
{
var text = Placeholders.Paragraph();
foreach (var i in Enumerable.Range(0, 16))
foreach (var i in Enumerable.Range(2, 5))
{
column
.Item()
.MinimalBox()
.Border(1)
.Padding(5)
.Width(50 + i * 25)
.Height(25 + i * 5)
.Width(i * 40)
.Height(i * 20)
.ScaleToFit()
.Text(text);
}
+48
View File
@@ -0,0 +1,48 @@
using NUnit.Framework;
using QuestPDF.Examples.Engine;
using QuestPDF.Fluent;
using QuestPDF.Helpers;
using QuestPDF.Infrastructure;
namespace QuestPDF.Examples
{
public class StopPaging
{
[Test]
public void Example()
{
RenderingTest
.Create()
.PageSize(300, 250)
.ProduceImages()
.ShowResults()
.Render(container =>
{
container
.Padding(25)
.DefaultTextStyle(TextStyle.Default.Size(14))
.Decoration(decoration =>
{
decoration
.Before()
.Text(text =>
{
text.DefaultTextStyle(TextStyle.Default.SemiBold().Color(Colors.Blue.Medium));
text.Span("Page ");
text.CurrentPageNumber();
});
decoration
.Content()
.Column(column =>
{
column.Spacing(25);
column.Item().StopPaging().Text(Placeholders.LoremIpsum());
column.Item().ExtendHorizontal().Height(75).Background(Colors.Grey.Lighten2);
});
});
});
}
}
}
+23 -41
View File
@@ -1,53 +1,41 @@
using System;
using System.Linq.Expressions;
using QuestPDF.Drawing.Exceptions;
using QuestPDF.Elements;
using QuestPDF.Helpers;
using QuestPDF.Infrastructure;
namespace QuestPDF.Fluent
{
internal class ComponentDescriptor<TComponent> where TComponent : IComponent
class ComponentDescriptor<T> where T : IComponent
{
public TComponent Component { get; }
public T Component { get; }
public ComponentDescriptor(TComponent component)
public ComponentDescriptor(T component)
{
Component = component;
}
public IContainer Slot(Expression<Func<TComponent, ISlot>> selector)
public IContainer Slot(Expression<Func<T, ISlot>> selector)
{
AssureThatTheSlotIsNotConfiguredYet(selector);
var slot = new Slot();
Component.SetPropertyValue(selector, slot);
return slot;
}
public void Slot<TArgument>(Expression<Func<TComponent, ISlot<TArgument>>> selector, Action<TArgument, IContainer> handler)
{
AssureThatTheSlotIsNotConfiguredYet(selector);
var slot = new Slot<TArgument>
try
{
GetContent = argument =>
{
var container = new Container();
handler(argument, container);
return container;
}
};
Component.SetPropertyValue(selector, slot);
}
var existingValue = Component.GetPropertyValue(selector);
private void AssureThatTheSlotIsNotConfiguredYet<TSlot>(Expression<Func<TComponent, TSlot>> selector) where TSlot : class
{
var existingValue = Component.GetPropertyValue(selector);
if (existingValue != null)
throw new DocumentComposeException($"The slot {selector.GetPropertyName()} of the component {(typeof(T).Name)} was already used.");
if (existingValue != null)
throw new DocumentComposeException($"The slot {selector.GetPropertyName()} of the component {(typeof(TComponent).Name)} was already used.");
var slot = new Slot();
Component.SetPropertyValue(selector, slot);
return slot;
}
catch (DocumentComposeException)
{
throw;
}
catch
{
throw new DocumentComposeException("Every slot in a component should be a public property with getter and setter.");
}
}
}
@@ -63,7 +51,7 @@ namespace QuestPDF.Fluent
element.Component(new T(), null);
}
internal static void Component<T>(this IContainer element, T component, Action<ComponentDescriptor<T>>? handler = null) where T : IComponent
static void Component<T>(this IContainer element, T component, Action<ComponentDescriptor<T>>? handler = null) where T : IComponent
{
var descriptor = new ComponentDescriptor<T>(component);
handler?.Invoke(descriptor);
@@ -74,21 +62,15 @@ namespace QuestPDF.Fluent
component.Compose(element.Container());
}
internal static void Component<T>(this IContainer element, Action<ComponentDescriptor<T>>? handler = null) where T : IComponent, new()
static void Component<T>(this IContainer element, Action<ComponentDescriptor<T>>? handler = null) where T : IComponent, new()
{
element.Component(new T(), handler);
}
internal static void Slot(this IContainer element, ISlot slot)
static void Slot(this IContainer element, ISlot slot)
{
var child = (slot as Slot)?.Child;
element.Element(child);
}
internal static void Slot<TArgument>(this IContainer element, ISlot<TArgument> slot, TArgument argument)
{
var child = (slot as Slot<TArgument>)?.GetContent(argument) ?? Empty.Instance;
element.Element(child);
}
}
}
+1 -1
View File
@@ -7,7 +7,7 @@ namespace QuestPDF.Helpers
{
public static class Placeholders
{
public static readonly Random Random = new Random(3); // 3
public static readonly Random Random = new();
#region Word Cache
+1 -12
View File
@@ -1,4 +1,3 @@
using System;
using QuestPDF.Elements;
namespace QuestPDF.Infrastructure
@@ -12,17 +11,7 @@ namespace QuestPDF.Infrastructure
{
}
interface ISlot<T>
{
}
class Slot<T> : ISlot<T>
{
public Func<T, IElement> GetContent { get; set; }
}
public interface IComponent
{
void Compose(IContainer container);
+1 -1
View File
@@ -4,7 +4,7 @@
<Authors>MarcinZiabek</Authors>
<Company>CodeFlint</Company>
<PackageId>QuestPDF</PackageId>
<Version>2022.2.0-beta2</Version>
<Version>2022.2.0</Version>
<PackageDescription>QuestPDF is an open-source, modern and battle-tested library that can help you with generating PDF documents by offering friendly, discoverable and predictable C# fluent API.</PackageDescription>
<PackageReleaseNotes>$([System.IO.File]::ReadAllText("$(MSBuildProjectDirectory)/Resources/ReleaseNotes.txt"))</PackageReleaseNotes>
<LangVersion>9</LangVersion>
+5 -5
View File
@@ -1,8 +1,8 @@
- Added a `ScaleToFit` element - scales it child down so it does fit in the provided space,
- Added a `ScaleToFit` element - scales its child down so it fits in the provided space,
- Added a `StopPaging` element - when its child requires more than one page to fully render, only the first page is shown,
- Added a 'LineVertical' and a 'LineHorizontal' elements - those will simplify your code a lot, no need to use the `Border` element anymore!
- Renaming: the `Stack` element has been renamed to the `Column` element,
- Renaming: children of the `Row` elements are not called `items` instead of `columns`, e.g. `ConstantItem`, `RelativeItem`, `AutoItem`,
- Added a 'LineVertical' and a 'LineHorizontal' elements - those will simplify your code a lot, there is no need to use the `Border` element anymore!
- Renaming: the `Stack` element was renamed to the `Column` element,
- Renaming: children of the `Row` element are now called `items` instead of `columns`, e.g. `RelativeItem` instead of `RelativeColumn`,
- Added support of the `AutoItem` to the `Row` element - those items take as little width as possible,
- Improved default Fluent configuration behavior for elements: Scale, Padding, Translate,
- Improved integration support with the HttpContext.Response.Body. This improvement was introduced by schulz3000, thank you!
- Improved integration support with the HttpContext.Response.Body. This improvement was introduced by schulz3000, thank you!
+31 -32
View File
@@ -149,41 +149,40 @@ void ComposeTable(IContainer container)
{
var headerStyle = TextStyle.Default.SemiBold();
container.Decoration(decoration =>
container.Table(table =>
{
// header
decoration.Header().BorderBottom(1).Padding(5).Row(row =>
table.ColumnsDefinition(columns =>
{
row.ConstantColumn(25).Text("#", headerStyle);
row.RelativeColumn(3).Text("Product", headerStyle);
row.RelativeColumn().AlignRight().Text("Unit price", headerStyle);
row.RelativeColumn().AlignRight().Text("Quantity", headerStyle);
row.RelativeColumn().AlignRight().Text("Total", headerStyle);
columns.ConstantColumn(25);
columns.RelativeColumn(3);
columns.RelativeColumn();
columns.RelativeColumn();
columns.RelativeColumn();
});
// content
decoration
.Content()
.Stack(column =>
{
foreach (var item in Model.Items)
{
column
.Item()
.ShowEntire()
.BorderBottom(1)
.BorderColor(Colors.Grey.Lighten2)
.Padding(5)
.Row(row =>
{
row.ConstantColumn(25).Text(Model.Items.IndexOf(item) + 1);
row.RelativeColumn(3).Text(item.Name);
row.RelativeColumn().AlignRight().Text($"{item.Price}$");
row.RelativeColumn().AlignRight().Text(item.Quantity);
row.RelativeColumn().AlignRight().Text($"{item.Price * item.Quantity}$");
});
}
});
table.Header(header =>
{
header.Cell().Text("#", headerStyle);
header.Cell().Text("Product", headerStyle);
header.Cell().AlignRight().Text("Unit price", headerStyle);
header.Cell().AlignRight().Text("Quantity", headerStyle);
header.Cell().AlignRight().Text("Total", headerStyle);
header.Cell().ColumnSpan(5)
.PaddingVertical(5).BorderBottom(1).BorderColor(Colors.Black);
});
foreach (var item in Model.Items)
{
table.Cell().Text(Model.Items.IndexOf(item) + 1);
table.Cell().Text(item.Name);
table.Cell().AlignRight().Text($"{item.Price}$");
table.Cell().AlignRight().Text(item.Quantity);
table.Cell().AlignRight().Text($"{item.Price * item.Quantity}$");
table.Cell().ColumnSpan(5)
.PaddingVertical(5).LineHorizontal(1).LineColor(Colors.Grey.Lighten2);
}
});
}
```