首先呢,小程序打开pdf等文件有下面几种办法:
- 用微信自带的wx.downloadFile() + wx.openDocument()
- 使用web-view,uni-app中webview可以直接加载pdf文件
- 可以使用网上说的pdf.js去实现(我没有用到这个,就不介绍了)
网上查到很多资料显示安卓是可以通过上面第一种办法,但是ios用第一个方法打不开,网上、社区确实有这个说法,但是貌似bug被修复了,我经过测试现在安卓和ios都可以打开。
如果大家遇到了这样的bug,那可以安卓使用方法1,苹果使用webview的方式打开文件
我上传文件使用的是uni-ui的上传组件:
这里要提一个bug就是说,这个组件设置v-model 后上传文件后,按道理再去读取这个v-model的值就应该是之前上传的文件数据,但是打印后并没有数据,而只有在点击删除文件后,再读取v-model才会有值,这个bug在社区很早就有人提出了,所以我采用通过监听select事件去手动存储文件数据,然后对应delete事件也删除数组中对应的文件数据。其次因为我项目中的需求是点击文件名字预览,那么文件的展示是手写的,组件原本的文件展示我用display:none隐藏掉了。
<view style="width: 70%;margin: 0 auto;margin-bottom: 20rpx;"> <uni-file-picker v-model="fileList" title="最多选择9个文件" :list-styles="styleObject" :sourceType="['album', 'camera']" file-mediatype="all" ref="files" :limit="11" :auto-upload="false" @select="select" @success="success" @fail="fail" @progress="progress" @delete="deleteFile"> <view class="clickBtn">点击选择文件</view> </uni-file-picker> </view> <view style="width: 70%;margin: 0 auto;margin-bottom: 20rpx;" v-for="(item, index) in ajaxFileList" :key="index"> <view class="flex justify-start align-center"> <view class="fileBox" @click="Preview(item)">{{ item.name }}</view> <view class="delBox" @click="delFile(index)">删除</view> </view> </view>
// 获取上传状态 select(e) { console.log('选择文件:', e) e.tempFiles.forEach(item => { this.ajaxFileList.push({//用一个变量单独存储上传的文件数据 name: item.cloudPath, extname: item.extname, url: item.path, }) }); console.log(this.ajaxFileList); }, deleteFile(e) { console.log('删除文件:', e) this.ajaxFileList.forEach((item, index) => { if (e.tempFilePath === item.path) { this.ajaxFileList.splice(index, 1) } }) console.log(this.ajaxFileList); }, // 上传成功 success(e) { console.log('上传成功') }, // 上传失败 fail(e) { console.log('上传失败:', e) }, // 获取上传进度 progress(e) { console.log('上传进度:', e) }, Preview(item) {//用正则去识别不同文件类型,然后对应不同文件类型去做不同操作 console.log(item); // 定义图片类型的正则表达式 const imageRegex = /(/.jpg|/.jpeg|/.png)$/i; // 定义文档类型的正则表达式 const docRegex = /(/.doc|/.docx|/.pdf)$/i; // 定义其他文件类型的正则表达式 const othersRegex = /(/.txt|/.csv|/.xlsx)$/i; // 利用正则表达式判断文件类型 if (imageRegex.test(item.name)) { console.log("图片类型"); this.lookImage(item.url) } else if (docRegex.test(item.name)) { console.log("文档类型"); this.lookFile(item.url) } else if (othersRegex.test(item.name)) { console.log("其他文件类型"); } else { uni.showToast({ title: `未知文件类型`, icon: 'none', duration: 2000 }) } }, delFile(index) { console.log(index); this.ajaxFileList.splice(index, 1) }, lookImage(url) { let imgArray = []; imgArray[0] = url uni.previewImage({ current: 0, urls: imgArray }) }, lookFile(url) { uni.openDocument({ filePath: url, success: function (res) { console.log("打开文档成功"); }, fail: function (res) { console.log("uni.openDocument,fail"); console.log(res) }, complete: function (res) { console.log("uni.openDocument,complete"); console.log(res) } }); },
如果大家的文件是https或者http的线上资源:
uni.downloadFile({ url: url, success: function (res) { var filePath = res.tempFilePath; console.log("下载文件:",res); uni.openDocument({ filePath: filePath, success: function (res) { console.log("打开文档成功"); }, fail: function (res) { console.log("uni.openDocument,fail"); console.log(res) }, complete: function (res) { console.log("uni.openDocument,complete"); console.log(res) } }); }, fail: function (res) { console.log('uni.downloadFile,fail') console.log(res) }, complete: function (res) { console.log('uni.downloadFile,complete') console.log(res) }}, );
我本次遇到的需求是单图预览、文件上传时候支持预览文件,
如果出现uni.openDocument安卓能打开,ios打不卡id情况那么就看下面的文章
https://blog.csdn.net/weixin_38673922/article/details/128626373
https://blog.csdn.net/liuxiaocaie/article/details/125874472