uni-app、H5+ 下载并保存、打开文件
2023-12-30 12:24:11
前言
紧接 上一篇保存图片到相册 ,项目中还有一个根据条件导出 Excel 文件并要求保存到手机上的需求,接下来也将分别介绍 uni-app 及 H5+ 两种方案。
一、uni-app 实现方案
1. H5 端发送消息
uni.webView.postMessage({
data: {
operType: 'saveFile',
url: 'http://www.test.com/exportExcel',
token: '123',
params: {
key1: 'value1',
key2: 'value2'
}
}
});
2. uni-app 下载文件并保存
<template>
<view>
<web-view src="/hybrid/html/index.html" @message="handleMessage"></web-view>
</view>
</template>
<script>
export default {
methods: {
handleMessage(e) {
const [opts] = e.detail.data; // e.detail.data 得到的是一个消息数组
this.downloadFile(opts);
},
// 下载文件
downloadFile(opts) {
let {
url,
token,
operType,
params
} = opts;
if (params) url = url + JSON.stringify(params);
uni.downloadFile({
url,
// timeout: 30000, 超时时间
header: { token }, // 下载文件需要传递的请求头参数都设置在 header 对象中
success: res => {
const {
statusCode,
tempFilePath // 临时文件路径,下载后的文件会存储到一个临时文件
} = res;
console.log(tempFilePath);
if (statusCode === 200) {
console.log('下载文件成功');
if (operType === 'saveImg') {
this.saveImg(tempFilePath);
}
if (operType === 'saveFile') {
this.saveFile(tempFilePath);
}
} else {
uni.showToast({
title: '下载文件失败'
});
}
}
})
},
// 保存文件
saveFile(filePath) {
uni.saveFile({
tempFilePath: filePath,
success: (res) => {
uni.showToast({
title: '文件保存成功'
});
console.log('文件保存成功,路径为:' + res.savedFilePath)
},
fail: (err) => {
console.log('文件保存失败:' + err)
}
})
},
}
}
</script>
因为 uni.downloadFile 只支持 get 请求,原本导出 Excel 的后端请求是 post,参数都放在 body 中,与后端协商之后改为 get 方式,参数使用 url 中的 params 接收一个经过 JSON.stringify 转换的对象字符串。
uni.saveFile 保存成功之后,但无法设置文档的存放位置,而实际文档存放的位置对于用户来说又比较难找到,比如这是一个用 HBuilderX + 夜神模拟器调试 时打印的存储路径:
/storage/emulated/0/Android/data/io.dcloud.HBuilder/apps/HBuilder/doc/uniapp_save/17038344728620.xls
3. uni-app 打开文档
将保存文档的操作修改为了打开文档,打开文档之后用户可自行通过wx等分享此文档。以下为修改之后的代码:
<template>
<view>
<web-view src="/hybrid/html/index.html" @message="handleMessage"></web-view>
</view>
</template>
<script>
export default {
methods: {
handleMessage(e) {
const [opts] = e.detail.data; // e.detail.data 得到的是一个消息数组
this.downloadFile(opts);
},
// 下载文件
downloadFile(opts) {
let {
url,
token,
operType,
params
} = opts;
if (params) url = url + JSON.stringify(params);
uni.downloadFile({
url,
// timeout: 30000, 超时时间
header: { token }, // 下载文件需要传递的请求头参数都设置在 header 对象中
success: res => {
const {
statusCode,
tempFilePath // 临时文件路径,下载后的文件会存储到一个临时文件
} = res;
console.log(tempFilePath);
if (statusCode === 200) {
console.log('下载文件成功');
if (operType === 'saveImg') {
this.saveImg(tempFilePath);
}
if (operType === 'saveFile') {
// this.saveFile(tempFilePath);
this.openFile(tempFilePath);
}
} else {
uni.showToast({
title: '下载文件失败'
});
}
}
})
},
// 保存文件
saveFile(filePath) {
uni.saveFile({
tempFilePath: filePath,
success: (res) => {
uni.showToast({
title: '文件保存成功'
});
console.log('文件保存成功,路径为:' + plus.io.convertLocalFileSystemURL(res.savedFilePath));
},
fail: (err) => {
console.log('文件保存失败:' + err);
}
})
},
// 打开文档
openFile(filePath) {
let platform = uni.getSystemInfoSync().platform; //当前环境
if (platform == 'ios') {
filePath = escape(filePath);
}
uni.openDocument({
filePath,
showMenu: true,
success: function(res) {
console.log('打开文档成功');
},
fail: function(e) {
console.log(e);
uni.showToast({
title: '打开失败'
})
}
});
},
}
}
</script>
- uni.openDocument 的参数配置项中 showMenu: true 用于设置右上角是否有可以转发分享的功能
- 下载的文件名中会包含中文字符,在执行打开文档方法的时候会在 ios 系统中打开文件失败,查找到一个解决方案是
针对 ios 系统将 filepath 经过 escape() 转换
之后就可正常打开
二、H5+ 实现方案
let params: {
key1: 'value1',
key2: 'value2'
}
let url = `http://www.test.com/exportExcel?params=${JSON.stringify(params)}`
let fileName = '测试.xls'
let options = {
filename: `_downloads/${fileName}`,
// timeout: 120 // 超时时间单位s,默认120s
}
let header = {
token: '123'
}
plusDownloadFile(url, options, header)
// H5下载文件
plusDownloadFile(url, options = {}, header = {}) {
let dtask = plus.downloader.createDownload(url, options, (d, status) => {
if (status == 200) {
this.$showToast.ok( '下载成功' );
console.log('文件存储路径:' + d.filename);
// 调用打开文件方法
plus.runtime.openFile(options.filename);
} else {
this.$showToast.error('下载失败');
plus.downloader.clear();
}
});
Object.keys(header).forEach(k => {
dtask.setRequestHeader(k, header[k]);
});
// 开始下载
dtask.start();
},
总结
- 经过在项目中测试验证,两种方案都能下载并打开文件。
- H5+ 的下载是支持 post 请求方式,请求参数是放在 options 的 data 中,不过需要注意这个 data 只接收 string 类型的参数,对象形式可通过 JSON.stringify 先转换,但是和 uni.downloadFile 一样都需要服务端支持,下载的请求接收参数拿到字符串之后再通过 JSON.parse 解析。
- H5+ 的下载是支持修改文件的保存路径为以"_downloads/“、”_doc/“、”_documents/"开头的字符串,uni-app 的方式不支持。
文章来源:https://blog.csdn.net/qq_42966167/article/details/135287027
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!