小程序下载文件,有两种情况,一种是文件在服务器上,一种是请求后台接口,接口返回文件流在进行下载。本文针对这两种情况给出解题思路,方法有很多,如果大家有更好的方法,欢迎留言交流。
1、文件在服务器上,通过GET请求打开文档
export function useDownload() {
function download() {
uni.showLoading({ title: '加载中...' })
const downloadTask = uni.downloadFile({
url: '文件地址',
success: (res) => {
if (res.statusCode === 200) {
console.log('下载成功')
uni.openDocument({
filePath: res.tempFilePath,
showMenu: true, // 开启时右上角会有三点,点击可以保存
success: (res) => {
console.log(res)
console.log('打开文档成功')
},
fail: (res) => {
console.log(res)
uni.showToast({ title: '打开文件失败', icon: 'error' })
},
complete: () => {
uni.hideLoading()
},
})
} else {
console.log(res)
uni.showToast({ title: '获取文件失败', icon: 'error' })
}
},
fail: (res) => {
console.log(res)
uni.showToast({ title: '获取文件失败', icon: 'error' })
},
complete: () => {
uni.hideLoading()
},
})
// 可以通过onProgressUpdate显示一个加载进度条等
downloadTask.onProgressUpdate((res) => {
console.log('下载进度' + res.progress)
console.log('已经下载的数据长度' + res.totalBytesWritten)
console.log('预期需要下载的数据总长度' + res.totalBytesExpectedToWrite)
console.log(res)
})
}
return { download }
}
2、通过请求接口文件流下载文件
export function useDownload() {
const loading = ref(false)
function download() {
if (loading.value) return
uni.showLoading({ title: '文件加载中...' })
loading.value = true
// 请求接口
uni.request({
url: '请求接口',
// 也可以是get方法,具体看业务
method: 'POST',
// 这里如果需要传参数,可以通过data参数传入
// data: {id: 1},
dataType: 'arraybuffer',
header: {'content-type': 'application/x-www-form-urlencoded' },
responseType: 'arraybuffer',
})
.then((res: any) => {
// 获取全局唯一的文件管理器
const fs = uni.getFileSystemManager()
//文件名
const fileName = !res.header['Content-Disposition']
? '下载文件'
: decodeURIComponent(res.header['Content-Disposition'].match(/filename="?(.+)"?/)[1])
//写文件
fs.writeFile({
// wx.env.USER_DATA_PATH 是小程序访问用户文件路径的变量
filePath: wx.env.USER_DATA_PATH + '/' + fileName,
// res.data就是接口返回的文件流
data: res.data,
//二进制流文件必须是 binary
encoding: 'binary',
success(e) {
console.log(e)
uni.openDocument({
// 上面存入的文件路径
filePath: wx.env.USER_DATA_PATH + '/' + fileName,
// 显示右上角菜单
showMenu: true,
success: (res) => {
console.log(res)
loading.value = false
uni.hideLoading()
uni.showToast({ title: '文件获取成功,请通过右上角菜单进行分享保存', icon: 'none' })
},
fail: (res) => {
console.log(res)
loading.value = false
uni.hideLoading()
uni.showToast({ title: '打开文件失败', icon: 'none' })
}
})
},
fail(e) {
console.log(e)
uni.hideLoading()
loading.value = false
uni.showToast({ title: '写文件失败', icon: 'none' })
},
})
})
.catch(() => {
loading.value = false
uni.hideLoading()
uni.showToast({ title: '文件获取失败', icon: 'none' })
})
}
return { download }
}