downLoadAjaxEvt('get', `https://imp1.epsolarpv.com/static?key=${config.USER_KEY}&action=excel&type=RTU&salesman=${imeiinput1}&model=${select1}&ip=${select2}&num=${imeiinput3}&APN=${imeiinput5}&APNname=${imeiinput6}&APNkey=${imeiinput7}&addr=${imeiinput2}&orderNo=${imeiinput4}&slaveAddr=1`)
// 下载文件流 -------------------------- function downloadEvt(url, fileName = '未知文件') { const el = document.createElement('a'); el.style.display = 'none'; el.setAttribute('target', '_blank'); /** * download的属性是HTML5新增的属性 * href属性的地址必须是非跨域的地址,如果引用的是第三方的网站或者说是前后端分离的项目(调用后台的接口),这时download就会不起作用。 * 此时,如果是下载浏览器无法解析的文件,例如.exe,.xlsx..那么浏览器会自动下载,但是如果使用浏览器可以解析的文件,比如.txt,.png,.pdf....浏览器就会采取预览模式 * 所以,对于.txt,.png,.pdf等的预览功能我们就可以直接不设置download属性(前提是后端响应头的Content-Type: application/octet-stream,如果为application/pdf浏览器则会判断文件为 pdf ,自动执行预览的策略) */ fileName && el.setAttribute('download', fileName); el.href = url; console.log(el); document.body.appendChild(el); el.click(); document.body.removeChild(el); }; // 根据header里的contenteType转换请求参数 function transformRequestData(contentType, requestData) { requestData = requestData || {}; if (contentType.includes('application/x-www-form-urlencoded')) { // formData格式:key1=value1&key2=value2,方式二:qs.stringify(requestData, {arrayFormat: 'brackets'}) -- {arrayFormat: 'brackets'}是对于数组参数的处理 let str = ''; for (const key in requestData) { if (Object.prototype.hasOwnProperty.call(requestData, key)) { str += `${key}=${requestData[key]}&`; } } return encodeURI(str.slice(0, str.length - 1)); } else if (contentType.includes('multipart/form-data')) { const formData = new FormData(); for (const key in requestData) { const files = requestData[key]; // 判断是否是文件流 const isFile = files ? files.constructor === FileList || (files.constructor === Array && files[0].constructor === File) : false; if (isFile) { for (let i = 0; i < files.length; i++) { formData.append(key, files[i]); } } else { formData.append(key, files); } } return formData; } // json字符串{key: value} return Object.keys(requestData).length ? JSON.stringify(requestData) : ''; } /** * ajax实现文件下载、获取文件下载进度 * @param {String} method - 请求方法get/post * @param {String} url * @param {Object} [params] - 请求参数,{name: '文件下载'} * @param {Object} [config] - 方法配置 */ function downLoadAjaxEvt(method = 'get', url, params, config) { const _method = method.toUpperCase(); const _config = Object.assign({ contentType: _method === 'GET' ? 'application/x-www-form-urlencoded' : 'application/json', // 请求头类型 fileName: '未知文件', // 下载文件名(必填,若为空,下载下来都是txt格式) async: true, // 请求是否异步-true异步、false同步 token: 'token' // 用户token }, config); const queryParams = transformRequestData(_config.contentType, params); const _url = `${url}${_method === 'GET' && queryParams ? '?' + queryParams : ''}`; const ajax = new XMLHttpRequest(); ajax.open(_method, _url, _config.async); ajax.setRequestHeader('Authorization', _config.token); ajax.setRequestHeader('Content-Type', _config.contentType); // responseType若不设置,会导致下载的文件可能打不开 ajax.responseType = 'blob'; // 获取文件下载进度 ajax.addEventListener('progress', (progress) => { const percentage = ((progress.loaded / progress.total) * 100).toFixed(2); const msg = `下载进度 ${percentage}%...`; }); ajax.onload = function () { if (this.status === 200 || this.status === 304) { // 通过FileReader去判断接口返回是json还是文件流 const fileReader = new FileReader(); fileReader.onloadend = (e) => { if (this.getResponseHeader('content-type').includes('application/json')) { const result = JSON.parse(fileReader.result || '{message: 服务器出现问题,请联系管理员}'); alert(result.message); } else { var date = new Date(); //获取一个时间对象 let Year = date.getFullYear(); // 获取完整的年份(4位,1970) let Month = date.getMonth() + 1; // 获取月份(0-11,0代表1月,用的时候记得加上1) let code = '' for (var i = 0; i < 6; i++) { code += parseInt(Math.random() * 10) } let imeiinput1 = $("#imeiinput1").val() let imeiinput2 = $("#imeiinput2").val() let imeiinput3 = $("#imeiinput3").val() let imeiinput4 = $("#imeiinput4").val() let imeiinput5 = $("#imeiinput5").val() let imeiinput6 = $("#imeiinput6").val() let imeiinput7 = $("#imeiinput7").val() let select1 = $("#select1").val() let select2 = $("#select2").val() // 两种解码方式,区别自行百度: decodeURIComponent/decodeURI(主要获取后缀名,否则低版本浏览器会一律识别为txt,导致下载下来的都是txt) const _fileName = `${imeiinput1} ${select1} 出货表 ${imeiinput3}套 ${Year}${Month}${code}.xls`//decodeURI((this.getResponseHeader('content-disposition') || '; filename="未知文件"').split(';')[1].trim().slice(9)); /** * Blob.type一个字符串,表明该 Blob 对象所包含数据的 MIME 类型。如果类型未知,则该值为空字符串。 * 对于pdf:type为application/pdf 同时 a标签 不设置download属性, 可以直接预览 */ const blob = new Blob([this.response]); const href = URL.createObjectURL(blob); downloadEvt(href, _fileName); // 释放一个之前已经存在的、通过调用 URL.createObjectURL() 创建的 URL 对象 URL.revokeObjectURL(href); removeLoading('test'); } }; // 调用readAsText读取文件,少了readAsText将不会触发onloadend事件 fileReader.readAsText(this.response); } else { alert('服务器出现问题,请联系管理员'); } }; // send(string): string:仅用于 POST 请求 ajax.send(queryParams); }