【问题标题】:first time save blank page using webivew in xamarin forms第一次在 xamarin 表单中使用 webview 保存空白页
【发布时间】:2020-05-04 00:36:17
【问题描述】:

我有 local html file 我想将 html 保存到本地路径中加载的 Webview。 但第一次总是保存空数据。

 try 
        {
            htmltopdfs = html;
            var dir = new Java.IO.File(Android.OS.Environment.ExternalStorageDirectory.AbsolutePath + "/SVSTATIONERY/");
            var file = new Java.IO.File(dir + "/" + fileName + ".pdf");

            if (!dir.Exists())
                dir.Mkdirs();
            //else
            //    dir.Delete();

            int x = 0;
            while (file.Exists())
            {
                x++;
                file = new Java.IO.File(dir + "/" + fileName + "( " + x + " )" + ".pdf");
            }

            //if (webpage == null)
            var webpage = new Android.Webkit.WebView(MainActivity.context);

            int width = 2102;
            int height = 2970;

            webpage.Layout(0, 0, width, height);
            webpage.LoadDataWithBaseURL("", htmltopdfs, "text/html", "UTF-8", null);
            webpage.SetWebViewClient(new WebViewCallBack(file.ToString()));

            return file.ToString();
        }
        catch (Java.Lang.Exception e)
        {
            return e.Message;
        }

Onpagefinished event

 class WebViewCallBack : WebViewClient
{

    string fileNameWithPath = null;

    public WebViewCallBack(string path)
    {
        this.fileNameWithPath = path;
    }

    public override void OnPageFinished(Android.Webkit.WebView myWebview, string url)
    {
        PdfDocument document = new Android.Graphics.Pdf.PdfDocument();
        PdfDocument.Page page = document.StartPage(new PdfDocument.PageInfo.Builder(2102, 3500, 1).Create());

        myWebview.Draw(page.Canvas);
        document.FinishPage(page);
        Stream filestream = new MemoryStream();
        FileOutputStream fos = new Java.IO.FileOutputStream(fileNameWithPath, false);

        document.WriteTo(filestream);
        fos.Write(((MemoryStream)filestream).ToArray(), 0, (int)filestream.Length);
        fos.Close();
    }


}

创建后,但第一次,空白页面已创建到本地路径,然后创建多次后正常工作。

【问题讨论】:

    标签: android xamarin mobile xamarin.forms webview


    【解决方案1】:

    这是我关于将 webview(加载本地 html)打印为 PDF 的演示。

    这里正在运行 GIF()。

    我在 xamarin 表单中的布局,如以下代码。

       <StackLayout>
        <Button Text="save" Clicked="Button_Clicked"/>
        <Entry x:Name="MyEntry" Text="5"></Entry>
        <Label x:Name="MyLabel"></Label>
        <!-- Place new controls here -->
        <WebView x:Name="MywebView" HeightRequest="1000" Navigated="MywebView_Navigated"
        WidthRequest="1000"/>
    </StackLayout>
    

    在 Android 成就中,我使用了 MessagingCenter 和 webview 的自定义渲染器来实现。

    [assembly: ExportRenderer(typeof(Xamarin.Forms.WebView), typeof(MyWebviewRender))]
    

    命名空间 MyWebView.Droid { MyWebviewRender 类:WebViewRenderer { 上下文上下文; 公共 MyWebviewRender(上下文上下文):基础(上下文){ this.context = 上下文; }

        protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.WebView> e)
        {
            base.OnElementChanged(e);
    
            MessagingCenter.Subscribe<string>(this, "pdf", (key) => {
    
                var printManager = (PrintManager)context.GetSystemService(Context.PrintService);
                var printAdapter = new MyPrintDocumentAdapter(context, Control);
                var printJob = printManager.Print("MyPrintJob", printAdapter, null);
    
            });
    
    
        }
    
    }
    

    MyPrintDocumentAdapter.cs

        public class MyPrintDocumentAdapter : PrintDocumentAdapter
    {
    
        View view;
        Context context;
        PrintedPdfDocument document;
        float scale;
    
        public MyPrintDocumentAdapter(Context context, View view)
        {
            this.view = view;
            this.context = context;
        }
    
        public override void OnLayout(PrintAttributes oldAttributes, PrintAttributes newAttributes, CancellationSignal cancellationSignal, LayoutResultCallback callback, Bundle extras)
        {
            document = new PrintedPdfDocument(context, newAttributes);
    
            CalculateScale(newAttributes);
    
            //set the printed PDF attributes
            var printInfo = new PrintDocumentInfo
                .Builder("MyPrint.pdf")
                .SetContentType(PrintContentType.Document)
                .SetPageCount(10)
                .Build();
    
            callback.OnLayoutFinished(printInfo, true);
        }
    
        public override void OnWrite(PageRange[] pages, ParcelFileDescriptor destination, CancellationSignal cancellationSignal, WriteResultCallback callback)
        {
            PrintedPdfDocument.Page page = document.StartPage(0);
    
            page.Canvas.Scale(scale, scale);
    
            view.Draw(page.Canvas);
    
            document.FinishPage(page);
    
            WritePrintedPdfDoc(destination);
    
            document.Close();
    
            document.Dispose();
    
            callback.OnWriteFinished(pages);
        }
    
        void CalculateScale(PrintAttributes newAttributes)
        {
            int dpi = Math.Max(newAttributes.GetResolution().HorizontalDpi, newAttributes.GetResolution().VerticalDpi);
    
            int leftMargin = (int)(dpi * (float)newAttributes.MinMargins.LeftMils / 1000);
            int rightMargin = (int)(dpi * (float)newAttributes.MinMargins.RightMils / 1000);
            int topMargin = (int)(dpi * (float)newAttributes.MinMargins.TopMils / 1000);
            int bottomMargin = (int)(dpi * (float)newAttributes.MinMargins.BottomMils / 1000);
    
            int w = (int)(dpi * (float)newAttributes.GetMediaSize().WidthMils / 1000) - leftMargin - rightMargin;
            int h = (int)(dpi * (float)newAttributes.GetMediaSize().HeightMils / 1000) - topMargin - bottomMargin;
    
            scale = Math.Min((float)document.PageContentRect.Width() / w, (float)document.PageContentRect.Height() / h);
        }
    
        void WritePrintedPdfDoc(ParcelFileDescriptor destination)
        {
            var i=destination.FileDescriptor;
            var javaStream = new Java.IO.FileOutputStream(destination.FileDescriptor);
            var osi = new OutputStreamInvoker(javaStream);
            using (var mem = new MemoryStream())
            {
                document.WriteTo(mem);
                var bytes = mem.ToArray();
                osi.Write(bytes, 0, bytes.Length);
            }
        }
    
    }
    

    这是我的演示链接。 https://github.com/851265601/PrintLocalWebview2PDF

    【讨论】:

    • @Vignesh Siva 这个问题有更新吗?如果回复有帮助,请将其标记为答案,它将帮助其他有类似问题的人。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-04-23
    • 1970-01-01
    • 2015-08-24
    • 1970-01-01
    • 2017-05-23
    • 2023-01-24
    • 1970-01-01
    相关资源
    最近更新 更多