我一直无法在 Android 上打印 PDF。我想要做的是在 WebView 中呈现一些 HTML,然后在 PDF Canvas 上绘制 WebView 内容,最后将 PDF 写入文件。我遇到的问题是,当我绘制到 PDF Canvas 时,即使还有很多 Canvas ,内容也会被剪裁。我已经尝试使用 .clipRect(Rect rect, Op op) 调整 Canvas 的大小,这种方法很有效,但效果不如我所愿。
我也不知道如何将 HTML px 测量值可靠地转换为 PDF PostScript 1/72 英寸测量值。
这是我使用的代码:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
WebView wv = (WebView) this.findViewById(R.id.webView1);
wv.loadUrl("file:///android_asset/temp.html");
}
public void button1onClick(View v)
{
//Create PDF document
PdfDocument doc = new PdfDocument();
//Create A4 sized PDF page
PageInfo pageInfo = new PageInfo.Builder(595,842,1).create();
Page page = doc.startPage(pageInfo);
WebView wv = (WebView) this.findViewById(R.id.webView1);
page.getCanvas().setDensity(200);
//Draw the webview to the canvas
wv.draw(page.getCanvas());
doc.finishPage(page);
try
{
//Create the PDF file
File root = Environment.getExternalStorageDirectory();
File file = new File(root,"webview.pdf");
FileOutputStream out = new FileOutputStream(file);
doc.writeTo(out);
out.close();
doc.close();
//Open the PDF
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(file), "application/pdf");
intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(intent);
}
catch(Exception e)
{
throw new RuntimeException("Error generating file", e);
}
}
基本上,该程序只是将 temp.html 文件加载到 webview 并呈现一个按钮,我可以使用它来创建 PDF。
temp.html 文件如下所示:
<html>
<head>
<style>
div.border
{
width:600px;
height:800px;
border:1px solid black;
}
</style>
</head>
<body>
<div class="border"></div>
</body>
这是手动添加黑色边框以显示比例的结果:
我非常感谢一些关于如何在 Android 上可靠地将 HTML 转换为 PDF 而无需使用需要商业用途许可的库的提示。
最佳答案
总结: 不要修改密度(它应该在您的设备上设置,可能设置为中等 160 dpi),而是使用比例。 如果您只需要 PDF 中 HTML 页面的位图(无超链接功能),这就可以了。 这是您的代码使用以下代码生成的内容:
//Create PDF document
PdfDocument doc = new PdfDocument();
//Create A4 sized PDF page
int my_width = 595;
int my_height = 842;
PageInfo pageInfo = new PageInfo.Builder(my_width,my_height,1).create();
// PageInfo pageInfo = new PageInfo.Builder(650,850,1).create();
Page page = doc.startPage(pageInfo);
WebView wv = (WebView) this.findViewById(R.id.webView1);
Canvas canvas = page.getCanvas();
WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
final DisplayMetrics displayMetrics = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(displayMetrics);
int height = displayMetrics.heightPixels;
int width = displayMetrics.widthPixels;
float density = displayMetrics.density;
int wvWidth = wv.getWidth();
int wvHeight= wv.getHeight();
float wvScaleX= wv.getScaleX();
float wvScaleY= wv.getScaleY();
// canvas.setDensity(100);//200 Bitmap.DENSITY_NONE
int cdensity = canvas.getDensity();
float scaleWidth = (float)width/(float)my_width;
float scaleHeight = (float)height/(float)my_height;
canvas.scale(scaleWidth, scaleHeight);
Log.e("button1onClick","canvas width:" + canvas.getHeight() + " canvas height:" + canvas.getWidth());
Log.e("button1onClick","metrics width:" + width + " metrics height:" + height + "metrics density:" + density);
Log.e("button1onClick"," wvWidth:" + wvWidth + " wvHeight:" + wvHeight);
Log.e("button1onClick"," scaleWidth: " + scaleWidth +
" scaleHeight:" + scaleHeight +" cdensity:" + cdensity);
Paint paint = new Paint();
// paint.setStyle(Style.FILL);
paint.setColor(Color.RED);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(1);
//Draw the webview to the canvas
wv.draw(canvas);
canvas.scale(1f, 1f);
canvas.drawRect(0, 0, canvas.getWidth()-1, canvas.getHeight()-1, paint);
canvas.drawText("Direct drawn Red Rectangle to fill page canvas 0, 0," +
canvas.getWidth() + "," + canvas.getHeight(), 100, 100, paint);
doc.finishPage(page);
关于Android - 从 WebView 绘制到 PDF Canvas ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26828329/
最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路
我正在寻找一种简单的方法来绘制大约10个点和矩形,以便能够查看我的算法哪里出了问题。我查看了gnuplot,但似乎绘制矩形特别糟糕。 最佳答案 SVG(MDNTutorial)是一种非常简单的基于文本(XML)的格式,您可以使用Ruby轻松生成它,而无需任何SVG库,并可以在任何现代Web浏览器中查看。这是一个示例:通过字符串插值的SVG点points=(0..5).map{[rand(100)-50,rand(100)-50]}puts#{points.map{|x,y|""}.join("\n")}ENDSVG输出:http:/
运行有问题或需要源码请点赞关注收藏后评论区留言一、利用ContentResolver读写联系人在实际开发中,普通App很少会开放数据接口给其他应用访问。内容组件能够派上用场的情况往往是App想要访问系统应用的通讯数据,比如查看联系人,短信,通话记录等等,以及对这些通讯数据及逆行增删改查。首先要给AndroidMaifest.xml中添加响应的权限配置 下面是往手机通讯录添加联系人信息的例子效果如下分成三个步骤先查出联系人的基本信息,然后查询联系人号码,再查询联系人邮箱代码 ContactAddActivity类packagecom.example.chapter07;importandroid
1.前言 在10.0的系统rom定制化开发中,在系统中有多个launcher的时候,会在开机进入launcher的时候弹窗launcher列表,让用户选择进入哪个launcher,这样显得特别的不方便所以产品开发中,要求用RoleManager的相关api来设置默认Launcher,但是在设置完默认Launcher以后,在安装一款Launcher的时候,默认Launcher就会失效,在系统设置的默认应用中Launcher选项就为空,点击home键的时候会弹出默认Launcher列表,让选择进入哪个默认Launcher.所以需要从安装Launcher的流程来分析相关的设置。来解决问题设置默认La
Ai-Bot基于流行的Node.js和JavaScript语言的一款新自动化框架,支持Windows和Android自动化。1、Windowsxpath元素定位算法支持支持Windows应用、.NET、WPF、Qt、Java和Electron客户端程序和ie、edgechrome浏览器2、Android支持原生APP和H5界面,元素定位速度是appium十倍,无线远程自动化操作多台安卓设备3、基于opencv图色算法,支持找图和多点找色,1080*2340全分辨率找图50MS以内4、内置免费OCR人工智能技术,无限制获取图片文字和找字功能。5、框架协议开源,除官方node.jsSDK外,用户可
前一段时间由于工作需要把可爱的小雪狐舍弃了,找到了小蜜蜂。但是新版本的小蜜蜂出现了很多和旧版本不一样的位置。1.功能位置迁移,原来在工程build.gradle的buildscript和allprojects移动至setting.gradle并改名为pluginManagement和dependencyResolutionManagement。里面的东西依旧可以按照原来的copy过来。pluginManagement{repositories{gradlePluginPortal()google()mavenCentral()}}dependencyResolutionManagement{r
关闭。这个问题不符合StackOverflowguidelines.它目前不接受答案。要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于StackOverflow来说是偏离主题的,因为它们往往会吸引自以为是的答案和垃圾邮件。相反,describetheproblem以及迄今为止为解决该问题所做的工作。关闭9年前。Improvethisquestion我几乎用完了Ruby,但现在想试试Ruboto,android上的ruby。谷歌未能给我足够的(几乎没有结果)。所以任何人都可以分享一些关于Ruboto的教程。
微信小程序webview中使用cover-view展示分享弹窗公司业务需要在webview中添加分享弹窗,可以发送给朋友及生成海报分享,因为好几个详情都需要这个功能,因此抽离了share-sheet的组件,ui效果如下图:点击分享,显示以下弹窗share-sheet.wxml如下:{!show}}"catchtouchmove="poptouchmove">发送给朋友生成海报取消share-sheet.js如下:Component({options:{addGlobalClass:true,},/***组件的属性列表*/properties:{//控制弹窗显示与否show:{type:Bool
Aproblemoccurredconfiguringrootproject'MyApplication2'.>Couldnotresolveallfilesforconfiguration':classpath'. >Couldnotresolvecom.android.tools.build:gradle:7.4.2. Requiredby: project:>com.android.application:com.android.application.gradle.plugin:7.4.2 project:>com.android.library:com.andr
简介:我们都知道在Android开发中,当我们的程序在与用户交互时,用户会得到一定的反馈,其中以对话框的形式的反馈还是比较常见的,接下来我们来介绍几种常见的对话框的基本使用。前置准备:(文章最后附有所有代码)我们首先先写一个简单的页面用于测试这几种Dialog(对话框)代码如下,比较简单,就不做解释了一、提示对话框(即最普通的对话框)首先我们给普通对话框的按钮设置一个点击事件,然后通过AlertDialog.Builder来构造一个对象,为什么不直接Dialog一个对象,是因为Dialog是一个基类,我们尽量要使用它的子类来进行实例化对象,在实例化对象的时候,需要将当前的上下文传过去,因为我这