Android實現(xiàn)在線預(yù)覽office文檔的示例詳解
一、項目概述
在移動端展示在線 Office 文檔(如 Word、Excel、PPT)是一項常見需求。用戶點擊鏈接即可在 App 內(nèi)預(yù)覽,無需下載應(yīng)用或文件到本地。實現(xiàn)該功能主要有兩種思路:
WebView + 在線文檔服務(wù):利用微軟 Office Online 或 Google Docs Viewer,將文檔 URL 嵌入預(yù)覽頁面;
第三方 SDK(如騰訊 TBS/WPS):集成瀏覽器內(nèi)核或文檔 SDK,支持在本地加載遠程文檔并渲染顯示。
本文重點介紹兩種方案的實現(xiàn)方法,并給出完整例子。
二、相關(guān)技術(shù)知識
1.WebView 加載在線預(yù)覽
Office Online URL 模板:
https://view.officeapps.live.com/op/view.aspx?src=<URL_ENCODED_DOC_URL>
Google Docs Viewer:
https://docs.google.com/gview?embedded=true&url=<URL_ENCODED_DOC_URL>
WebView 配置:開啟 JavaScript、支持縮放、調(diào)整緩存策略等。
2.騰訊 TBS SDK(X5 內(nèi)核)
TBS 提供的 TbsReaderView 可加載 doc/docx/xls/ppt/pdf 等格式。
需在 App 初始化時預(yù)加載內(nèi)核,并在布局中添加 TbsReaderView。
3.文件訪問與權(quán)限
在線預(yù)覽不需讀寫權(quán)限;
若下載到本地后用 SDK 打開,則需申請存儲權(quán)限(Android 6.0+ 運行時權(quán)限)。
4.性能與兼容
WebView 方案依賴外部網(wǎng)絡(luò)和服務(wù);
SDK 方案包體較大但支持離線,可自定義 UI。
三、實現(xiàn)思路
3.1 方案一:WebView + Office Online
在布局中放置一個 WebView。
在 Activity 中取得文檔遠程 URL,進行 URL 編碼后拼接到 Office Online 查看地址。
配置 WebView:啟用 JavaScript、DOM 存儲、縮放控制。
調(diào)用 webView.loadUrl(previewUrl) 即可在線預(yù)覽。
3.2 方案二:TBS SDK 離線預(yù)覽
在項目 build.gradle 中引入 TBS SDK 依賴。
在 Application 啟動時初始化 X5:調(diào)用 QbSdk.initX5Environment(...)。
在布局中添加 TbsReaderView。
在 Activity 中下載或緩存文檔到本地,然后調(diào)用 tbsView.openFile(bundle, null) 加載預(yù)覽。
記得在 onDestroy() 中銷毀 TbsReaderView。
四、整合代碼
4.1 Java 代碼(MainActivity.java)
package com.example.officedocpreview;
import android.Manifest;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.*;
import android.view.View;
import android.webkit.*;
import android.widget.*;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import com.tencent.smtt.sdk.TbsReaderView;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
public class MainActivity extends AppCompatActivity {
private static final int REQ_STORAGE = 1001;
private WebView webView;
private TbsReaderView tbsView;
private FrameLayout container;
private String remoteDocUrl = "https://example.com/test.docx";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
webView = findViewById(R.id.web_view);
tbsView = findViewById(R.id.tbs_view);
container = findViewById(R.id.tbs_container);
findViewById(R.id.btn_web_preview).setOnClickListener(v -> previewWithWeb());
findViewById(R.id.btn_tbs_preview).setOnClickListener(v -> previewWithTbs());
}
/** 方案一:WebView + Office Online */
private void previewWithWeb() {
webView.setVisibility(View.VISIBLE);
container.setVisibility(View.GONE);
WebSettings ws = webView.getSettings();
ws.setJavaScriptEnabled(true);
ws.setBuiltInZoomControls(true);
ws.setDisplayZoomControls(false);
ws.setDomStorageEnabled(true);
String urlEncoded = Uri.encode(remoteDocUrl);
String previewUrl = "https://view.officeapps.live.com/op/view.aspx?src=" + urlEncoded;
webView.loadUrl(previewUrl);
}
/** 方案二:TBS SDK 預(yù)覽,需要存儲權(quán)限 */
private void previewWithTbs() {
webView.setVisibility(View.GONE);
container.setVisibility(View.VISIBLE);
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQ_STORAGE);
} else {
downloadAndOpenWithTbs(remoteDocUrl);
}
}
@Override
public void onRequestPermissionsResult(int req,
@NonNull String[] perms, @NonNull int[] grantResults) {
if (req == REQ_STORAGE && grantResults.length>0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
downloadAndOpenWithTbs(remoteDocUrl);
} else {
Toast.makeText(this, "存儲權(quán)限被拒絕", Toast.LENGTH_SHORT).show();
}
}
/** 下載到本地后用 TbsReaderView 打開 */
private void downloadAndOpenWithTbs(String urlStr) {
new Thread(() -> {
try {
URL url = new URL(urlStr);
HttpURLConnection conn =
(HttpURLConnection) url.openConnection();
conn.connect();
InputStream is = conn.getInputStream();
File file = new File(getExternalFilesDir(null), "temp.docx");
FileOutputStream fos = new FileOutputStream(file);
byte[] buf = new byte[4096];
int len;
while ((len = is.read(buf))>0) fos.write(buf,0,len);
fos.close();
is.close();
runOnUiThread(() -> openFileInTbs(file.getAbsolutePath()));
} catch (Exception e) {
e.printStackTrace();
runOnUiThread(() ->
Toast.makeText(this, "下載失敗", Toast.LENGTH_SHORT).show());
}
}).start();
}
private void openFileInTbs(String filePath) {
Bundle params = new Bundle();
params.putString(TbsReaderView.KEY_FILE_PATH, filePath);
params.putString(TbsReaderView.KEY_TEMP_PATH,
getExternalFilesDir(null).getPath());
boolean ok = tbsView.preOpen(getFileType(filePath), false);
if (ok) {
tbsView.openFile(params);
} else {
Toast.makeText(this, "TBS 內(nèi)核未加載或不支持", Toast.LENGTH_SHORT).show();
}
}
private String getFileType(String path) {
if (path == null || !path.contains(".")) return "";
return path.substring(path.lastIndexOf('.') + 1);
}
@Override
protected void onDestroy() {
super.onDestroy();
tbsView.onStop();
}
}4.2 XML 布局與 Manifest
<!-- AndroidManifest.xml —— 聲明 INTERNET 與讀寫權(quán)限,并注冊 TbsReaderView 權(quán)限 -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.officedocpreview">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application
android:allowBackup="true"
android:label="OfficePreview"
android:icon="@mipmap/ic_launcher"
android:theme="@style/Theme.AppCompat.Light.NoActionBar">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>
???????<!-- activity_main.xml —— 同時包含 WebView 與 TbsReaderView -->
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- WebView 方式預(yù)覽 -->
<WebView
android:id="@+id/web_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"/>
<!-- TBS SDK 方式預(yù)覽 -->
<FrameLayout
android:id="@+id/tbs_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone">
<com.tencent.smtt.sdk.TbsReaderView
android:id="@+id/tbs_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</FrameLayout>
<!-- 底部按鈕 -->
<LinearLayout
android:layout_gravity="bottom|center_horizontal"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="16dp">
<Button
android:id="@+id/btn_web_preview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Web 預(yù)覽"/>
<Button
android:id="@+id/btn_tbs_preview"
android:layout_marginStart="16dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TBS 預(yù)覽"/>
</LinearLayout>
</FrameLayout>五、代碼解讀
1.WebView 方案
將文檔 URL 進行 URL 編碼后拼接到 Office Online 查看地址;
在 WebView 中啟用 JavaScript、縮放支持及 DOM 存儲;
直接 loadUrl() 即可,無需額外下載。
2.TBS SDK 方案
需提前在 Application 或任意時機調(diào)用 QbSdk.initX5Environment()(省略);
下載文檔到 App 私有存儲后,通過 TbsReaderView.preOpen() 檢測內(nèi)核支持;
調(diào)用 openFile() 加載本地文檔,支持 doc、xls、ppt、pdf 等多種格式;
在 onDestroy() 中調(diào)用 tbsView.onStop() 釋放資源。
3.權(quán)限與生命周期
運行時申請寫存儲權(quán)限后才能保存到本地;
在 onPause()/onDestroy() 清理動畫和 TBS 資源,避免內(nèi)存泄漏。
六、項目總結(jié)
WebView + Office Online:實現(xiàn)簡單、無需集成第三方 SDK,依賴外部服務(wù);
TBS SDK:支持離線預(yù)覽和更多格式,但包體較大、需初始化內(nèi)核;
本文示例將兩種方案合二為一,按需選擇并切換。
七、實踐建議與未來展望
UI 優(yōu)化:增加加載進度條、錯誤頁面提示;
緩存策略:對已下載文件做緩存,下次直接讀??;
更多格式:結(jié)合 open-source 渲染庫(如 Apache POI + PDF 轉(zhuǎn)換)實現(xiàn)更多定制;
Compose 時代:在 Jetpack Compose 中也可直接使用 AndroidView 嵌入 WebView 或 TBS。
到此這篇關(guān)于Android實現(xiàn)在線預(yù)覽office文檔的示例詳解的文章就介紹到這了,更多相關(guān)Android在線預(yù)覽office內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Android 實現(xiàn)當(dāng)下最流行的吸頂效果
本文主要介紹了Android 實現(xiàn)當(dāng)下最流行的吸頂效果的示例代碼。具有很好的參考價值,下面跟著小編一起來看下吧2017-03-03
詳解Android中Runtime解決屏幕旋轉(zhuǎn)問題(推薦)
這篇文章主要介紹了Runtime解決屏幕旋轉(zhuǎn)問題的方法,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2016-09-09
Android開發(fā)實現(xiàn)的導(dǎo)出數(shù)據(jù)庫到Excel表格功能【附源碼下載】
這篇文章主要介紹了Android開發(fā)實現(xiàn)的導(dǎo)出數(shù)據(jù)庫到Excel表格功能,涉及Android數(shù)據(jù)庫及Excel表格相關(guān)操作技巧,并附帶完整源碼供讀者下載參考,需要的朋友可以參考下2018-03-03
android nfc常用標(biāo)簽讀取總結(jié)
NFC(Near Field Communication,近場通信)是一種數(shù)據(jù)傳輸技術(shù)這篇文章主要介紹了android nfc常用標(biāo)簽讀取總結(jié),有興趣的可以了解一下。2016-12-12
Jetpack?Compose實現(xiàn)點擊事件click的多種方法
這篇文章主要介紹了Jetpack?Compose實現(xiàn)點擊事件的多種方法,Jetpack?Compose是一款基于Kotlin的聲明式UI工具包,可以方便地創(chuàng)建漂亮的用戶界面,下面我們就來看看Jetpack?Compose添加點擊事件都可以怎么實現(xiàn)2024-02-02
Android使用自定義View實現(xiàn)橫行時間軸效果
這篇文章主要給大家介紹了關(guān)于Android使用自定義View實現(xiàn)橫行時間軸效果的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家學(xué)習(xí)或者使用Android具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-12-12
Android Dialog 設(shè)置字體大小的具體方法
這篇文章介紹了Android Dialog 設(shè)置字體大小的具體方法,希望能幫助到有同樣需求的朋友,可能我的方法不是最好的,也希望有朋友指點2013-09-09
Android實現(xiàn)移動小球和CircularReveal頁面切換動畫實例代碼
這篇文章主要給大家介紹了關(guān)于利用Android如何實現(xiàn)移動的小球和CircularReveal頁面切換動畫的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對各位Android開發(fā)者們具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起看看吧。2017-09-09

