Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
655 views
in Technique[技术] by (71.8m points)

android - Open several pages in webview and create PDF

I am trying to build an app to create a PDF from several pages in webview.

As beginner i was happy i found this: Android create pdf document from webview with multiple pages

However I am not able to get it right. The amount of pages created in the PDF is fine, but the content is not. A PDF with (in this case) 3 similar pages is created. All showing the webview of before the method was called. Once finished creating the PDF, the last url of the url array loads.

How can i achieve that a pdf page is created only after a new url is loaded in webview?

I did try to use delay, but that does not seem to be the issue. If delayed, the pdf is created first and pages are opened up only after.

I did try to call the pdf creation from within onPageFinished(). It did not do the job either.

Maybe i did use all this wrong. Here is what my code looks like right now:

            //Create folder
            String baseDir = Environment.getExternalStorageDirectory().getAbsolutePath();
            String dirName = "exampledirectory";
            File newdir = new File(baseDir + File.separator + dirName);
            newdir.mkdirs();
            //Create PDF
            String fileName = "example.pdf";
            String fileNameWithPath = newdir + File.separator + fileName;
            //Create document
            PdfDocument document = new PdfDocument();

            String[] urlArr = {"exampleurl1.com", "exampleurl2.com", "exampleurl3.com"};

            for (int i = 0; i < urlArr.length; i++) {
                mWebView.loadUrl(urlArr[i]);
                PdfDocument.PageInfo pageInfo = new PdfDocument.PageInfo.Builder(mWebView.getMeasuredWidth(), mWebView.getContentHeight(), i).create();
                // start [i]st page
                PdfDocument.Page page = document.startPage(pageInfo);
                // draw on the page
                View content = mWebView;
                content.draw(page.getCanvas());
                // finish [i]st page
                document.finishPage(page);
            }

            FileOutputStream fos;
            try {
                fos = new FileOutputStream(fileNameWithPath, false);
                // write the document content
                document.writeTo(fos);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            document.close();
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

I found a solution that works for me. It feels a bit odd, but it does the job.

As I mentioned above onPageFinished() did not work on my first tries, cause the page is not rendered yet when called. Now I tried again calling another method from onPageFinished() which then calls the PDFbuilder Methods. With this "workaround" I was able to build a PDF from all URLs. Here`s the code:

private class printPDFFromWebcontent {

    int i = 0;
    public String pageURL = "exampleURL";
    public PdfDocument document = new PdfDocument();
    public String fileNameWithPath ="blank.pdf";

    private void runPDFBuilder() {
    zWebView = (WebView) findViewById(R.id.activity_main_webview);
    WebSettings webSettings = zWebView.getSettings();
    webSettings.setJavaScriptEnabled(true);
    zWebView.setWebViewClient(new WebViewClient() {
        @Override
        public void onPageFinished(WebView view, String url) {
            super.onPageFinished(zWebView, url);
            i++;
            openNextPage();
        }
        private void openNextPage() {
            String nextPage = pageURL + "?page=" + String.valueOf(i + 1); //This works with my specific target URLs. You may want to use an URL array.
            if (i == 1) {
                zWebView.loadUrl(nextPage);
                createPDFNow();
            }
            if (i == 2) {
                zWebView.loadUrl(nextPage);
                addPageToPDF();
            }
            if (i == 3) {
                zWebView.loadUrl(nextPage);
                addPageToPDF();
            }
            if (i == 4) {
                mWebView.loadUrl("whateverYouWantToShowIfFinishedURL"); 
                //Not added to the PDF
                //Reason is to trigger onPageFinished() once more. You could probably i++ here and call openNextPage() from within.
                addPageToPDF(); //Add the last webview content to PDF.
            }
            if (i == 5) {
                createPDFNow();
                Toast.makeText(getApplicationContext(), "Finito.", Toast.LENGTH_SHORT).show();
                savePDF();
                return;
            }
        }
        public void createPDFNow(){
            String baseDir = Environment.getExternalStorageDirectory().getAbsolutePath();
            String dirName = "example";
            File newdir = new File(baseDir + File.separator + dirName);
            newdir.mkdirs();
            String fileName = "example.pdf";
            fileNameWithPath = newdir + File.separator + fileName;
        }
        public void addPageToPDF() {
            PdfDocument.PageInfo pageInfo = new PdfDocument.PageInfo.Builder(zWebView.getMeasuredWidth(), zWebView.getContentHeight(), i).create();
            PdfDocument.Page page = document.startPage(pageInfo);
            View content = zWebView;
            content.draw(page.getCanvas());
            document.finishPage(page);
        }
        public void savePDF(){
            FileOutputStream fos;
            try {
                fos = new FileOutputStream(fileNameWithPath, false);
                document.writeTo(fos);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            document.close();
        }
    });
    zWebView.getSettings().setUseWideViewPort(true);
    zWebView.getSettings().setLoadWithOverviewMode(true);
    zWebView.loadUrl("URL1");
    return;
}

However if there is a smarter solution: I`d like to learn.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...