工作需求,将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();
总体说一下原理就是将大bitmap通过Bitmap.createBitmap分成若干段,再将sub_bitmap转换成byte再转换成Image(itextpdf的类),调节大小至A4大小,通过document.add()加入到pdf文档中。
itextpdf还是挺厉害的,大家感兴趣可以去搜索一下相关用法,可以设置image的缩放,pdf的页边距,image旋转等。