快速实现PDF,DOC,XLS,PPT等文件预览
说起app内部浏览pdf以及办公文档,对于android来说就不像ios那么方便,直接在webview里放入相应链接即可实现app内部预览;但是面对要预览pdf,doc等文件的需求,安卓小伙伴又不可能不去实现,只因产品一句ios就能android为什么不能;然后,在不断的撕逼与妥协之下相当一部分的实现方式就是将文件下载下来调用第三方APP打开。这种跳出自家应用的体验的确不怎么好,但是面对有限的开发时间这也不失为一种解决方式。
好了,故事背景介绍完毕,下面聊一下几种解决方案;
一、服务器端解决
1、把pdf相关文档生成图片,给客户端展示;
2、应用pdf.js这个第三方工具,由服务器端提供一个html页面,实现调用pdf.js相关方法传入文件链接,即可通过客户端webview实现在线预览,当然客户端也可以把pdf.js相关内容放到本地assets里自己实现。但是实用pdf.js有个缺点就是在手机端预览时,如果手机配置高的话还是比较流畅的,否则的话绘制比较慢,还有个缺点就是如果把pdf.js放到应用本地实现,安装包会多好几兆,具体多少我也不记得了,毕竟是去年用这个东西试了下,感觉不太理想就删了。
3、其他。
二、客户端解决
1、上面说的pdf.js,也可由客户端单独完成,如果觉得合适可以试试用下。
2、使用腾讯提供的X5内核,坑还是比较多的,如果想试着自己踩(反正我不想,哈哈…),可以自己实现看看,如果不想自己踩下面我会推荐一个封装好的工具包的使用方法,简单易用。
虽说该工具直接拿来就能用,我觉得,简单介绍一下X5内核实现的逻辑还是有必要的,尽管不懂也不影响接入。下面简单说一下,app要加载pdf文件就需要先加载pdf插件,然而加载pdf插件之前需要有X5内核,所以说有了X5内核就可以顺利的预览pdf文件了。如果手机上装有qq,微信,或者qq浏览器,本地基本都会有X5内核,只要你在自己的应用内调用内核初始化代码,就可共享使用本地已有的X5内核。如果本地没有,那就只能自己下载了,大概20M多点,官方说法是90秒左右可以下载完,我试了下快的话30秒左右也能下载完,具体还是看网速。
3、其他。
如下图,我拿两个手机试了下,从图中可以看出,第一次使用,如果没有X5内核要几十秒才能加载完成,之后再使用,一两秒也就加载完成了。


废话不再多说,刚才提到的第三方工具,就是封装了X5内核的DocOpen。使用方式如下,跟别的jar引入方式一样,在相应的model的.gradle引入
implementation 'com.redking.x5:app:+'
如图:

由于X5内核只有32位没有64位,所以要支持64为手机,同时要在.gradle加入如下配置
ndk {
abiFilters "armeabi", "armeabi-v7a", "x86", "mips"
}
如图:

至此,jar导入以及相关配置完成,下面看代码实现,主要功能该jar包已经实现,包括文件下载,进度显示以及下载完成后渲染pdf文件。我们只需要做下面两件事:
第一,初始化X5内核,直接在首页Activity调用初始化代码,如下
InitX5.initX5(this);
第二,把jar包里的DocOpenFragment放入我们自己的Activity或者Fragment,实现自己的顶栏样式即可。代码如下
布局文件red_act_doc_demo.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:id="@+id/rl_title"
android:layout_width="match_parent"
android:layout_height="50dip"
android:background="#0894EC"
android:orientation="horizontal">
<TextView
android:id="@+id/tv_close"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:paddingLeft="15dip"
android:paddingRight="20dip"
android:textColor="#ffffff"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:gravity="center"
android:textSize="18sp"
android:text="关闭"/>
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@+id/tv_close"
android:textColor="#ffffff"
android:layout_centerInParent="true"
android:singleLine="true"
android:gravity="center"
android:textSize="18sp"/>
</RelativeLayout>
<RelativeLayout
android:id="@+id/ll_doc_frag"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/rl_title">
</RelativeLayout>
</RelativeLayout>
页面代码DocOpenDemoActivity.java:
/**
*
* 声明:该DocOpenDemoActivity 只是使用方式演示,要实现自己的页面应该写自己的activity嵌入DocOpenFragment
*
* 1、app的首页Activity调用Init.initX5(this);提前加载好内核,如果没有内核第一次大概需要90秒
*
* 2、按照DocOpenDemoActivity方式把DocOpenFragment 放入activity
*
* 3、通过docOpenFragment.setFilePath(fileUrl)设置文件路径(可以是本地路径,也可以是网络下载地址),在beginTransaction.commit();之前调用
*
*/
public class DocOpenDemoActivity extends Activity{
FragmentManager fragmentManager;
FragmentTransaction beginTransaction;
DocOpenFragment docOpenFragment;
StringfileUrl="http://sources.ikeepstudying.com/jquery.media/guice.pdf";
private TextView tvTitle;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.red_act_doc_demo);
initView();
initData();
}
private void initView(){
tvTitle = (TextView) findViewById(R.id.tv_title);
}
private void initData(){
if(getIntent().getStringExtra("fileUrl") != null && getIntent().getStringExtra("fileUrl") != "" )
fileUrl = getIntent().getStringExtra("fileUrl");
fragmentManager = getFragmentManager();
beginTransaction = fragmentManager.beginTransaction();
docOpenFragment = new DocOpenFragment();
//设置文件路径
docOpenFragment.setFilePath(fileUrl);
beginTransaction.add(R.id.ll_doc_frag, docOpenFragment);
beginTransaction.commit();
tvTitle.setText(docOpenFragment.getFileName(this));
}
}

著作:一点愁
原创博客转载请注明出处……