Bootstrap

Uniapp移动端调用后端接口保存文件到本地

  • uni.uploadFile(OBJECT)只支持GET的网络请求,有时服务端端接口是POST类型,就没办法用,这个工具类可以实现GET和POST方式的请求下载文件

注意点

  • baseUrl :后端的地址 例如 http://localhost:8080/ 根据需求修改
  • reqMethod要大写
  • getToken()为项目中的获取token的方法,如果接口不需要token则掉本工具方法时传入参数token=false就可。
  • d.filename为下载后的文件名
  • var fileSaveUrl = plus.io.convertLocalFileSystemURL(d.filename);可以得到下载后的绝对路径
  • 下面有调用示例

参数

  • url:路径
  • reqMethod:请求方式 GET||POST,大写
  • object: post的请求参数
  • filename:文件名
  • folderName:存放文件的文件夹名称,默认download(二级),在手机文件系统的app的包目录下面
  • isToken:是否要token 默认需要
import {
	getToken
} from '@/utils/auth'
import config from '@/config'
import {
	toast,
	showConfirm,
	tansParams
} from '@/utils/common'
import errorCode from '@/utils/errorCode'

const baseUrl = 'http://localhost:8080/' //后端的地址 例如 http://localhost:8080/ 根据需求修改

/**
 * url:路径
 * reqMethod:请求方式 GET||POST
 * object: post的请求参数
 * filename:文件名
 * folderName:文件夹名称,默认download(二级)
 * isToken:是否要token 默认需要
 */
const download = (url, reqMethod, object,filename,folderName='download',isToken = true) => {
	if (reqMethod != 'GET' && reqMethod != 'POST'){
		uni.showToast({
			title: '只支持GET||POST方法',
			icon: "none"
		})
	}
	if (reqMethod == 'GET') {
		url = url + '?' + tansParams(object)
		url = url.slice(0, -1)
	}
	console.log('开始下载')
	// #ifdef H5
	uni.showToast({
		title: "请在移动端操作",
		icon: "none"
	})
	// #endif
	// #ifdef APP-PLUS
	// uni.showLoading({
	// 	title: "正在下载"
	// })
	var url = baseUrl + url; //文件名称可以在上传时进行保存,下载时取出,当文件名称中存在单双引号时,要做好处理,否则会报错
	var name = "_doc/download/"+ folderName + '/' + filename;
	// console.log('method', reqMethod)
	return new Promise((resolve,reject) => {
		var dtask = plus.downloader.createDownload(url, {
			filename: name, //利用保存路径,实现下载文件的重命名
			method: reqMethod,
			data: object
		}, function(d, status) {
			console.log("d====>", d)
			console.log("status====>", status)
			//d为下载的文件对象
			if (status == 200) {
				// uni.hideLoading()
				//下载成功,d.filename是文件在保存在本地的相对路径,使用下面的API可转为平台绝对路径
				// console.log(d)
				var fileSaveUrl = plus.io.convertLocalFileSystemURL(d.filename);
				// console.log(fileSaveUrl)
				d['fileSaveUrl'] = fileSaveUrl
				resolve({data:d,status})
				//进行DOM操作
				$("#downloadDom").attr('src', fileSaveUrl);
				// plus.runtime.openFile(d.filename);	   //选择软件打开文件
			} else {
				//下载失败
				plus.downloader.clear(); //清除下载任务
				reject({data:d,status})
			}
		})
		if (isToken) {
			dtask.setRequestHeader("Authorization", "Bearer " + getToken()) // getToken()为项目中的获取token的方法,如果接口不需要token则掉本工具方法时传入参数token=false就可。
		}
		dtask.setRequestHeader("Content-Type", "application/json")
		dtask.start(); //执行下载
	})
	// #endif
}

export default download

common.js

/**
 * 显示消息提示框
 * @param content 提示的标题
 */
export function toast(content) {
	uni.showToast({
		icon: 'none',
		title: content
	})
}

/**
 * 显示模态弹窗
 * @param content 提示的标题
 */
export function showConfirm(content) {
	return new Promise((resolve, reject) => {
		uni.showModal({
			title: '提示',
			content: content,
			cancelText: '取消',
			confirmText: '确定',
			success: function(res) {
				resolve(res)
			}
		})
	})
}

/**
 * 参数处理
 * @param params 参数
 */
export function tansParams(params) {
	let result = ''
	for (const propName of Object.keys(params)) {
		const value = params[propName]
		var part = encodeURIComponent(propName) + "="
		if (value !== null && value !== "" && typeof(value) !== "undefined") {
			if (typeof value === 'object') {
				for (const key of Object.keys(value)) {
					if (value[key] !== null && value[key] !== "" && typeof(value[key]) !== 'undefined') {
						let params = propName + '[' + key + ']'
						var subPart = encodeURIComponent(params) + "="
						result += subPart + encodeURIComponent(value[key]) + "&"
					}
				}
			} else {
				result += part + encodeURIComponent(value) + "&"
			}
		}
	}
	return result
}

示例

<template>
	<view class="online-container">
		<button @click="exportData">下载</button>
		<u-modal :show="showOpenFileModel" :showCancelButton="true" content='文件下载成功,需要打开文件吗?' @confirm="handleOpenFile" @cancel="showOpenFileModel = false"></u-modal>
	</view>
</template>

<script>
	import download from '@/utils/download.js'
	export default {
		data() {
			return {
				showOpenFileModel:false,
				openFilePath:''
			}
		},
		methods: {
			exportData(){
				uni.showLoading({
					title: "正在下载"
				})
				download(
				'/test/download',//网络请求地址,拼到http://localhost:8080/后面
				'POST',
				this.queryForm,
				'fileppp.xlsx', //文件名
				'online' //存放的文件夹名称 
				).then(res=>{
					uni.hideLoading()
					console.log("res===>",res)
					this.openFilePath = res.data.fileSaveUrl
					this.showOpenFileModel = true
					}).catch(err=>{
					uni.hideLoading()
					uni.showToast({
						title: '下载失败',
						icon: "none"
					})
					console.log("err====>",err)
				})
			},
			handleOpenFile(){
				this.showOpenFileModel = false
				uni.openDocument({
					filePath: this.openFilePath,
					showMenu: true,
					success: function(res) {
						console.log('打开文档成功');
					},
					fail: function(res) {
						console.log(res.data.filename)
						console.log("打开文档失败", res)
					}
				})
			}
</script>

<style lang="scss" scoped>
.online-container {}
</style>

;