首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

Android WebView 實現線上 PDF 預覽方案(不調用第三方、不依賴 Google Docs)

     編輯:程式設計疑難解答

方案對比

方案原理優點缺點推薦度
Google Docs Vieweriframe 嵌入 https://docs.google.com/gview?embedded=true&url=...零成本、支持多格式國內無法訪問、隱私風險、限流❌ 不可用
Mozilla PDF.jsWebView 加載本地/服務端部署的 PDF.js 查看器純前端、開源、無依賴、功能全需部署靜態資源、大文件加載慢⭐⭐⭐⭐⭐ 首選
Android PdfRenderer API原生渲染 PDF 頁面為 Bitmap,自定義 View 顯示性能最好、系統級、無第三方庫API 21+、需手寫 UI(縮放/翻頁/選中)⭐⭐⭐⭐ 原生首選
第三方 SDK (MuPDF/PDFium)集成 C++ 渲染庫經 JNI 調用功能強、商業級支持體積大、授權費用、集成複雜⭐⭐⭐ 企業級

方案一:WebView + PDF.js(推薦通用方案)

步驟 1:獲取 PDF.js

  • 下載:GitHub Releases (預構建版 pdfjs--dist.zip)
  • 解壓得到 build/ (核心) 和 web/ (查看器 UI) 目錄。

步驟 2:放入 Android 項目

app/src/main/assets/
├── pdfjs/
│   ├── build/
│   │   ├── pdf.js
│   │   ├── pdf.worker.js
│   │   └── ...
│   └── web/
│       ├── viewer.html
│       ├── viewer.css
│       ├── viewer.js
│       ├── locale/zh-CN/  (可選:中文語言包)
│       └── images/

步驟 3:修改 viewer.html 支持動態 URL

<!-- viewer.html 關鍵修改 -->
<script>
  // 接收 Android 傳遞的 PDF URL
  var pdfUrl = decodeURIComponent(location.search.substring(1).split('url=')[1]);
  if (pdfUrl) {
      PDFViewerApplication.open(pdfUrl);
  }
</script>

步驟 4:WebView 加載代碼

WebView webView = findViewById(R.id.webView);
WebSettings settings = webView.getSettings();
settings.setJavaScriptEnabled(true);
settings.setAllowFileAccess(true);
settings.setAllowContentAccess(true);
settings.setDomStorageEnabled(true);
// 關鍵:允許 file:// 協議加載本地 assets 中的 js/css
settings.setAllowFileAccessFromFileURLs(true);
settings.setUniversalAccessFromFileURLs(true);

String pdfUrl = "https://example.com/document.pdf"; // 你的 PDF 鏈接
String viewerUrl = "file:///android_asset/pdfjs/web/viewer.html?url=" + URLEncoder.encode(pdfUrl, "UTF-8");
webView.loadUrl(viewerUrl);

步驟 5:處理大文件/權限/下載

webView.setWebViewClient(new WebViewClient() {
    @Override
    public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
        String url = request.getUrl().toString();
        if (url.endsWith(".pdf")) {
            // 攔截 PDF 直接在當前 WebView 打開
            String newUrl = "file:///android_asset/pdfjs/web/viewer.html?url=" + URLEncoder.encode(url, "UTF-8");
            view.loadUrl(newUrl);
            return true;
        }
        return super.shouldOverrideUrlLoading(view, request);
    }
    
    @Override
    public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
        // 處理加載失敗:網絡錯誤、跨域、文件不存在等
    }
});

// 長按下載/另存為
webView.setOnLongClickListener(v -> {
    WebView.HitTestResult result = webView.getHitTestResult();
    if (result.getType() == WebView.HitTestResult.SRC_ANCHOR_TYPE) {
        String url = result.getExtra();
        // 啟動下載服務或彈出菜單
    }
    return false;
});

方案二:Android PdfRenderer (API 21+,原生高性能)

// 核心渲染邏輯
PdfRenderer renderer = new PdfRenderer(ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY));
int pageCount = renderer.getPageCount();

for (int i = 0; i < pageCount; i++) {
    PdfRenderer.Page page = renderer.openPage(i);
    Bitmap bitmap = Bitmap.createBitmap(pageWidth, pageHeight, Bitmap.Config.ARGB_8888);
    page.render(bitmap, null, null, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY);
    // 將 bitmap 顯示在 ImageView/RecyclerView 中
    page.close();
}
renderer.close();
  • 優勢:流暢度最好、內存可控、支持密文 PDF(需密碼)。
  • 缺點:需自行實現縮雙指縮放、頁面切換、文本選中、目錄導航等 UI 交互。
  • 開源封裝庫:AndroidPdfViewer (基於 PdfRenderer 封裝完整 UI)。

方案三:Mozilla PDF.js 服務端部署(解決大文件/離線)

  1. 將 PDF.js 部署到你的服務器 (Nginx/Apache 靜態托管)。
  2. App 中 WebView 加載 https://yourdomain.com/pdfjs/web/viewer.html?url=...。
  3. 優勢:App 體積小、PDF.js 可獨立升級、支持 CDN 加速。

關鍵問題解決

問題解決方案
跨域 (CORS) 導致 PDF 無法加載服務端配置 Access-Control-Allow-Origin: *;或 App 端下載 PDF 到本地文件,再用 file:// 協議加載
大文件 (>50MB) 加載極慢/崩潰使用 PdfRenderer 分頁渲染;或服務端預生成縮略圖/分頁圖片
加密 PDF 無法打開PDF.js 支持輸入密碼回調;PdfRenderer 需 openPage(password)
WebView 白屏/JS 報錯啟用 setWebContentsDebuggingEnabled(true) 調試;檢查 assets 路徑、JS 語法錯誤

總結建議

  • 通用項目、快速集成:WebView + 本地 PDF.js (assets 部署),功能完整、無原生開發成本。
  • 高性能、原生體驗、API 21+:PdfRenderer + AndroidPdfViewer 庫。
  • 企業級、加密、批註、簽名:考慮商業 SDK (Foxit、PDFTron、MuPDF 商業版)。
  • 完全離線、無服務端:PDF.js assets 方案最佳。

參考資源

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved