You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在Xamarin Forms中使用PDF.js从URL及WEB API显示PDF

解决方案:从Web API加载二进制PDF到PDF.js

看起来你已经搞定了本地PDF的显示,现在要对接Web API返回的二进制PDF数据对吧?核心思路是先从API拿到二进制流,转换成PDF.js能识别的格式,再加载渲染就行。下面是具体的实现步骤和代码示例:

1. 从Web API获取二进制PDF数据

先用HttpClient发送请求,指定接受PDF格式的响应,再读取字节数组:

private async Task<byte[]> GetPdfFromApi(string apiUrl)
{
    using (var client = new HttpClient())
    {
        // 告诉API我们需要PDF格式的响应
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/pdf"));
        
        // 发送请求并确保请求成功
        var response = await client.GetAsync(apiUrl);
        response.EnsureSuccessStatusCode();
        
        // 读取二进制数据
        return await response.Content.ReadAsByteArrayAsync();
    }
}

2. 在PDF.js页面中加载二进制数据

修改你的pdfjsPage方法,先获取API数据,再转换成PDF.js支持的Uint8Array格式,最后注入到WebView的HTML中渲染:

public async void pdfjsPage(string apiUrl)
{
    InitializeComponent();
    
    try
    {
        // 从API获取PDF二进制字节数组
        var pdfBytes = await GetPdfFromApi(apiUrl);
        // 转成Base64字符串方便传递给JS
        var pdfBase64 = Convert.ToBase64String(pdfBytes);
        
        // 构建包含PDF.js逻辑的HTML内容(请确保本地已打包pdf.js和worker文件)
        var htmlContent = $@"
        <!DOCTYPE html>
        <html>
        <head>
            <script src='pdf.min.js'></script> <!-- 引入本地的pdf.js文件 -->
            <style>
                #pdf-container {{ width: 100%; height: 100vh; margin: 0; padding: 0; }}
            </style>
        </head>
        <body>
            <div id='pdf-container'></div>
            <script>
                // 设置PDF.js的worker路径(指向本地的worker文件)
                pdfjsLib.GlobalWorkerOptions.workerSrc = 'pdf.worker.min.js';
                
                // 将Base64转回二进制数据
                const pdfData = atob('{pdfBase64}');
                const uint8Array = new Uint8Array(pdfData.length);
                for (let i = 0; i < pdfData.length; i++) {{
                    uint8Array[i] = pdfData.charCodeAt(i);
                }}
                
                // 加载并渲染PDF
                pdfjsLib.getDocument(uint8Array).promise.then(pdf => {{
                    // 示例:渲染第一页
                    pdf.getPage(1).then(page => {{
                        const scale = 1.5;
                        const viewport = page.getViewport({{ scale: scale }});
                        
                        const canvas = document.createElement('canvas');
                        const context = canvas.getContext('2d');
                        canvas.height = viewport.height;
                        canvas.width = viewport.width;
                        
                        document.getElementById('pdf-container').appendChild(canvas);
                        
                        const renderContext = {{
                            canvasContext: context,
                            viewport: viewport
                        }};
                        page.render(renderContext);
                    }});
                }}).catch(error => {{
                    console.error('PDF加载失败:', error);
                    alert('无法加载API返回的PDF');
                }});
            </script>
        </body>
        </html>";
        
        // 将HTML加载到你的WebView控件中
        YourWebViewControl.LoadHtmlString(htmlContent, null);
    }
    catch (Exception ex)
    {
        await DisplayAlert("PDF加载错误", ex.Message, "OK");
    }
}

3. 关键注意事项

  • 本地文件依赖:请确保你的项目中已包含pdf.min.jspdf.worker.min.js文件,不要用外部CDN链接,避免跨域或加载失败问题。
  • 错误处理:要捕获API请求异常和PDF.js加载异常,给用户清晰的错误提示。
  • 性能优化:如果是大体积PDF,建议添加加载中状态,或者实现分页加载,避免UI卡顿。
  • 权限验证:如果API需要身份验证,记得在HttpClient中添加对应的请求头(比如Token)。

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

火山引擎 最新活动