#yyds干货盘点#愚公系列2023年03月 .NET CORE工具案例-.NET Core使用QuestPDF
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了#yyds干货盘点#愚公系列2023年03月 .NET CORE工具案例-.NET Core使用QuestPDF相关的知识,希望对你有一定的参考价值。
前言
QuestPDF是一个用于生成PDF文档的open-source.NET库。
它提供了一个布局引擎,设计时考虑了完整的分页支持。文档由许多简单元素组成(例如边框、背景、图像、文本、填充、表格、网格等),这些元素组合在一起以创建更复杂的结构。这样,作为一名开发人员,您可以理解每个元素的行为,并满怀信心地使用它们。此外,文档及其所有元素都支持分页功能。例如,一个元素可以移动到下一页(如果没有足够的空间),甚至可以像表的行一样在页面之间拆分。
与其他库不同,它不依赖html-to-PDF转换,在许多情况下,这种转换不可靠。相反,它实现了自己的布局引擎,该引擎经过优化以覆盖所有paging-related需求。
github文档地址:https://github.com/QuestPDF/QuestPDF
API文档地址:https://www.questpdf.com/api-reference/index
一、.NET Core使用QuestPDF
1.Nuget安装包
Install-Package QuestPDF
2.官方案例
using QuestPDF.Fluent;
using QuestPDF.Helpers;
using QuestPDF.Infrastructure;
// code in your main method
Document.Create(container =>
container.Page(page =>
page.Size(PageSizes.A4);
page.Margin(2, Unit.Centimetre);
page.PageColor(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");
3.发票案例
3.1 定义模型类InvoiceModel
//发票类
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;
3.2 InvoiceDocumentDataSource数据生成
public static class InvoiceDocumentDataSource
private static Random Random = new Random();
public static InvoiceModel GetInvoiceDetails()
var items = Enumerable
.Range(1, 25)
.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 = Placeholders.Paragraph()
;
private static OrderItem GenerateRandomOrderItem()
return new OrderItem
Name = Placeholders.Label(),
Price = (decimal) Math.Round(Random.NextDouble() * 100, 2),
Quantity = Random.Next(1, 10)
;
private static Address GenerateRandomAddress()
return new Address
CompanyName = Placeholders.Name(),
Street = Placeholders.Label(),
City = Placeholders.Label(),
State = Placeholders.Label(),
Email = Placeholders.Email(),
Phone = Placeholders.PhoneNumber()
;
3.3 InvoiceDocument 发票文档
using System.Linq;
using QuestPDF.Drawing;
using QuestPDF.Fluent;
using QuestPDF.Helpers;
using QuestPDF.Infrastructure;
namespace QuestPDF.ExampleInvoice
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.Margin(50);
//页面头
page.Header().Element(ComposeHeader);
// 页面内容
page.Content().Element(ComposeContent);
//1 / 2
page.Footer().AlignCenter().Text(text =>
//当前页数
text.CurrentPageNumber();
//分割
text.Span(" / ");
//总页数
text.TotalPages();
);
);
//发票头
void ComposeHeader(IContainer container)
container.Row(row =>
//其实row相当于列,Column相当于行
row.RelativeItem().Column(Column =>
Column
.Item().Text($"Invoice #Model.InvoiceNumber")
.FontSize(20).SemiBold().FontColor(Colors.Blue.Medium);
Column.Item().Text(text =>
text.Span("Issue date: ").SemiBold();
text.Span($"Model.IssueDate:d");
);
Column.Item().Text(text =>
text.Span("Due date: ").SemiBold();
text.Span($"Model.DueDate:d");
);
);
//宽100,高50的图片
row.ConstantItem(100).Height(50).Placeholder();
);
//发票体
void ComposeContent(IContainer container)
//其实row相当于列,Column相当于行
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$").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)
table.Cell().Element(CellStyle).Text(Model.Items.IndexOf(item) + 1);
table.Cell().Element(CellStyle).Text(item.Name);
table.Cell().Element(CellStyle).AlignRight().Text($"item.Price$");
table.Cell().Element(CellStyle).AlignRight().Text(item.Quantity);
table.Cell().Element(CellStyle).AlignRight().Text($"item.Price * item.Quantity$");
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);
);
3.4 生成发票
class Program
static void Main(string[] args)
var model = InvoiceDocumentDataSource.GetInvoiceDetails();
var document = new InvoiceDocument(model);
// 生成PDF文件并在默认查看器中显示
GenerateDocumentAndShow(document);
//或者nuget安装QuestPDF Previewer预览器并尝试文档的设计
//在每次代码更改后,无需重新编译即可实时执行
//document.ShowInPreviewer();
static void GenerateDocumentAndShow(InvoiceDocument document)
const string filePath = "invoice.pdf";
document.GeneratePdf(filePath);
//执行进程查看发票
var process = new Process
StartInfo = new ProcessStartInfo(filePath)
UseShellExecute = true
;
process.Start();
以上是关于#yyds干货盘点#愚公系列2023年03月 .NET CORE工具案例-.NET Core使用QuestPDF的主要内容,如果未能解决你的问题,请参考以下文章
#yyds干货盘点#愚公系列2023年02月 微信小程序-获取WIFI信息
#yyds干货盘点#愚公系列2023年02月 微信小程序-Page页面扩展
#yyds干货盘点#愚公系列2023年02月 .NET/C#知识点-程序运行计时的总结
#yyds干货盘点#愚公系列2023年02月 微信小程序-电商项目-商品详情页面的标题及价格功能实现