微信小程序文件下載與預覽功能實現詳解

在微信小程序開發中,文件處理是常見需求,尤其是涉及合同、文檔等場景。本文將通過一個實際案例,詳細講解如何實現文件的下載、解壓、列表展示及預覽功能。

功能概述

該頁面主要實現了以下核心功能:

  • 列表展示可下載的文件信息
  • 支持 ZIP 文件下載與解壓
  • 解壓后文件列表展示
  • 多種類型文件預覽(圖片、文檔等)
  • 分頁加載列表數據

核心代碼實現

頁面結構(Template)

<template><view class="contractClass"><!-- 滾動列表區域 --><scroll-view scroll-y class="scrollClass" @scrolltolower="handleToLower"><view class="contentClass"><!-- 文件列表項 --><view class="contentItemClass" v-for="(item,index) in bookList" :key="index"><view class="headClass">{{ item.state_text }}</view><van-divider /><!-- 操作按鈕區 --><view class="buttonClass"><view class="downloadClass" @click="downloadFile(item)">下載文件并解壓</view></view></view></view></scroll-view><!-- 解壓文件列表彈窗 --><van-popup :show="fileShow" round position="bottom"><view class="fileHeaderClass"><view></view><view>解壓文件列表</view><uni-icons type="closeempty" @click="closeFn"></uni-icons></view><scroll-view scroll-y class="filesListClass"><view v-for="(item , index) in files" :key="index" class="fileItemClass" @click="previewFn(item)">{{item}}</view></scroll-view></van-popup></view>
</template>

邏輯處理(Script)

