简体   繁体   English

从 Android 上的 Webview 创建 PDF

[英]Create a PDF from Webview on Android

So I am trying to create a PDF from a Webview.所以我试图从 Webview 创建一个 PDF。 Right now I can create an image from the webview, but I am having some problems to split my document in many pages.现在我可以从 webview 创建图像,但是在将文档拆分为多页时遇到了一些问题。

First, I create a Bitmap from the webview:首先,我从 webview 创建一个 Bitmap:

public static Bitmap screenShot(View view) {
        Bitmap bitmap = Bitmap.createBitmap(view.getWidth(),
                view.getHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        canvas.drawColor(Color.WHITE);
        view.draw(canvas);
        return bitmap;
    }

Second, I create and I show the PDF:其次,我创建并显示 PDF:

public void criaPdf(){
        Bitmap bitmap = Utils.screenShot(mContratoWebview);

        Document doc = new Document();


        File dir = new File(getFilesDir(), "app_imageDir");

        if(!dir.exists()) {
            dir.mkdirs();
        }

        File file = new File(dir, "contratoPdf.pdf");

        try {
            FileOutputStream fOut = new FileOutputStream(file);

            PdfWriter.getInstance(doc, fOut);

            //open the document
            doc.open();

            ByteArrayOutputStream stream = new ByteArrayOutputStream();
            bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);

            byte[] byteArray = stream.toByteArray();
            Image image = Image.getInstance(byteArray);
            image.scaleToFit(PageSize.A4.getHeight(), PageSize.A4.getWidth());

            doc.newPage();
            doc.add(image);
        } catch (DocumentException de) {
            Log.e("PDFCreator", "DocumentException:" + de);
        } catch (IOException e) {
            Log.e("PDFCreator", "ioException:" + e);
        }
        finally {
            doc.close();
        }

        mPdfView.fromFile(file)
                .pages(0, 1) // all pages are displayed by default
                .enableSwipe(true)
                .load();
        mPdfView.setVisibility(View.VISIBLE);
}

This is what I got so far:这是我到目前为止得到的:

在此处输入图像描述

So my problem is: The content of the Webview is too big to fit in the PDF.所以我的问题是: Webview 的内容太大,无法放入 PDF。 How can I solve this?我该如何解决这个问题?

WebView has built-in functionality to generate PDF's which is made available by using PrintManager Service specifically for the purpose of printing. WebView具有生成PDF的内置功能,可通过使用PrintManager服务专门用于打印。 But for your specific usecase I would suggest you to write(store) the final output of WebView's PrintAdapter which is a PDF file to a local file and go from there. 但是对于您的特定用例,我建议您编写(存储)WebView的PrintAdapter的最终输出,这是一个PDF文件到本地文件并从那里开始。

This link will walk you through the details and implementation. 此链接将引导您完成详细信息和实施。 http://www.annalytics.co.uk/android/pdf/2017/04/06/Save-PDF-From-An-Android-WebView/ http://www.annalytics.co.uk/android/pdf/2017/04/06/Save-PDF-From-An-Android-WebView/

You can achieve API level 19(KitKat) compatibility with small tweaks for the above solution. 您可以通过上述解决方案的小调整实现API级别19(KitKat)兼容性。

This should solve your problem but incase you face any issue with the implementation let me know. 这应该可以解决您的问题,但是如果您对实施有任何疑问,请告诉我。

to create pdf from webview you need android>kitkat -> sdk>=19 要从webview创建pdf,你需要安装android> kitkat - > sdk> = 19

  btnSave.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            if (Build.VERSION.SDK_INT > Build.VERSION_CODES.KITKAT) {

                createWebPrintJob(webView);
            } else {



            }

        }
    });

//// Function: ////功能:

private void createWebPrintJob(WebView webView) {

    PrintManager printManager = (PrintManager) this
            .getSystemService(Context.PRINT_SERVICE);

    PrintDocumentAdapter printAdapter =
            webView.createPrintDocumentAdapter();

    String jobName = getString(R.string.app_name) + " Print Test";

    if (printManager != null) {
        printManager.print(jobName, printAdapter,
                new PrintAttributes.Builder().build());
    }
}

I have problem in create image from webview :)))) 我从webview创建图像有问题:))))

