为实现从本地服务器下载xlsx文件至前端vue echarts中展示,踩过许多坑,现将完整流程和源码分享。
1、 vue axios get请求 返回304 Not Modified 不更新数据
原因:由于浏览器缓存了get请求,导致不管如何刷新,数据都不更新。
python
var url = 'http://127.0.0.1:8000/' + this.value.value + '?nocache=' + (new Date()).getTime() // 本地数据库下载
axios.get(url,{ responseType: "arraybuffer" })
解决方法:url尾部添加 '?nocache=' + (new Date()).getTime()
给url这个对象添加一个nocache的参数,属性为timestamp,值为时间戳,原理是实时更改url,浏览器判断缓存内容不同,就会正常更新数据。
2、获取并解析xlsx文件流数据
python
axios.get(url,{ responseType: "arraybuffer" })
.then((res) => {
console.log("res:" + res)
console.log("res.data:" + res.data)
let wb = XLSX.read(res.data, {
type: 'arraybuffer'
});
//wb.SheetNames[0]是获取Sheets中第一个Sheet的名字
//wb.Sheets[Sheet名]获取第一个Sheet的数据
let worksheet = JSON.stringify(XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]])); // 将一个 JavaScript 对象或值转换为 JSON 字符串
console.log('worksheet:' + worksheet)
可以使用axios的get方法发送HTTP请求,获取Excel文件的二进制流数据。在请求中,需要设置responseType为arraybuffer。
得到Excel文件流数据后,可以使用wb.Sheets[wb.SheetNames[0]]函数获取Sheets中第一个Sheet的数据。使用插件SheetJS使用XLSX.utils.sheet_to_json()解析excel,给空的单元格赋值为空字符串。最后使用JSON.stringify()将对象转换为 JSON 字符串。
本地存储的xlsx文件内容,简单的线性回归的y = 2x:
我们打印下worksheet看看字符串内容:
3、处理Json字符串并由前端echarts可视化展示
将Json字符串转为二维数组:
python
var axisData = []
for( var i = 0;i < myobj.length; i++) {
var x = myobj[i].x
var y = myobj[i].y
var newArr = [x,y]
}
console.log("axisData:" + axisData);
打印二维数组axisData内容如下:
博主尝试了很多种方法,只有上面函数转换生成的二维数组echarts才会正常显示。
以下为其他尝试Json转数组的方法,echarts均不可识别,如果有明白的大佬请留言解释下。
python
// 获取二维数组第一种方法
const array = [[]];
for(var i = 0;i < myobj.length; i++){
array[i] = [];
for(var j=0;j<2;j++){
if(j==0){
var x = myobj[i].x;
array[i][j] = x;
console.log("array[i][j]:"+array[i][j]);
} else if (j==1) {
var y = myobj[i].y;
array[i][j] = y;
console.log("array[i][j]:"+array[i][j]);
}
}
}
// 获取二维数组第二种方法
let array2 = new Array(myobj.length); //动态定义一个二维数组
for(let i=0;i<array2.length;i++){
array2[i] = new Array(2);
for(var j=0;j<2;j++){
if(j==0){
var x = myobj[i].x;
array2[i][j] = x;
console.log("array2[i][j]:"+array2[i][j]);
} else if (j==1){
var y = myobj[i].y;
array2[i][j] = y;
console.log("array2[i][j]:"+array2[i][j]);
}
}
}
this.arrActive2 = {...array2}; //形同于arrActive2=[['','',''],['','',''],['','','']]
console.log("this.arrActive2" + this.arrActive2);
最后将axisData二维数组传递给echarts组件
python
echarts.init(document.getElementById('chart')).setOption({
xAxis: { triggerEvent: true }, // 允许点击X轴(y轴需要点击也是要加这句话)
yAxis: { triggerEvent: true },
series: [
{
symbolSize: 20,
data: axisData,
type: 'scatter'
}
]
})
用户选择已导入的xlsx数据文件,单击"展示"按钮,可视化结果散点图展示在按钮下方,完整效果如下:
4、完整的前端源码
python
<script>
import * as api from './api'
import { crudOptions } from './crud'
import { d2CrudPlus } from 'd2-crud-plus'
import * as echarts from 'echarts'
import * as XLSX from 'xlsx'
import { request } from '@/api/service'
import { AddObj, GetList, UpdateObj, DelObj } from './api' // 查询添加修改删除的http请求接口
import axios from 'axios' // Axios是一个基于promise的HTTP库(类似于jQuery的Ajax,用于HTTP请求)可以用于浏览器和node.js(既可以用于客户端也可以用于node.js编写的服务端)
// import { process_chart_data1 } from './process_data.js'
export default {
name: 'echarts',
mixins: [d2CrudPlus.crud],
mounted () {
this.pageRequest().then((res) => {
const resList = res.data.data
resList.forEach((val, index) => {
this.dataList.push({
value: val.file_url,
label: val.name
})
})
console.log(this.dataList)
})
},
data () {
return {
form: {},
dataList: [],
value: ''
}
},
methods: {
change (val) {
console.log(val)
},
onSubmit () {
// 在这设置图表option
// api
// .getFileData({
// filePath: 'this.value.value'
// })
var url = 'http://127.0.0.1:8000/' + this.value.value + '?nocache=' + (new Date()).getTime() // 本地数据库下载
axios.get(url,{ responseType: "arraybuffer" })
.then((res) => {
console.log("res:" + res)
console.log("res.data:" + res.data)
// let str = String.fromCharCode.apply(null, new Uint16Array(res.data)) // ArrayBuffer转为字符串,参数为ArrayBuffer对象
let wb = XLSX.read(res.data, {
type: 'arraybuffer'
});
// this.handle(wb);
//wb.SheetNames[0]是获取Sheets中第一个Sheet的名字
//wb.Sheets[Sheet名]获取第一个Sheet的数据
let worksheet = JSON.stringify(XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]])); // 将一个 JavaScript 对象或值转换为 JSON 字符串
console.log('worksheet:' + worksheet)
// this.worksheet是读入的JSON文件的数据,读出的数据时对象类型,要转为数组才行
// const obj= JSON.stringify(worksheet);
// var arr = [];
// for(let key in obj){
// arr.push(obj[key])
// }
// console.log("arr" + arr); // ",[,{,\,",x,\,",:,1,,,\,",y,\,",:,2,},,,{,\,",x,\,",:,2,,,\,",y,\,",:,4,},,,{,\,",x,\,",:,3,.,5,,,\,",y,\,",:,7,},,,{,\,",x,\,",:,4,,,\,",y,\,",:,8,},],"
// var myobj = worksheet;
var myobj = eval('('+worksheet+')'); // 将字符串str当成有效的表达式来求值并返回计算结果
// 获取二维数组第一种方法
// const array = [[]];
// for(var i = 0;i < myobj.length; i++){
// array[i] = [];
// for(var j=0;j<2;j++){
// if(j==0){
// var x = myobj[i].x;
// array[i][j] = x;
// console.log("array[i][j]:"+array[i][j]);
// } else if (j==1) {
// var y = myobj[i].y;
// array[i][j] = y;
// console.log("array[i][j]:"+array[i][j]);
// }
// }
// }
// 获取二维数组第二种方法
// let array2 = new Array(myobj.length); //动态定义一个二维数组
// for(let i=0;i<array2.length;i++){
// array2[i] = new Array(2);
// for(var j=0;j<2;j++){
// if(j==0){
// var x = myobj[i].x;
// array2[i][j] = x;
// console.log("array2[i][j]:"+array2[i][j]);
// } else if (j==1){
// var y = myobj[i].y;
// array2[i][j] = y;
// console.log("array2[i][j]:"+array2[i][j]);
// }
// }
// }
// this.arrActive2 = {...array2}; //形同于arrActive2=[['','',''],['','',''],['','','']]
// console.log("this.arrActive2" + this.arrActive2);
var axisData = []
for( var i = 0;i < myobj.length; i++) {
var x = myobj[i].x
var y = myobj[i].y
var newArr = [x,y]
axisData.push(newArr)
}
console.log("axisData:" + axisData);
//解析excel
// this.analysisExcel(file).then((tableJson) => {
// if (tableJson && tableJson.length > 0) {
// //成功解析出数据
// //只取第一个sheet的数据
// let dataExcel = tableJson[0];
// console.log("数据", dataExcel);
// console.log(JSON.stringify(dataExcel.sheet));
// }
// });
console.log('this.value.label' + this.value.label)
this.data = axisData
// this.data = res.data.data
switch (this.value.label) {
case '逻辑回归.xlsx':
echarts.init(document.getElementById('chart')).setOption({
xAxis: {},
yAxis: {},
series: [
{
symbolSize: 20,
data: this.data,
type: 'scatter'
}
]
})
break
case '线性回归.xlsx':
echarts.init(document.getElementById('chart')).setOption({
xAxis: { triggerEvent: true }, // 允许点击X轴(y轴需要点击也是要加这句话)
yAxis: { triggerEvent: true },
series: [
{
symbolSize: 20,
data: axisData,
type: 'scatter'
}
]
})
break
default:
break
}
})
},
getCrudOptions () {
return crudOptions(this)
},
pageRequest (query) {
return GetList(query)
},
addRequest (row) {
console.log('api', api)
return AddObj(row)
},
updateRequest (row) {
console.log('----', row)
return UpdateObj(row)
},
delRequest (row) {
return DelObj(row.id)
}
}
}
</script>