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

如何在WinUI 3桌面应用中离线显示只读PDF流(无需外部程序)

解决方案:嵌入PdfiumCore实现WinUI3内PDF离线渲染

核心思路

使用PdfiumCore(Google Pdfium的.NET绑定),将PDF页面渲染为WinUI支持的BitmapSource,直接在应用内的Image或自定义控件中显示,同时将Pdfium的原生库嵌入应用程序,无需外部安装依赖,完全离线运行。

具体实现步骤

1. 安装NuGet包

在项目中安装PdfiumCore和SkiaSharp.Views.WinUI(用于将Pdfium渲染的位图转换为WinUI可用格式):

Install-Package PdfiumCore
Install-Package SkiaSharp.Views.WinUI

2. 嵌入Pdfium原生库

  • 从PdfiumCore的NuGet包中提取对应架构(x86/x64/arm64)的pdfium.dll文件,添加到项目中。
  • 设置pdfium.dll的属性:复制到输出目录选择“始终复制”,生成操作选择“内容”。这样打包应用时会将原生库包含在内,无需用户额外安装。

3. 编写PDF流渲染代码

以下是从解密后的PDF流中渲染单页并显示的示例代码:

using PdfiumCore;
using SkiaSharp;
using SkiaSharp.Views.WinUI;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media.Imaging;

// decryptedPdfStream为已获取的解密PDF流
public async Task RenderSinglePdfPage(Stream decryptedPdfStream, Image pdfDisplayImage)
{
    // 加载PDF文档
    using var document = PdfDocument.Load(decryptedPdfStream);
    // 取第一页(可根据需求指定页码)
    using var page = document.Pages[0];
    
    // 设置渲染参数(DPI可根据显示需求调整)
    const int dpi = 96;
    var renderWidth = (int)(page.Width * dpi / 72);
    var renderHeight = (int)(page.Height * dpi / 72);
    
    // 创建SkiaSharp位图用于承载渲染内容
    using var bitmap = new SKBitmap(renderWidth, renderHeight, SKColorType.Rgba8888, SKAlphaType.Premul);
    using var canvas = new SKCanvas(bitmap);
    canvas.Clear(SKColors.White);
    
    // 渲染PDF页面到位图
    page.Render(canvas, renderWidth, renderHeight, dpi, dpi, PdfRenderFlags.Annotations);
    
    // 将SkiaSharp位图转换为WinUI可用的BitmapSource
    using var imageStream = new MemoryStream();
    bitmap.Encode(imageStream, SKEncodedImageFormat.Png, 100);
    imageStream.Position = 0;
    
    var bitmapImage = new BitmapImage();
    await bitmapImage.SetSourceAsync(imageStream.AsRandomAccessStream());
    
    // 在Image控件中显示渲染结果
    pdfDisplayImage.Source = bitmapImage;
}

4. 多页PDF滚动浏览实现

如果需要显示完整的多页PDF,可以将每个页面的渲染结果添加到ScrollViewer的StackPanel容器中,实现滚动浏览:

public async Task RenderAllPdfPages(Stream decryptedPdfStream, ScrollViewer scrollViewer)
{
    var pageContainer = new StackPanel();
    using var document = PdfDocument.Load(decryptedPdfStream);
    
    foreach (var page in document.Pages)
    {
        const int dpi = 96;
        var renderWidth = (int)(page.Width * dpi / 72);
        var renderHeight = (int)(page.Height * dpi / 72);
        
        using var bitmap = new SKBitmap(renderWidth, renderHeight, SKColorType.Rgba8888, SKAlphaType.Premul);
        using var canvas = new SKCanvas(bitmap);
        canvas.Clear(SKColors.White);
        
        page.Render(canvas, renderWidth, renderHeight, dpi, dpi, PdfRenderFlags.Annotations);
        
        using var imageStream = new MemoryStream();
        bitmap.Encode(imageStream, SKEncodedImageFormat.Png, 100);
        imageStream.Position = 0;
        
        var bitmapImage = new BitmapImage();
        await bitmapImage.SetSourceAsync(imageStream.AsRandomAccessStream());
        
        var pageImage = new Image
        {
            Source = bitmapImage,
            Margin = new Thickness(0, 0, 0, 10)
        };
        pageContainer.Children.Add(pageImage);
    }
    
    scrollViewer.Content = pageContainer;
}

方案优势

  • 完全离线:所有依赖(Pdfium原生库、.NET包)均嵌入应用,无需用户安装任何外部组件。
  • 无外部调用:全程在应用内完成PDF渲染,无需启动第三方程序。
  • 天然只读:渲染结果为静态图片,满足只读显示需求,无法直接编辑PDF内容。

内容的提问来源于stack exchange,提问作者אפרת

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 21:34:51