当前位置:网站首页>Using questpdf operation to generate PDF is faster and more efficient!
Using questpdf operation to generate PDF is faster and more efficient!
2022-07-26 20:13:00 【biyusr】

QuestPDF
QuestPDF Is an open source tool library , Can be in .NET perhaps .Net Core In the middle of pdf file
It provides a layout engine , The design takes into account the complete paging support and flexibility requirements ! More common than on the market Aspose and iTextSharp It's easy to use !GitHub Address
install
Install-Package QuestPDF

Example
A simple example
Generate Pdf The document is divided into three parts ,Header( header ),Content( Content ),Footer( The footer )
Document.Create(container =>
{
container.Page(page =>
{
page.Size(PageSizes.A4);
page.Margin(2, Unit.Centimetre);
page.Background(Colors.White);
page.DefaultTextStyle(x => x.FontSize(20));
page.Header()
.Text("Hello PDF!")
.SemiBold().FontSize(36).FontColor(Colors.Blue.Medium);
page.Content()
.PaddingVertical(1, Unit.Centimetre)
.Column(x =>
{
x.Spacing(20);
x.Item().Text(Placeholders.LoremIpsum());
x.Item().Image(Placeholders.Image(200, 100));
});
page.Footer()
.AlignCenter()
.Text(x =>
{
x.Span("Page ");
x.CurrentPageNumber();
});
});
})
.GeneratePdf("hello.pdf");

The template to generate
Use template generation to design a total of three application layers :
file Model( A set of descriptions PDF Class of document content )
data source ( Map domain entities to the layers of the document model )
Templates ( Describes how to visualize information and transform it into PDF File layer representation )
For example, we design a basic invoice information To design a shopping list , The address of a seller buyer , And invoice number, etc We designed this 3 individual Model class
public class InvoiceModel
{
public int InvoiceNumber { get; set; }
public DateTime IssueDate { get; set; }
public DateTime DueDate { get; set; }
public Address SellerAddress { get; set; }
public Address CustomerAddress { get; set; }
public List<OrderItem> Items { get; set; }
public string Comments { get; set; }
}
public class OrderItem
{
public string Name { get; set; }
public decimal Price { get; set; }
public int Quantity { get; set; }
}
public class Address
{
public string CompanyName { get; set; }
public string Street { get; set; }
public string City { get; set; }
public string State { get; set; }
public object Email { get; set; }
public string Phone { get; set; }
}
Model Once defined, we will define some false data to fill in pdf
public static class InvoiceDocumentDataSource
{
private static Random Random = new Random();
public static InvoiceModel GetInvoiceDetails()
{
var items = Enumerable
.Range(1, 8)
.Select(i => GenerateRandomOrderItem())
.ToList();
return new InvoiceModel
{
InvoiceNumber = Random.Next(1_000, 10_000),
IssueDate = DateTime.Now,
DueDate = DateTime.Now + TimeSpan.FromDays(14),
SellerAddress = GenerateRandomAddress(),
CustomerAddress = GenerateRandomAddress(),
Items = items,
Comments =" Test notes "
};
}
private static OrderItem GenerateRandomOrderItem()
{
return new OrderItem
{
Name = " goods ",
Price = (decimal)Math.Round(Random.NextDouble() * 100, 2),
Quantity = Random.Next(1, 10)
};
}
private static Address GenerateRandomAddress()
{
return new Address
{
CompanyName = " Test store ",
Street = " Test Street ",
City = " Test cities ",
State = " Test status ",
Email = " Test mail ",
Phone = " Test call "
};
}
}
Then build our formwork scaffold We will use formwork and scaffolding , We need to define an implementation IDocument Start with a new class of the interface . This interface contains two methods
DocumentMetadata GetMetadata();
void Compose(IDocumentContainer container);
The first is some basic information of the template document The second is the container of the template Based on these principles, we design a template layer class
public class InvoiceDocument : IDocument
{
public InvoiceModel Model { get; }
public InvoiceDocument(InvoiceModel model)
{
Model = model;
}
public DocumentMetadata GetMetadata() => DocumentMetadata.Default;
public void Compose(IDocumentContainer container)
{
container
.Page(page =>
{
page.PageColor(Colors.Red.Lighten1);
page.Size(PageSizes.A4);
page.Margin(10);// Margin
page.Header().Height(100).Background(Colors.LightBlue.Lighten1);
page.Content().Background(Colors.Grey.Lighten3);
page.Footer().Height(50).Background(Colors.Grey.Lighten1);
});
}
}
pdf Of page A page always has three elements : header , The footer , Content . Take a look at the document we generated

up to now , We have built a very simple page , Each part has a different color or size
Next, let's fill in his header , After we sort out the data source , You can call Element Method fill
public void Compose(IDocumentContainer container)
{
container
.Page(page =>
{
page.PageColor(Colors.Red.Lighten1);
page.Size(PageSizes.A4);
page.Margin(10);// Margin
page.Header().Height(100).Background(Colors.LightBlue.Lighten1).Element(ComposeHeader);
page.Content().Background(Colors.Grey.Lighten3);
page.Footer().Height(50).Background(Colors.Grey.Lighten1);
});
}
void ComposeHeader(IContainer container)
{
var titleStyle = TextStyle.Default.FontSize(20).SemiBold().FontColor(Colors.Blue.Medium);
container.Row(row =>
{
row.RelativeItem().Column(column =>
{
column.Item().Text($" invoice #{Model.InvoiceNumber}").FontFamily("simhei").Style(titleStyle);
column.Item().Text(text =>
{
text.Span(" Date of issue : ").SemiBold().FontFamily("simhei");
text.Span($"{Model.IssueDate:d}").FontFamily("simhei");
});
column.Item().Text(text =>
{
text.Span(" Payment date : ").FontFamily("simhei").SemiBold();
text.Span($"{Model.DueDate:d}").FontFamily("simhei");
});
})
;
});
}

