当前位置:网站首页>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】
边栏推荐
- 内网渗透学习(二)信息收集
- 猎聘问卷星,成为微信「寄生虫」
- I tried many report tools and finally found a report based on Net 6
- Solution to the third game of 2022 Niuke multi school league
- this指向-超经典面试题
- Use request header authentication to test API interfaces that need authorization
- 金仓数据库 KingbaseES SQL 语言参考手册 (15. SQL语句:CREATE MATERIALIZED VIEW 到 CREATE SCHEMA)
- three.js 给地球加标签和弹窗
- 操作系统常见面试题目总结,含答案
- Week 6 Convolutional Neural Networks (CNNs)
猜你喜欢
随机推荐
Design of intelligent weighing system based on Huawei cloud IOT (STM32) [i]
svn使用碎碎念
2022 极术通讯-安谋科技开启商业化新篇章
[binary tree] balance the binary search tree
金融机构盘点
猎聘问卷星,成为微信「寄生虫」
EFCore Migrations的深入研究
有点酷,使用 .NET MAUI 探索太空
密室逃脱、剧本杀加强监管 重点加强消防安全和未成年人保护
【JVM 系列】JVM 调优
SQL优化的一些建议,希望可以帮到和我一样被SQL折磨的你
Silent desktop fan chip dltap703sd Jericho
千亿酸奶赛道,乳企巨头和新品牌打响拉锯战
Dio problem summary
几张图帮你捋清“中国金融机构体系”
金仓数据库 KingbaseES SQL 语言参考手册 (14. SQL语句:COMMIT 到 CREATE LANGUAGE)
.net GC workflow
C # use the default transformation method
开源 | AREX-携程无代码侵入的流量回放实践
试用了多款报表工具,终于找到了基于.Net 6开发的一个了








