1 表格
效果图:
此处主要描述是将js改写成ts所遇到的坑🕳。
在读取成Uint8Array,再转换为Unicode编码时,之前的js中,这样写是没问题的,但是在ts中则会报类型不匹配的错误,需要使用as转换成相匹配的类型。
// js let bytes = new Uint8Array(reader.result); // ts let bytes = new Uint8Array(reader.result as ArrayBuffer);
此外,在导出excel函数中,之前使用ES6语法的const { columns } = this;
在ts响应会出现错误。
const { columns } = this; //等于 const columns = this.columns;
可以使用原生js,当然也可以使用tslint的校验忽略:在代码上一行加上tslint注释// tslint:disable
。
2 处理坐标
将上传与导出做成按钮组件,在上传文件后,选用vuex进行非关系型组件之间通信。
2.1 vuex模块化
store目录如下:
采用vuex中的modules模块化。在StoreFactory.ts文件中,封装store类。user.ts中写具体的user模块内成员变量,mutiations、actions中的方法名使用storeConst成员变量。
import { StoreDataModuleBase } from '../helper/StoreFactory'; import StoreConst from '../storeConst'; // tslint:disable-next-line: class-name export class excelData { public data: object[] = []; } class StateDcvMain { public excel_Data: excelData = new excelData(); } export const StoreData = new StoreDataModuleBase<StateDcvMain, any>( new StateDcvMain(), // getter { GetExcelData: (state: StateDcvMain, getters: any) => { return state.excel_Data; } }, // mutiations { [StoreConst.UPDATE_DATA]: (state: StateDcvMain, value: excelData) => { state.excel_Data = value; } }, // actions { [StoreConst.UPDATE_DATA_COMMIT]: ({ commit }: any, value: any) => { return new Promise((resolve, reject) => { commit('UpdateData', value); resolve(); }); } } ); // storeConst.ts export default class StoreConst { public static UPDATE_DATA = 'UpdateData'; public static UPDATE_DATA_COMMIT = 'UpdateDataCommit'; }
在index的Vuex中声明modulesStoreData
。
const Store = new Vuex.Store({ modules: { StoreData } }); export default Store;
在导入文件,获取文件json后,将其写入vuex的excel_Data中。
that.$store.dispatch('UpdateDataCommit', that.upData).then(() => { if (that.$store.getters.GetExcelData.length !== 0) { alert('上传成功!'); } // 读取 console.log(this.$store.getters.GetExcelData);
2.2 处理数据
查看百度api,可以发现,转换接口一次上限传递100个坐标,此时,就需要考虑上传的json数组长度是否超过100。 将导出excel绑定down方法,
<template> <div class="export"> <button @click="down"> <slot>导出Excel</slot> </button> </div> </template>
private points: object[] = []; private down() { this.points = this.$store.getters.GetExcelData; this.points.length <= 100 ? this.change1(this.points) : this.change2(this.points); this.ExportExcel(); } // 获取到的数据格式: // [ // { x: '121.325543', y: '31.763342' }, // { x: '121.355543', y: '31.463342' }, // { x: '121.324543', y: '31.763352' } // ] // 需要处理成的格式 // '114.21892734521,29.575429778924;114.21892794521,29.575429778924;114.21892734521,29.579029778924'
此时需要分两种情况讨论:
- 长度小于100
使用map遍历数组,进行字符串拼接。
private change1(p: object[]) { let str = p.map((_: any) => _.x + ',' + _.y + ';').join(''); this.changeBd(str.substring(0, str.lastIndexOf(';'))); }
- 长度大于100
使用group方法,将其分成最大长度为100的二维数组,再使用map进行遍历(reduce也可)。
private change2(p: object[]) { // tslint:disable this.group(p, 100).map(_ => { let s = _.map((c: any) => c.x + ',' + c.y + ';').join(''); this.changeBd(s.substring(0, s.lastIndexOf(';'))); }); } // 数组变为多维数组 private group(array: object[], subGroupLength: number) { let index = 0; let newArray = []; while (index < array.length) { newArray.push(array.slice(index, (index += subGroupLength))); } return newArray; }
3 调用第三方接口
百度web服务API可查看接口功能介绍。
安装好axios(yarn add axios
),采用局部导入即可。 接口调用代码如下,获取到数据后需要将多维转为一维,将一维数组导出成excel。
private changeBd(arg: string) { $axios .get( '/api/geoconv/v1/?coords=' + arg + '&from=1&to=5&ak=G54LAaflEVRcUG0CfwtdONWRDFuACnWa' ) // tslint:disable .then(res => { // 拿到后台数据赋值给前端 this.newArr.push(res.data.result); // 降维 this.newArr = this.newArr.reduce((p: any, c: any) => p.concat(c), []); }) // tslint:disable .catch(err => { console.log('错误信息:' + err); }); }
在调用的时候,如果直接拼成百度的接口,会出现跨域问题。使用第三方接口的时候可以使用proxy代理,或者后端代理。在此我使用vue的proxy代理。
proxy代理:在项目根目录新建一个vue.config.js文件。
module.exports = { publicPath: "/", devServer: { proxy: { '/api': { target: 'http://api.map.baidu.com', changeOrigin: true,//是否跨域 开启代理:在本地创建一个虚拟服务器 // ws: true,//是否代理websockets // secure: false,//如果是https接口,需要配置这个参数 pathRewrite: { '^/api': '' } //重写路径 } }, open: true }, }
点击clying GitHub可查看源码。
作者:ClyingDeng
链接:https://juejin.cn/post/6869736267149246478
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。