在Xamarin App中从字节数组显示PDF

时间:2018-07-20 15:36:00

标签: arrays pdf xamarin xamarin.forms stream

我正在使用Xamarin Forms创建一个移动应用程序,用户可以在其中查看已完成检查的结果。考试的结果来自字节数组格式的数据库,我需要以某种方式将字节数组转换为PDF并将其显示给用户。我看到我可以使用WebView来显示PDF,但是需要将其保存到设备中然后再显示。有人会知道我如何将字节数组转换为PDF并在WebView中显示而不需要保存它或进行其他操作吗?

谢谢。

1 个答案:

答案 0 :(得分:0)

使用pdf.js非常简单:https://mozilla.github.io/pdf.js/

  1. 向您的表单页面添加WebView并设置相关性代码以获取每个平台的baseurl路径

  2. pdf.jspdf.worker.js添加到您的应用程序项目(iOS为BundleResource,Android为AndroidAsset

  3. 将您的PDF流转换为Base64字符串(如果需要,可通过MemoryStream),然后将该字符串嵌入基于HTML的字符串中。

  4. 使用JavaScript(atob)解码该base64字符串,并设置html中定义的pdf.js / pdf.worker.js to render to a canvas`。

示例:

XAML:

<StackLayout x:Name="webViewContainer" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">
    <WebView x:Name="webView" BindingContext="{x:Reference webViewContainer}" WidthRequest="{Binding Width}" HeightRequest="{Binding Height}"/>
</StackLayout>

隐藏代码:

注意:通过捆绑的资源使用PDF,在那里替换您的流。...

            var baseUrl = DependencyService.Get<IBaseUrl>().Get();
            string base64Pdf;
            using (var stream = await FileSystem.OpenAppPackageFileAsync("Dank Learning 1806.04510.pdf"))
            using (var memoryStream = new MemoryStream())
            {
                await stream.CopyToAsync(memoryStream);
                base64Pdf = Convert.ToBase64String(memoryStream.ToArray());
            }
            var html = @"
<html>
<head> 
<script type=""text/javascript"" src=""pdf.js""></script>
 <script type=""text/javascript"">
    window.onload=function(){
var pdfData = atob('SUSHIHANGOVER');
var pdfjsLib = window['pdfjs-dist/build/pdf'];
pdfjsLib.GlobalWorkerOptions.workerSrc = 'pdf.worker.js';
var loadingTask = pdfjsLib.getDocument({data: pdfData});
loadingTask.promise.then(function(pdf) {
  console.log('PDF loaded');
  var pageNumber = 1;
  pdf.getPage(pageNumber).then(function(page) {
    console.log('Page loaded');
    var scale = 1.5;
    var viewport = page.getViewport(scale);
    var canvas = document.getElementById('the-canvas');
    var context = canvas.getContext('2d');
    canvas.height = viewport.height;
    canvas.width = viewport.width;
    var renderContext = {
      canvasContext: context,
      viewport: viewport
    };
    var renderTask = page.render(renderContext);
    renderTask.then(function () {
      console.log('Page rendered');
    });
  });
}, function (reason) {
  console.error(reason);
});
    }
</script>
</head>
<body>
<h1>StackOverflow / Base64 PDF</h1>
<canvas id=""the-canvas"" style=""border: 1px solid""></canvas>
<h2>by SushiHangover</h2>
</body>
</html>
";
            html = html.Replace("SUSHIHANGOVER", base64Pdf);
            webView.Source = new HtmlWebViewSource
            {
                BaseUrl = baseUrl,
                Html = html
            };