最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

uni-app安卓端純前端預覽DOCX的實現(xiàn)思路及代碼實例

 更新時間:2026年05月14日 11:02:41   作者:Amy_yang  
在移動應用開發(fā)中,文件預覽功能幾乎成為標配需,這篇文章主要介紹了uni-app安卓端純前端預覽DOCX的實現(xiàn)思路及代碼實例的相關資料,文中通過代碼介紹的非常詳細,需要的朋友可以參考下

前言

在 uni-app 項目中,docx 文件預覽看起來像是一個簡單需求,但在安卓 App 環(huán)境下會遇到不少坑。

本文結(jié)合當前項目的實現(xiàn),說明為什么不能直接在頁面中渲染 docx,以及如何通過 docx-preview + 本地 web-view 實現(xiàn)純前端預覽。

一、DOCX 為什么可以純前端預覽

docx 本質(zhì)上不是傳統(tǒng)二進制文件,而是一個壓縮包。

它內(nèi)部主要包含:

  • XML 文檔內(nèi)容
  • 樣式文件
  • 圖片資源
  • 字體、編號、頁眉頁腳等配置

所以前端可以通過 JS 解壓并解析這些 XML,再渲染成 HTML。

常見純前端庫有:

  • docx-preview
  • mammoth.js

其中:

  • docx-preview 更偏向“還原 Word 頁面效果”
  • mammoth.js 更偏向“提取正文內(nèi)容”

如果目標是“預覽文檔”,更推薦使用 docx-preview。

二、為什么 DOC 不能一樣處理

doc 是老版本 Word 二進制格式,不是 zip + XML 結(jié)構(gòu)。

瀏覽器端沒有成熟穩(wěn)定的純 JS 方案可以完整解析 .doc 文件。

所以:

docx -> 可以嘗試純前端預覽
doc  -> 不建議純前端預覽

對于 .doc,更推薦:

  • 后端轉(zhuǎn) PDF
  • 調(diào)用系統(tǒng)應用打開
  • 使用文檔服務或原生插件

三、為什么不能直接在 uni-app 頁面里渲染

一開始最容易想到的寫法是:

import { renderAsync } from 'docx-preview';

const renderDocx = async () => {
  const bodyEl = document.getElementById('docxBodyBox');

  await renderAsync(buffer, bodyEl);
};

在 H5 里這通常沒問題。

但在 uni-app 安卓 App 端,普通頁面里的 <script setup> 并不是穩(wěn)定的瀏覽器 DOM 執(zhí)行環(huán)境。

常見問題包括:

  • document 不存在
  • document.getElementById() 找不到容器
  • DOM 已渲染但原生層還沒準備好
  • 文件讀取能力和瀏覽器 H5 不一致

因此,直接在 filePreview.vue 里使用 docx-preview,在安卓 App 端并不可靠。

四、最終方案:本地 HTML + web-view

更穩(wěn)的方案是:

uni-app 頁面
-> web-view 打開本地 viewer.html
-> viewer.html 加載 docx-preview
-> viewer.html 下載或讀取 docx 文件
-> docx-preview 渲染 HTML

也就是說,把 docx-preview 放到真正的 WebView 頁面里執(zhí)行。

項目結(jié)構(gòu)示例:

static/docx-preview/
├── viewer.html
├── docx-preview.min.js
└── jszip.min.js

其中:

  • viewer.html 是本地預覽頁面
  • docx-preview.min.js 是預覽庫
  • jszip.min.js 是 docx 解壓依賴

五、App 頁面如何打開 DOCX 預覽

filePreview.vue 中,docx 文件走單獨分支:

