如何在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.js和pdf.worker.min.js文件,不要用外部CDN链接,避免跨域或加载失败问题。 - 错误处理:要捕获API请求异常和PDF.js加载异常,给用户清晰的错误提示。
- 性能优化:如果是大体积PDF,建议添加加载中状态,或者实现分页加载,避免UI卡顿。
- 权限验证:如果API需要身份验证,记得在
HttpClient中添加对应的请求头(比如Token)。
内容的提问来源于stack exchange,提问作者waqas waqas




