欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android實(shí)現(xiàn)在線預(yù)覽office文檔的示例詳解

 更新時(shí)間:2025年04月23日 11:15:41   作者:Katie。  
在移動(dòng)端展示在線 Office 文檔(如 Word、Excel、PPT)是一項(xiàng)常見需求,這篇文章為大家重點(diǎn)介紹了兩種方案的實(shí)現(xiàn)方法,希望對(duì)大家有一定的幫助

一、項(xiàng)目概述

在移動(dòng)端展示在線 Office 文檔(如 Word、Excel、PPT)是一項(xiàng)常見需求。用戶點(diǎn)擊鏈接即可在 App 內(nèi)預(yù)覽,無需下載應(yīng)用或文件到本地。實(shí)現(xiàn)該功能主要有兩種思路:

WebView + 在線文檔服務(wù):利用微軟 Office Online 或 Google Docs Viewer,將文檔 URL 嵌入預(yù)覽頁面;

第三方 SDK(如騰訊 TBS/WPS):集成瀏覽器內(nèi)核或文檔 SDK,支持在本地加載遠(yuǎn)程文檔并渲染顯示。

本文重點(diǎn)介紹兩種方案的實(shí)現(xiàn)方法,并給出完整例子。

二、相關(guān)技術(shù)知識(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 初始化時(shí)預(yù)加載內(nèi)核,并在布局中添加 TbsReaderView。

3.文件訪問與權(quán)限

在線預(yù)覽不需讀寫權(quán)限;

若下載到本地后用 SDK 打開,則需申請(qǐng)存儲(chǔ)權(quán)限(Android 6.0+ 運(yùn)行時(shí)權(quán)限)。

4.性能與兼容

WebView 方案依賴外部網(wǎng)絡(luò)和服務(wù);

SDK 方案包體較大但支持離線,可自定義 UI。

三、實(shí)現(xiàn)思路

3.1 方案一:WebView + Office Online

在布局中放置一個(gè) WebView。

在 Activity 中取得文檔遠(yuǎn)程 URL,進(jìn)行 URL 編碼后拼接到 Office Online 查看地址。

配置 WebView:?jiǎn)⒂?JavaScript、DOM 存儲(chǔ)、縮放控制。

調(diào)用 webView.loadUrl(previewUrl) 即可在線預(yù)覽。

3.2 方案二:TBS SDK 離線預(yù)覽

在項(xiàng)目 build.gradle 中引入 TBS SDK 依賴。

在 Application 啟動(dòng)時(shí)初始化 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ù)覽,需要存儲(chǔ)權(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, "存儲(chǔ)權(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)限,并注冊(cè) 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 —— 同時(shí)包含 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 進(jìn)行 URL 編碼后拼接到 Office Online 查看地址;

在 WebView 中啟用 JavaScript、縮放支持及 DOM 存儲(chǔ);

直接 loadUrl() 即可,無需額外下載。

2.TBS SDK 方案

需提前在 Application 或任意時(shí)機(jī)調(diào)用 QbSdk.initX5Environment()(省略);

下載文檔到 App 私有存儲(chǔ)后,通過 TbsReaderView.preOpen() 檢測(cè)內(nèi)核支持;

調(diào)用 openFile() 加載本地文檔,支持 doc、xls、ppt、pdf 等多種格式;

在 onDestroy() 中調(diào)用 tbsView.onStop() 釋放資源。

3.權(quán)限與生命周期

運(yùn)行時(shí)申請(qǐng)寫存儲(chǔ)權(quán)限后才能保存到本地;

在 onPause()/onDestroy() 清理動(dòng)畫和 TBS 資源,避免內(nèi)存泄漏。

六、項(xiàng)目總結(jié)

WebView + Office Online:實(shí)現(xiàn)簡(jiǎn)單、無需集成第三方 SDK,依賴外部服務(wù);

TBS SDK:支持離線預(yù)覽和更多格式,但包體較大、需初始化內(nèi)核;

本文示例將兩種方案合二為一,按需選擇并切換。

七、實(shí)踐建議與未來展望

UI 優(yōu)化:增加加載進(jìn)度條、錯(cuò)誤頁面提示;

緩存策略:對(duì)已下載文件做緩存,下次直接讀??;

更多格式:結(jié)合 open-source 渲染庫(如 Apache POI + PDF 轉(zhuǎn)換)實(shí)現(xiàn)更多定制;

Compose 時(shí)代:在 Jetpack Compose 中也可直接使用 AndroidView 嵌入 WebView 或 TBS。

到此這篇關(guān)于Android實(shí)現(xiàn)在線預(yù)覽office文檔的示例詳解的文章就介紹到這了,更多相關(guān)Android在線預(yù)覽office內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論