<view v-else-if="isDocxFile" class="docx-preview-container">
  <!-- #ifdef APP-PLUS -->
  <view v-if="docxRendering" class="preview-loading">
    <view class="loading-spinner"></view>
    <text class="loading-text">文檔下載中...</text>
  </view>
  <view v-else-if="docxRenderError" class="preview-error">
    <text class="error-text">{{ docxRenderError }}</text>
    <view class="retry-btn" @click="prepareAppDocxPreview">重新加載</view>
    <view class="retry-btn secondary" @click="previewWithSystemViewer">
      系統(tǒng)應用打開
    </view>
  </view>
  <view v-else class="app-native-preview">
    <web-view
      :src="getDocxViewerUrl"
      class="docx-webview"
      :fullscreen="false"
      style="width: 100%; height: 100%; border: 0"
      :webview-styles="{
        width: '100%',
        height: '100%',
        progress: { color: '#16a5fb' }
      }"
    ></web-view>
  </view>
  <!-- #endif -->
</view>

預覽地址:

const getDocxViewerUrl = computed(() => {
  const previewUrl = docxLocalPath.value || fileInfo.value.url;
  if (!previewUrl) return '';
  return `/static/docx-preview/viewer.html?file=${encodeURIComponent(previewUrl)}`;
});

六、為什么要先用 uni.downloadFile 下載

一開始可以讓 viewer.html 自己下載遠程 docx

fetch(fileUrl)

或:

plus.downloader.createDownload(fileUrl)

但在真實項目中經(jīng)常會失?。?/p>

  • 文件地址需要登錄態(tài)
  • 下載接口需要 token
  • 本地 HTML 不一定能拿到業(yè)務請求頭
  • 遠程文件可能有跨域限制
  • plus.downloader 在 web-view 內(nèi)部回調(diào)不穩(wěn)定

所以更穩(wěn)的方式是:

filePreview.vue 用 uni.downloadFile 下載
-> 帶上 token
-> 拿到 tempFilePath
-> 傳給 viewer.html

代碼示例:

const prepareAppDocxPreview = () => {
  docxLocalPath.value = '';
  docxRenderError.value = '';
  docxRendering.value = true;

  uni.downloadFile({
    url: fileInfo.value.url,
    header: {
      token: uni.getStorageSync('token') || ''
    },
    success: (res) => {
      docxRendering.value = false;

      if (res.statusCode !== 200 || !res.tempFilePath) {
        docxRenderError.value = `文檔下載失敗: ${res.statusCode || '未知錯誤'}`;
        return;
      }

      try {
        docxLocalPath.value =
          plus.io.convertLocalFileSystemURL(res.tempFilePath) ||
          res.tempFilePath;
      } catch (error) {
        docxLocalPath.value = res.tempFilePath;
      }
    },
    fail: () => {
      docxRendering.value = false;
      docxRenderError.value = '文檔下載失敗,請檢查文件地址或權(quán)限';
    }
  });
};

七、viewer.html 如何渲染 DOCX

viewer.html 需要先加載依賴:

<script src="./jszip.min.js"></script>
<script src="./docx-preview.min.js"></script>

然后讀取文件并渲染:

await window.docx.renderAsync(
  buffer,
  document.getElementById('docxBodyBox'),
  document.getElementById('docxStyleBox'),
  {
    className: 'docx-rendered',
    inWrapper: true,
    ignoreWidth: false,
    ignoreHeight: false,
    ignoreFonts: false,
    breakPages: true,
    experimental: false,
    useBase64URL: true
  }
);

八、本地文件讀取的坑

安卓 App 端下載后的路徑可能是:

_doc/uniapp_temp_xxx/download/xxx.docx

也可能被轉(zhuǎn)換成:

/storage/emulated/0/Android/data/xxx/xxx.docx

這些路徑不是標準瀏覽器 URL。

常見坑包括:

1. FileReader 不能讀取 plus.io 的 File 對象

錯誤示例:

Failed to execute 'readAsArrayBuffer' on 'FileReader':
parameter 1 is not of type 'Blob'

原因是 Android WebView 里的 plus.io File 對象不一定是標準 Blob。

2. XHR 不能直接讀取_doc/...

錯誤示例:

read local file failed

原因是 _doc/... 是 5+ 私有路徑,不是普通瀏覽器可直接訪問路徑。

