快速實現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核心要幾十秒才能載入完成,之後再使用,一兩秒也就載入完成了。

vivo核心載入過程.png

華為榮耀核心載入過程.png
廢話不再多說,剛才提到的第三方工具,就是封裝了X5核心的DocOpen。使用方式如下,跟別的jar引入方式一樣,在相應的model的.gradle引入
implementation 'com.redking.x5:app:+'
如圖:

jar包匯入.png
由於X5核心只有32位沒有64位,所以要支援64為手機,同時要在.gradle加入如下配置
ndk { abiFilters "armeabi", "armeabi-v7a", "x86", "mips" }
如圖:

ndk配置.png
至此,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)); } }

預覽效果.png
著作:一點愁
原創部落格轉載請註明出處……