将webview的内容转换成pdf输出

工作需求,将webview的内容导出到pdf输出


其中我们会用到itextpdf这个库,可以通过gradle添加

compile 'com.itextpdf:itextpdf:5.5.4'

首先,我们需要一个webview,加载完html并渲染成功之后我们就可以做以下的步骤。


1.生成webview的bitmap图


webview的pictureListener已经被遗弃了,所以我们需要别的方法


官方给我们的方法是新建一个bitmap,与canvas绑定,然后通过view.draw(Canvas canvas)将内容画到bitmap上


**********************************************

更新内容:getPageHeight,getPageWidth的来历


我们需要的是webview中的web页面大小 ,而不是webview在手机上显示大小


webview内部有一个protected的方法computeVerticalScrollRange和computeHorizontalScrollRange可以给我们提供


但是protected的方法没法被直接调用


所以我们必须用webview的子类调用该方法


    public int getPageHeight() {
        return computeVerticalScrollRange();
    }

    public int getPageWidth() {
        return computeHorizontalScrollRange();
    }

**********************************************


bitmap = Bitmap.createBitmap(webView.getPageWidth(), webView.getPageHeight(), Bitmap.Config.RGB_565);
        Canvas canvas = new Canvas(bitmap);
        webView.draw(canvas);

需要注意的是bitmap的大小需要设置好,用的是getPageWidth和getPageHeight而不是getWidth和getHeight


2.判断html是否需要多页pdf,多页的话到底需要多少页

我默认pdf的大小是A4大小,A4的高:宽大概是1.4142


float PDFBitmapRatio = (float) bitmap.getHeight() / (float) bitmap.getWidth();
就可以知道webview内容的比例


如果比例小于1.4142就只需要1页pdf,否则我们就要将bitmap切成小bitmap再一个个添加到pdf中


Document document = new Document(PageSize.A4, 0, 0, 0, 0);

                try {
                    PdfWriter.getInstance(document, new FileOutputStream(test
                            + "/file_name.pdf"));
                } catch (DocumentException e) {
                    e.printStackTrace();
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                }

                document.open();
                float PDFBitmapRatio = (float) bitmap.getHeight() / (float) bitmap.getWidth();
                if (PDFBitmapRatio <= 1.4) {

                    ByteArrayOutputStream stream = new ByteArrayOutputStream();
                    bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
                    byte[] byteArray = stream.toByteArray();
                    try {
                        Image image = Image.getInstance(byteArray);
                        image.scaleToFit(PageSize.A4.getWidth(), PageSize.A4.getHeight());
                        document.add(image);
                    } catch (DocumentException e) {
                        e.printStackTrace();
                    } catch (MalformedURLException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                } else {
                    float BitmapHeightPerPage = (float) bitmap.getWidth() * 1.4f;
                    int pages = (int) Math.ceil(bitmap.getHeight() / BitmapHeightPerPage);
                    System.out.println("pages:" + pages);
                    Bitmap sub_bitmap;
                    for (int i = 0; i < pages; i++) {
                        if (i == pages - 1) {
                            /**
                             * can not use default setting, or pdf reader cannot read the exported pdf
                             */
                            sub_bitmap = Bitmap.createBitmap(bitmap, 0, (int) BitmapHeightPerPage * i, bitmap.getWidth(), (int) (bitmap.getHeight() - (BitmapHeightPerPage * (pages - 1))));
                        } else {
                            sub_bitmap = Bitmap.createBitmap(bitmap, 0, (int) BitmapHeightPerPage * i, bitmap.getWidth(), (int) BitmapHeightPerPage);
                        }
                        ByteArrayOutputStream stream = new ByteArrayOutputStream();
                        sub_bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
                        byte[] byteArray = stream.toByteArray();
                        try {
                            Image image = Image.getInstance(byteArray);
                            image.scaleToFit(PageSize.A4.getWidth(), PageSize.A4.getHeight());
                            document.add(image);
                        } catch (DocumentException e) {
                            e.printStackTrace();
                        } catch (MalformedURLException e) {
                            e.printStackTrace();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                        sub_bitmap.recycle();
                    }
                }
                document.close();

其中sub_bitmap就是切割后的bitmap

总体说一下原理就是将大bitmap通过Bitmap.createBitmap分成若干段,再将sub_bitmap转换成byte再转换成Image(itextpdf的类),调节大小至A4大小,通过document.add()加入到pdf文档中。


itextpdf还是挺厉害的,大家感兴趣可以去搜索一下相关用法,可以设置image的缩放,pdf的页边距,image旋转等。




你可能感兴趣的:(android)