3. 需要多路徑兜底

所以讀取本地文件時,需要嘗試多種路徑:

  • entry.nativeURL
  • entry.toLocalURL()
  • entry.toURL()
  • _doc/...
  • /storage/...
  • file:///storage/...

示例邏輯:

function readLocalByPlus(fileUrl) {
  return new Promise(function(resolve, reject) {
    plus.io.resolveLocalFileSystemURL(fileUrl, function(entry) {
      const paths = [];

      if (entry.nativeURL) paths.push(entry.nativeURL);
      if (typeof entry.toLocalURL === 'function') paths.push(entry.toLocalURL());
      if (typeof entry.toURL === 'function') paths.push(entry.toURL());

      paths.push(fileUrl);

      readFirstAvailablePath(paths).then(resolve).catch(reject);
    }, reject);
  });
}

九、web-view 全屏問題

在安卓 App 端,web-view 是原生子窗口,不是普通 DOM 節(jié)點。

所以僅寫:

width: 100%;
height: 100%;

不一定能限制它的真實大小。

需要通過當前頁面的原生子 WebView 設置尺寸:

const childWebview = currentWebview.children()[0];

childWebview.setStyle({
  top: Math.round(rect.top),
  left: Math.round(rect.left),
  width: Math.round(rect.width),
  height: Math.round(rect.height)
});

這樣才能避免 docx 預覽的 web-view 在安卓端覆蓋全屏。

十、最終鏈路總結(jié)

當前推薦鏈路是:

用戶打開 docx 文件
-> filePreview.vue 判斷是 docx
-> uni.downloadFile 帶 token 下載文件
-> 得到本地 tempFilePath
-> 轉(zhuǎn)換本地路徑
-> web-view 打開 static/docx-preview/viewer.html?file=本地路徑
-> viewer.html 讀取本地 docx
-> docx-preview 渲染 HTML

這套方案的特點:

  • 不依賴后端轉(zhuǎn) PDF
  • 不依賴 Office Online
  • 不依賴 X5 插件
  • 屬于純前端預覽
  • 只支持 .docx
  • .doc 仍然需要系統(tǒng)應用或后端轉(zhuǎn)換

十一、局限性

docx-preview 不是 Word 官方內(nèi)核,因此存在一些限制:

  • 復雜頁眉頁腳可能不完全一致
  • 批注、修訂痕跡支持有限
  • 特殊字體可能不一致
  • 復雜表格可能變形
  • 大文件渲染慢
  • 加密文檔不支持
  • .doc 不支持

所以它適合“在線預覽”,不適合對版式要求極高的正式排版校驗。

十二、結(jié)論

在 uni-app 安卓 App 端,docx 純前端預覽不能簡單地把 docx-preview 寫在頁面腳本里。

更穩(wěn)的方式是:

docx-preview 放到本地 HTML
通過 web-view 執(zhí)行
App 頁面負責下載和傳遞本地文件路徑
viewer 頁面負責解析和渲染

一句話總結(jié):

DOCX 可以純前端預覽,但在 App 端必須把渲染放到真正的 WebView 環(huán)境里處理。

到此這篇關于uni-app安卓端純前端預覽DOCX的實現(xiàn)思路及代碼實例的文章就介紹到這了,更多相關uni-app安卓端純前端預覽DOCX內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

最新評論

临沂市| 龙南县| 文昌市| 五指山市| 华容县| 阿鲁科尔沁旗| 宁城县| 长春市| 昌邑市| 交口县| 舟曲县| 孝义市| 祁东县| 尤溪县| 乳源| 元氏县| 夹江县| 镶黄旗| 荔波县| 巩义市| 镇宁| 美姑县| 萍乡市| 临桂县| 柳江县| 白玉县| 和顺县| 武功县| 新乡县| 开原市| 库尔勒市| 通州区| 德安县| 成武县| 泾川县| 同江市| 濮阳县| 新河县| 盱眙县| 浦东新区| 蛟河市|