如何跨UWP、iOS、Android将Xamarin.Forms的XAML UI转PDF?
跨平台实现Xamarin.Forms可滚动XAML页面转PDF的方案
我来帮你梳理下可行的解决思路,毕竟跨平台PDF生成在Xamarin.Forms里确实容易踩坑,尤其是要兼容iOS/Android/UWP三大平台的话:
一、免费开源跨平台方案
1. SkiaSharp + HarfBuzzSharp
这是目前最靠谱的跨平台开源方案,SkiaSharp是谷歌维护的跨平台2D图形库,完全支持Xamarin.Forms三大平台,而且免费开源。核心思路是把XAML页面渲染成位图,再将位图插入PDF文档中。
步骤大概是这样:
- 先安装两个NuGet包:
SkiaSharp.Views.Forms和HarfBuzzSharp(用来处理文本渲染,避免字体显示异常) - 编写代码渲染整个可滚动页面:
// 获取页面的根布局 var content = YourPage.Content; // 测量整个页面的实际高度(包括滚动区域) var size = content.Measure(double.PositiveInfinity, double.PositiveInfinity); var totalWidth = (float)size.Request.Width; var totalHeight = (float)size.Request.Height; // 创建足够大的Bitmap以容纳整个页面 using var bitmap = new SKBitmap((int)totalWidth, (int)totalHeight, SKColorType.Rgba8888, SKAlphaType.Premul); using var canvas = new SKCanvas(bitmap); canvas.Clear(SKColors.White); // 渲染页面内容到Canvas var renderer = content.GetRenderer(); renderer.Element.Layout(new Rectangle(0, 0, totalWidth, totalHeight)); renderer.Draw(canvas, new Rectangle(0, 0, totalWidth, totalHeight)); - 用SkiaSharp的PDF API生成最终PDF:
using var stream = new MemoryStream(); using var pdfDocument = SKDocument.CreatePdf(stream); using var pdfCanvas = pdfDocument.BeginPage(totalWidth, totalHeight); pdfCanvas.DrawBitmap(bitmap, 0, 0); pdfDocument.EndPage(); pdfDocument.Close(); // 最后将stream保存为文件或其他输出形式
2. QuestPDF
这是一个基于SkiaSharp的.NET开源PDF生成库,语法采用声明式布局,非常简洁易读。虽然它主要面向.NET Core/.NET 5+,但也能在Xamarin.Forms中适配使用。你可以把XAML页面的数据提取出来,用QuestPDF的API重新构建PDF布局,生成的PDF是矢量格式,缩放不会模糊,比位图渲染的质量更高。
二、变通方案(如果开源插件适配遇到问题)
1. WebView中转方案
把XAML页面的内容转换成HTML,加载到Xamarin.Forms的WebView中,再调用各平台原生的PDF导出功能。这个方法兼容性极强,因为三大平台的WebView都原生支持PDF生成:
- Android:使用
PrintManager将WebView内容打印为PDF - iOS:使用
WKWebView的createPDF方法或UIPrintInteractionController - UWP:调用
WebView的PrintToPDFAsync方法
优点是不用处理复杂的XAML渲染逻辑,缺点是需要把XAML布局转换为HTML,更适合布局不特别复杂的页面。
2. 原生平台PDF生成 + DependencyService
针对每个平台编写原生的PDF生成代码,通过Xamarin.Forms的DependencyService统一调用。这种方法兼容性最好,但需要编写平台特定代码:
- Android:用
PdfDocument类,结合Xamarin.Forms视图的原生渲染器获取布局信息,手动绘制页面内容 - iOS:用
CoreGraphics的CGPDFContext来绘制内容 - UWP:用
PrintDocument或PdfDocumentAPI
这个方法适合对PDF质量要求高,且愿意投入时间编写平台特定代码的场景。
内容的提问来源于stack exchange,提问作者Selvamz
相关产品推荐
相关产品推荐