In my case, I solved this by firstly converting the webview into a bitmap, then scaling the bitmap to fit into the pdf page. In my case, I solved this by firstly converting the webview into a bitmap, then scaling the bitmap to fit into the pdf page.

As for the printing part, I think it was more flexible to simply share the pdf and ask the user to select his printer software, as it's more useful than simply saving as pdf.至于打印部分,我觉得简单分享 pdf 并要求用户 select 他的打印机软件更灵活,因为它比简单地保存为 Z437175BA4191210EE004E1D93749 更有用。

If you want to print several pages, I think it is more manageable to create different bitmaps and assign them to different pdf pages.如果要打印多页,我认为创建不同的位图并将它们分配给不同的 pdf 页面更易于管理。

Here is the code to converting the webview into a single pdf page and then sharing it:这是将 webview 转换为单个 pdf 页面然后共享它的代码:

public static void sharePdfFile(WebView webView, Context context)
{
    Bitmap bitmap = webviewToBitmap( webView );
    PrintedPdfDocument pdf =  bitmapToPdf( bitmap, context );
    File file = pdfToFile( pdf, context );
    shareFile( file,"application/pdf", context );
}

private static void shareFile(File file, String contentType, Context context)
{
    Uri uri = FileProvider.getUriForFile(
        context,
        context.getPackageName() + ".fileprovider",
        file);
    Intent shareIntent = new Intent(android.content.Intent.ACTION_SEND);
    shareIntent.setType(contentType);
    shareIntent.putExtra(Intent.EXTRA_STREAM, uri);
    shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
    Toast.makeText(
        context,
        "Choose your printer app",
        Toast.LENGTH_LONG
    ).show();
    context.startActivity( shareIntent );
}

private static File pdfToFile(PrintedPdfDocument printedPdfDocument, Context context)
{
    File file = new File(context.getFilesDir(), "share.pdf");
    try {
        FileOutputStream outputStream = new FileOutputStream(file);
        printedPdfDocument.writeTo(outputStream);
        outputStream.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
    printedPdfDocument.close();
    return file;
}


private static PrintedPdfDocument bitmapToPdf(Bitmap bitmap, Context context)
{
    PrintAttributes printAttributes = new PrintAttributes.Builder()
        .setColorMode(PrintAttributes.COLOR_MODE_COLOR)
        .setMediaSize(PrintAttributes.MediaSize.ISO_A4)
        .setMinMargins(PrintAttributes.Margins.NO_MARGINS)
        .setResolution(new PrintAttributes.Resolution("1", "label", 300, 300))
        .build();
    PrintedPdfDocument printedPdfDocument = new PrintedPdfDocument(context, printAttributes);
    PdfDocument.Page pdfDocumentPage = printedPdfDocument.startPage(1);
    Canvas pdfCanvas = pdfDocumentPage.getCanvas();
    bitmap = scaleBitmapToHeight(bitmap, pdfCanvas.getHeight());
    pdfCanvas.drawBitmap(bitmap, 0f, 0f, null);
    printedPdfDocument.finishPage(pdfDocumentPage);
    return printedPdfDocument;
}

private static Bitmap webviewToBitmap(WebView webView) {
    webView.measure(
        View.MeasureSpec.makeMeasureSpec(
            0,
            View.MeasureSpec.UNSPECIFIED
        ),
        View.MeasureSpec.makeMeasureSpec(
            0,
            View.MeasureSpec.UNSPECIFIED
        )
    );
    int webViewWidth = webView.getMeasuredWidth();
    int webViewHeight = webView.getMeasuredHeight();
    webView.layout(0,0, webViewWidth, webViewHeight );
    Bitmap bitmap = Bitmap.createBitmap(webViewWidth, webViewHeight, Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmap);
    canvas.drawBitmap(bitmap, 0, bitmap.getHeight(), new Paint());
    webView.draw(canvas);
    return bitmap;
}

private static Bitmap scaleBitmapToHeight(Bitmap bitmap, int maxHeight) {
    int height = bitmap.getHeight();
    if(height > maxHeight) {
        int width = bitmap.getWidth();
        float scalePercentage = ((float)maxHeight) / height;
        return Bitmap.createScaledBitmap(bitmap, (int) (width * scalePercentage), maxHeight, false);
    }
    return bitmap;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM