You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何处理.NET MAUI中SkiaSharp.SKDocument的BeginPage()无报错调试终止问题

.NET MAUI + SkiaSharp PDF生成调试终止问题

我正在用SkiaSharp开发.NET MAUI移动端应用,需求是生成指定日期的库存盘点表PDF并分享。代码能正常编译,但调试时执行到document.BeginPage()这一行,程序直接终止且无报错。相关代码片段如下:

public async Task<SKDocument> GenerateInventoryItemCountPdfAsync(DateTime date, List<Item> items, string pdfLogoPath, string pdfTitle) 
{ 
    var stream = new MemoryStream(); 
    using var document = SKDocument.CreatePdf(stream); 

    var pageSize = new SKSize(595, 842); 
    using var canvas = document.BeginPage((int)pageSize.Width, (int)pageSize.Height); 

    using (var logoBitmap = SKBitmap.Decode(pdfLogoPath)) 
    { 
        var logoRect = SKRect.Create(pageSize.Width / 2 - logoBitmap.Width / 2, 50, logoBitmap.Width, logoBitmap.Height); 
        canvas.DrawBitmap(logoBitmap, logoRect); 

        var titlePaint = new SKPaint 
        { 
            Typeface = SKTypeface.FromFamilyName("Arial", SKFontStyleWeight.Bold, SKFontStyleWidth.Normal, SKFontStyleSlant.Upright), 
            TextSize = 24, 
            IsAntialias = true, 
            Color = SKColors.Black
            // 后续代码省略
        };
    }
}

排查与解决建议

  • 检查Logo文件路径有效性:如果pdfLogoPath指向的文件不存在、路径错误或格式不支持,SKBitmap.Decode会抛出未捕获的异常直接终止进程。先加文件存在性判断:

    if (!File.Exists(pdfLogoPath))
    {
        throw new FileNotFoundException("Logo文件不存在", pdfLogoPath);
    }
    
  • 修正对象生命周期问题:当前方法返回SKDocument,但它被using包裹,方法结束时document会被自动释放,调用方使用时会触发异常。建议改为返回MemoryStream,确保PDF内容完整保留:

    public async Task<MemoryStream> GenerateInventoryItemCountPdfAsync(DateTime date, List<Item> items, string pdfLogoPath, string pdfTitle) 
    { 
        var stream = new MemoryStream(); 
        using var document = SKDocument.CreatePdf(stream); 
    
        var pageSize = new SKSize(595, 842); 
        using var canvas = document.BeginPage((int)pageSize.Width, (int)pageSize.Height); 
    
        // 执行所有绘制逻辑...
    
        document.EndPage();
        document.Close();
        stream.Position = 0; // 重置流指针到起始位置
        return stream;
    }
    
  • 匹配SkiaSharp依赖版本:确保项目中SkiaSharp和SkiaSharp.NativeAssets.Maui的版本完全一致,版本不兼容会导致底层渲染异常。

  • 捕获全局未处理异常:在App.xaml.cs中添加全局异常处理,排查隐藏的异常信息:

    protected override void OnStart()
    {
        AppDomain.CurrentDomain.UnhandledException += (sender, args) =>
        {
            var exception = args.ExceptionObject as Exception;
            System.Diagnostics.Debug.WriteLine($"未处理异常: {exception?.Message}\n{exception?.StackTrace}");
        };
    }
    
  • 避免字体加载失败:移动端可能没有Arial字体,换成系统默认字体或嵌入自定义字体,比如:

    Typeface = SKTypeface.Default,
    // 或者嵌入字体文件后加载
    // Typeface = SKTypeface.FromFile("Assets/Fonts/CustomFont.ttf")
    

内容的提问来源于stack exchange,提问作者Conrad Budde

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 02:17:11