Finally, let's implement the content ,
public void Compose(IDocumentContainer container)
{
container
.Page(page =>
{
page.PageColor(Colors.Red.Lighten1);
page.Size(PageSizes.A4);
page.Margin(10);// Margin
page.Header().Height(100).Background(Colors.LightBlue.Lighten1).Element(ComposeHeader);
page.Content().Background(Colors.Grey.Lighten3).Element(ComposeContent);
page.Footer().Height(50).Background(Colors.Grey.Lighten1);
});
}
void ComposeHeader(IContainer container)
{
var titleStyle = TextStyle.Default.FontSize(20).SemiBold().FontColor(Colors.Blue.Medium);
container.Row(row =>
{
row.RelativeItem().Column(column =>
{
column.Item().Text($" invoice #{Model.InvoiceNumber}").FontFamily("simhei").Style(titleStyle);
column.Item().Text(text =>
{
text.Span(" Date of issue : ").SemiBold().FontFamily("simhei");
text.Span($"{Model.IssueDate:d}").FontFamily("simhei");
});
column.Item().Text(text =>
{
text.Span(" Payment date : ").FontFamily("simhei").SemiBold();
text.Span($"{Model.DueDate:d}").FontFamily("simhei");
});
})
;
});
}
void ComposeContent(IContainer container)
{
container.Table(table =>
{
// step 1
table.ColumnsDefinition(columns =>
{
columns.ConstantColumn(25);
columns.RelativeColumn(3);
columns.RelativeColumn();
columns.RelativeColumn();
columns.RelativeColumn();
});
// step 2
table.Header(header =>
{
header.Cell().Text("#").FontFamily("simhei");
header.Cell().Text(" goods ").FontFamily("simhei");
header.Cell().AlignRight().Text(" Price ").FontFamily("simhei");
header.Cell().AlignRight().Text(" Number ").FontFamily("simhei");
header.Cell().AlignRight().Text(" The total price ").FontFamily("simhei");
header.Cell().ColumnSpan(5)
.PaddingVertical(5).BorderBottom(1).BorderColor(Colors.Black);
});
// step 3
foreach (var item in Model.Items)
{
table.Cell().Element(CellStyle).Text(Model.Items.IndexOf(item) + 1).FontFamily("simhei");
table.Cell().Element(CellStyle).Text(item.Name).FontFamily("simhei");
table.Cell().Element(CellStyle).AlignRight().Text($"{item.Price}$").FontFamily("simhei");
table.Cell().Element(CellStyle).AlignRight().Text(item.Quantity).FontFamily("simhei");
table.Cell().Element(CellStyle).AlignRight().Text($"{item.Price * item.Quantity}$").FontFamily("simhei");
static IContainer CellStyle(IContainer container)
{
return container.BorderBottom(1).BorderColor(Colors.Grey.Lighten2).PaddingVertical(5);
}
}
});
}
After these preparations are completed, we can generate Pdf Document.
var filePath = "invoice.pdf";
var model = InvoiceDocumentDataSource.GetInvoiceDetails();
var document = new InvoiceDocument(model);
document.GeneratePdf(filePath);

Of course, there are many interesting functions , Let's talk about a concept today , Let everyone have an impression of this thing , Later, I will continue to output the relevant functions of the library . If you are interested in the library , Keep an eye on me ! WeChat official account 【 Black brother chat dotNet】
边栏推荐
猜你喜欢
![Ue5 editor slate quick start [opening]](/img/88/9c6e8ff970b3138299ecbe79d90f2e.png)
Ue5 editor slate quick start [opening]

操作系统常见面试题目总结,含答案

C# 使用默认转型方法

网络与VPC动手实验

three. JS tag and pop-up the earth

I hope some suggestions on SQL optimization can help you who are tortured by SQL like me

FastTunnel-开源内网穿透框架

BluePrism流程业务对象的组件功能介绍-RPA第三章

Overview of canvas

Week 6 Convolutional Neural Networks (CNNs)
随机推荐
直播预约有奖| 高级咨询顾问徐雁斐:效能度量如何助力高效精细的外包管理
LeetCode_回溯_中等_40.组合总和 II
C# 客户端程序调用外部程序的3种实现方法
徽商期货开户安全吗?请问徽商期货开户应该注意什么呢?
Excel-VBA 快速上手(十一、字符串常用操作)
负载均衡的使用
正则表达式
Excel-VBA 快速上手(十、提示框、可输入的弹出框)
一文看懂中国的金融体系
福建争抢VC/PE
Kingbasees SQL language reference manual of Jincang database (17. SQL statement: discard to drop language)
regular expression
如何同步等待多个异步 task 的返回结果 ?
Solution to the third game of 2022 Niuke multi school league
STM32F103有源蜂鸣器驱动程序
金仓数据库 KingbaseES SQL 语言参考手册 (15. SQL语句:CREATE MATERIALIZED VIEW 到 CREATE SCHEMA)
UE5编辑器Slate快速入门【开篇】
Ue5 editor slate quick start [opening]
金仓数据库 KingbaseES SQL 语言参考手册 (14. SQL语句:COMMIT 到 CREATE LANGUAGE)
Codeforces Round #810 (Div. 2)(A~C)