<script>export default {data() {return {// 分頁數據pageData: {page: 1,pageSize: 10,total: 0},// 文件列表數據bookList: [],// 彈窗顯示控制fileShow: false,// 文件系統管理器FileSystemManager: '',// 支持預覽的文檔類型fileTypeArr: ['doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'pdf'],// 解壓后的文件列表files: [],// 當前操作的文件信息fileObj: {fileName: ''},}},onShow() {// 頁面顯示時獲取列表數據this.getList();},methods: {/*** 預覽文件* @param {string} item - 文件名*/previewFn(item) {// 獲取文件類型const fileType = this.onchangecb(item);// 構建文件完整路徑const fullPath = `${wx.env.USER_DATA_PATH}/extracted/${this.fileObj.fileName}/${item}`;// 圖片類型直接預覽if (this.isImageFile(item)) {this.previewMediaFn(fullPath);} // 支持的文檔類型直接打開else if (this.fileTypeArr.some(type => type === fileType)) {this.openDocumentFn(fullPath);} // 處理目錄情況else {this.FileSystemManager.stat({path: fullPath,success: (statRes) => {if (statRes.stats.isDirectory()) {// 如果是目錄,讀取目錄下的文件this.FileSystemManager.readdir({dirPath: fullPath,success: (readRes) => {if (readRes.files && readRes.files.length > 0) {// 遞歸處理目錄下的第一個文件const firstFile = readRes.files[0];this.previewFn(`${item}/${firstFile}`);} else {uni.showToast({title: this.$t('invoicePages.dirEmpty'),icon: 'none',duration: 2000});}},fail: () => {uni.showToast({title: this.$t('invoicePages.nosee'),icon: 'none',duration: 2000});}});} else {// 不支持的文件類型uni.showToast({title: this.$t('invoicePages.nosee'),icon: 'none',duration: 2000});}},fail: () => {uni.showToast({title: this.$t('invoicePages.fileNotFound'),icon: 'none',duration: 2000});}});}},/*** 關閉文件列表彈窗*/closeFn() {this.fileShow = false;this.removeSavedFileFn();this.fileObj.fileName = '';},/*** 獲取文件列表數據* @param {string} e - 區分是否是分頁加載*/async getList(e) {const data = {};const res = await this.userService.getBusinessList(data);if (res.code === 1) {// 分頁加載時合并數據,否則直接替換if (e === 'paging') {this.bookList = [...this.bookList, ...res.data.data];} else {this.bookList = res.data.data;}this.pageData.total = res.data.total || 0;}},/*** 處理滾動到底部事件(分頁加載)*/handleToLower() {let paginationTotal = 0;// 計算總頁數if (this.pageData.total % 10 === 0) {paginationTotal = Math.floor(this.total / 10)} else {paginationTotal = Math.ceil(this.total / 10)};// 如果還有下一頁,加載更多數據if (this.pageData.page < paginationTotal) {this.pageData.page = this.pageData.page + 1;this.getList('paging');}},/*** 獲取文件類型* @param {string} e - 文件名* @returns {string} 文件擴展名*/onchangecb(e) {const index = e.lastIndexOf(".");const ext = e.substr(index + 1);return ext;},/*** 判斷是否為圖片文件* @param {string} filename - 文件名* @returns {boolean} 是否為圖片*/isImageFile(filename) {const imageExtensions = ['jpg', 'jpeg', 'png', 'gif', 'bmp', 'svg'];const extension = filename.split('.').pop().toLowerCase();return imageExtensions.includes(extension);},/*** 下載文件* @param {object} item - 文件信息對象*/downloadFile(item) {const that = this;const fileType = this.onchangecb(item.attachment);// 處理ZIP文件if (fileType == 'zip') {this.FileSystemManager = uni.getFileSystemManager();uni.showLoading({title: "加載中...",mask: false});// 下載ZIP文件uni.downloadFile({url: item.attachment,success: res => {// 下載成功后解壓that.unzipHandler(res.tempFilePath);},fail: res => {uni.hideLoading();},})} // 處理文檔類型else if (this.fileTypeArr.some(type => type == fileType)) {uni.downloadFile({url: item.attachment,success: (res) => {that.openDocumentFn(res.tempFilePath);},});} // 處理圖片類型else if(this.isImageFile(item)){uni.downloadFile({url: item.attachment,success: (res) => {that.previewMediaFn(res.tempFilePath);},});} // 不支持的文件類型else {wx.showToast({title: this.$t('invoicePages.nosee'),icon: 'none',duration: 2000,mask: true,});}},/*** 解壓文件* @param {string} bookZipPath - ZIP文件路徑*/unzipHandler(bookZipPath) {console.log('解壓文件')let { FileSystemManager } = this;let that = this;FileSystemManager.unzip({zipFilePath: bookZipPath,targetPath: `${wx.env.USER_DATA_PATH}/extracted`, // 解壓目標路徑success(res) {// 解壓成功后獲取文件列表that.lookFileListFn();},})},/*** 獲取解壓后的文件列表*/lookFileListFn() {let { FileSystemManager } = this;let that = this;FileSystemManager.readdir({dirPath: `${wx.env.USER_DATA_PATH}/extracted`,success(res) {// 記錄文件夾名稱that.fileObj.fileName = res.files[0];// 獲取文件夾內文件列表that.lookFileListFn1();},fail(err) {// 處理錯誤}})},/*** 獲取指定文件夾內的文件列表*/lookFileListFn1() {let { FileSystemManager } = this;let that = this;FileSystemManager.readdir({dirPath: `${wx.env.USER_DATA_PATH}/extracted/${that.fileObj.fileName}`,success(res) {// 保存文件列表并顯示彈窗that.files = res.files;that.fileShow = true;uni.hideLoading();},fail(err) {// 處理錯誤}})},/*** 打開文檔* @param {string} attachment - 文件路徑*/openDocumentFn(attachment) {uni.openDocument({filePath: attachment,showMenu: true, // 顯示菜單success(res) {// 打開成功},fail(err) {// 打開失敗}})},/*** 預覽圖片* @param {string} imagePath - 圖片路徑*/previewMediaFn(imagePath) {uni.previewMedia({sources:[{url: imagePath,type:'image',}],showShareButton: true, // 顯示分享按鈕success(res){// 預覽成功},fail(err){// 預覽失敗}})},}}
</script>

樣式設計(Style)

<style lang="less" scoped>.contractClass {width: 750rpx;height: 100vh;background-color: #F5F7FB;.scrollClass {width: 100%;height: 100%;.contentClass {padding: 0rpx 40rpx 50px 40rpx;.contentItemClass{background-color: #fff;border-radius: 13rpx;padding: 30rpx;margin-top: 40rpx;.headClass{font-weight: bold;font-size: 29rpx;color: #333333;}.buttonClass{margin-top: 40rpx;display: flex;justify-content: flex-end;align-items: center;.downloadClass{height: 60rpx;background-color: #1B7AFE;color: #fff;border-radius: 30rpx;display: flex;justify-content: center;align-items: center;font-weight: 400;font-size: 29rpx;min-width: 180rpx;}}}}}/* 彈窗樣式 */.fileHeaderClass {padding: 24rpx 24rpx 0 24rpx;display: flex;justify-content: space-between;align-items: center;font-size: 36rpx;font-weight: bold;}.filesListClass {padding: 0 24rpx;height: 400rpx;.fileItemClass {color: #2875DA;margin-top: 20rpx;text-decoration: underline;}}}
</style>

核心功能解析

1. 文件下載與解壓流程

  1. 用戶點擊下載按鈕觸發downloadFile方法
  2. 根據文件類型進行不同處理:
    • ZIP 文件:下載后調用unzipHandler進行解壓
    • 文檔文件:直接下載并調用openDocumentFn打開
    • 圖片文件:下載后調用previewMediaFn預覽
  3. 解壓處理:
    • 使用FileSystemManager.unzip進行解壓
    • 解壓路徑使用小程序本地存儲路徑wx.env.USER_DATA_PATH
    • 解壓完成后讀取文件列表并顯示在彈窗中

2. 文件預覽機制

系統支持多種類型文件預覽,主要通過以下方法實現:

  • previewMediaFn:用于預覽圖片,支持常見圖片格式
  • openDocumentFn:用于打開文檔,支持 doc、docx、xls、xlsx、ppt、pptx、pdf 等格式
    - showMenu: true, 顯示分享菜單
  • 遞歸處理:對于解壓后包含文件夾的情況,通過遞歸方式查找可預覽的文件
    - showShareButton: true,, 顯示分享菜單

3. 分頁加載實現

通過scroll-view的scrolltolower事件實現分頁加載:

  • 初始加載第一頁數據
  • 滾動到底部時觸發handleToLower方法
  • 計算總頁數與當前頁數,判斷是否還有更多數據
  • 有更多數據則加載下一頁并合并到現有列表

注意事項

  1. 文件路徑處理:小程序中文件操作需使用wx.env.USER_DATA_PATH作為基礎路徑
  2. 權限問題:文件系統操作需要相應的權限,部分操作在不同平臺可能有差異
  3. 錯誤處理:需考慮文件下載失敗、解壓失敗、文件不存在等異常情況
  4. 性能優化:大文件處理可能影響性能,建議添加加載提示并優化用戶體驗

通過以上實現,我們可以構建一個功能完善的文件管理頁面,滿足用戶下載、解壓和預覽多種類型文件的需求。
在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/90858.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/90858.shtml
英文地址,請注明出處:http://en.pswp.cn/web/90858.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

postgresql執行創建和刪除時遇到的問題

刪除數據庫的時候出現的問題 有連接在占用 postgres=# DROP DATABASE "subgraph-dev"; ERROR: database "subgraph-dev" is being accessed by other users DETAIL: There is 1 other session using the database.強制斷開在用的連接 -- 替換 subgraph…

linux 應用層直接操作GPIO的方法

了解&#xff01;你使用的是 Rockchip RK3588S 平臺&#xff0c;需要操作 GPIO3_D5_d 這個引腳&#xff08;即 MCU_JTAG_TMS_M1/.../GPIO3_D5_d&#xff09;。以下是基于你提供的系統信息的具體操作步驟&#xff1a;&#x1f50d; 第一步&#xff1a;確認 GPIO 系統編號 在 RK3…

JavaScript核心概念全解析

目錄 1. 作用域 (1) 局部作用域 (2) 全局作用域 2. 垃圾回收 (1) 引用計數法 (2) 標記清除法 3. 閉包 (1) 作用 (2) 風險 4. 變量提升 (1) var (2) let 和 const (3) const 5. 函數提升 (1) 函數聲明 (2) 函數表達式 6. 函數參數 (1) 動態參數 (2) 剩余參數…

力扣刷題(第一百天)

靈感來源 - 保持更新&#xff0c;努力學習- python腳本學習提莫攻擊解題思路初始化總中毒時間 total。遍歷每次攻擊的時間點&#xff08;從第二個開始&#xff09;&#xff1a;計算當前攻擊與前一次攻擊的時間間隔 gap。若 gap < duration&#xff0c;則本次中毒時間為 gap&…

JMeter 性能測試實戰筆記

JMeter 性能測試實戰筆記 本文檔是一份詳細的 JMeter 指南&#xff0c;涵蓋了從創建測試計劃、執行測試到解讀性能結果的全過程。 一、創建測試計劃 一個完整的測試計劃是執行性能測試的基礎。下面將分步介紹如何創建一個針對文件上傳接口的測試場景。 第一步&#xff1a;添加線…

圖像處理:第二篇 —— 選擇鏡頭的基礎知識及對圖像處理的影響

一、圖像傳感器的典型應用圖像處理過程大致可分為如下四步&#xff1a;1.拍 攝 按下快門&#xff0c;拍攝圖像2.傳 送 將圖像數據由照相機傳送到控制器。3.處 理 前處理 : 對于圖像數據進行加工&#xff0c;使其特征更加明顯。測算處理 : 根據圖像數據對于損…

Linux 系統文件夾結構及用途說明

Linux 系統采用樹形文件結構&#xff0c;每個目錄都有明確的功能定位&#xff0c;遵循 FHS&#xff08;Filesystem Hierarchy Standard&#xff09; 標準。以下是新安裝系統后主要文件夾的用途&#xff1a;一、根目錄&#xff08;/&#xff09;核心文件夾1. /bin&#xff1a;基…

[spring6: HttpSecurity]-全新寫法

HttpSecurity HttpSecurity 是 Spring Security 中用于配置基于 HTTP 請求的安全策略的核心構建器&#xff0c;支持細粒度控制請求授權、認證、登錄、登出、CSRF、CORS、會話管理等安全功能。 package xyz.idoly.demo;import org.springframework.context.annotation.Bean; imp…

MIPI DSI 轉 1LVDS ,分辨率1920*1080.

一款橋接芯片&#xff0c;它接收 MP DSI 輸入并發送 LVDS 輸出。MlPI DSI 支持至多 4 條通道&#xff0c;每條通道的最大傳輸速率為 1Gbps&#xff0c;總的最大輸入帶寬為 4Gbps&#xff0c;并且還支持 MlPI 定義的 ULPS&#xff08;超低功耗狀態&#xff09;。LVDS 輸出采用 V…

墨者:SQL手工注入漏洞測試(MySQL數據庫)

一、SQL手工注入漏洞測試(MySQL數據庫) 本文以墨者學院靶場為例&#xff0c;演示MySQL數據庫的手工SQL注入全過程。靶場以自己的地址為準&#xff1a;http://124.70.64.48:47777/new_list.php?id1 二、注入原理與流程&#xff08;如下指令去掉了id之前的內容&#xff09; M…

idea打開后project窗口未顯示項目名稱的解決方案

前言 今天上班后&#xff0c;打開了idea發現之前project窗口中的項目都不見了&#xff0c;啥也沒有&#xff0c;見下圖原因 一般為配置文件*.iml 出錯了。 解決方案1 方法1&#xff1a;若知道出錯的具體位置與原因&#xff0c;用文本編輯器打開*.iml文件&#xff0c;找到出錯位…

不一樣的Mysql安裝方式

文章目錄MySQL介紹與安裝MySQL介紹基本安裝下載打開網址點擊點擊選擇LTSwindows選擇zip壓縮包格式&#xff0c;mac OS選擇dmg格式。不需要注冊登陸網站&#xff0c;直接謝謝&#xff0c;繼續下載即可。解壓復制bin路徑配置環境變量搜索點擊環境變量點擊用戶變量的Path 或 系統變…

MyBatis高級應用實戰指南

MyBatis高級應用實例 以下是MyBatis高級應用實例,涵蓋復雜查詢、動態SQL、插件開發、緩存優化等場景,幫助深入掌握MyBatis核心技術。 動態SQL構建 Example 1: 多條件動態查詢 使用<if>和<where>標簽實現條件組合: <select id="findUsers" resu…

Xilinx-FPGA-PCIe-XDMA 驅動內核兼容性問題修復方案

問題1&#xff1a;implicit declaration of function "mmiowb()"解決方法&#xff1a;在 libxdma.c 和 cdev_xvc.c 文件中注釋掉所有 mmiowb () 函數調用問題2&#xff1a; "macro"access_ok"passed 3 arguments, but takes just 2"解決方法&…

ThreadLocal--ThreadLocal介紹

&#x1f9e0; 一、什么是 ThreadLocal&#xff1f; ThreadLocal 是 Java 提供的一種 線程本地變量機制&#xff1b; 每個線程都維護一份自己的副本&#xff1b; 它不用于多個線程共享變量&#xff0c;而是用于每個線程獨立維護自己的變量副本&#xff1b; 常用于&#xff1…

AWS云S3+Glue+EMRonEC2+ReadShift

Amazon S3&#xff08;Amazon Simple Storage Service&#xff09;即亞馬遜簡單存儲服務&#xff0c;是 AWS&#xff08;Amazon Web Services&#xff09;提供的一種對象存儲服務&#xff0c;在大數據領域被廣泛使用。以下是關于它的詳細介紹&#xff1a;基本概念Amazon S3 主要…

OpenLayers 綜合案例-軌跡回放

看過的知識不等于學會。唯有用心總結、系統記錄&#xff0c;并通過溫故知新反復實踐&#xff0c;才能真正掌握一二 作為一名摸爬滾打三年的前端開發&#xff0c;開源社區給了我飯碗&#xff0c;我也將所學的知識體系回饋給大家&#xff0c;助你少走彎路&#xff01; OpenLayers…

語音自動生成PPT、思維導圖、會議紀要、筆記、大綱、導讀等

一、需要用到錄音工具&#xff0c;手機端工具&#xff1a;訊飛聽見二、需要用到的工具通義&#xff1a;https://www.tongyi.com/discover上傳錄音&#xff0c;描述一下&#xff0c;讓直接給生成PPT就行&#xff0c;點生成就可以生成ppt&#xff0c;對PPT進行導出就行 三、除了生…

【MySQL】腳本化快速搭建跨平臺、可定制的MySQL數據庫

冗長的廢話就省略了&#xff0c;大家看到這篇博客&#xff0c;效果如標題所示&#xff0c;我將提供完整的腳本&#xff0c;并用 「保姆級」的詳細步驟&#xff0c;給你提供一個快速搭建跨平臺、可定制的 MySQL環境的解決方案。保證無論你是 Linux 服務器管理員、macOS 開發者&a…

MAC包頭、IP包頭 、UDP包頭中的長度含義是啥?三者之間有啥區別?

以太網幀、IP包及TCP與UDP的報文格式 下面用通俗技術的方式詳細解釋&#xff1a; 1. MAC包頭&#xff08;以太網幀頭&#xff09;中的長度 字段名稱&#xff1a;EtherType/Length位置&#xff1a;以太網幀頭的第13、14字節含義&#xff1a; 如果值小于等于1500&#xff08;0x0…