遇到一个小需求,把火星坐标系转换为wgs84坐标系,给的是一个表格,要求转换完以后导出一个表格,导出导入利用了一个插件xlsx.full.min.js直接npm下载就行
文件导入
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>导入文件并处理格式</title>
<script src="./xlsx.full.min.js"></script>
</head>
<body>
<div class="demofile"> <input type="file" onchange="importf(this)" /></div>
<button>跳转到导出</button>
<div id="demo"></div>
<script>
var rABS = false; //是否将文件读取为二进制字符串
function importf(obj) {//导入
if (!obj.files) { return; }
var f = obj.files[0];
{
var reader = new FileReader();
var name = f.name;
reader.onload = function (e) {
var data = e.target.result;
var wb;
if (rABS) {
wb = XLSX.read(data, { type: 'binary' });
} else {
var arr = fixdata(data);
wb = XLSX.read(btoa(arr), { type: 'base64' });
}
document.getElementById("demo").innerHTML = JSON.stringify(XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]]));
localStorage.setItem("datas", JSON.stringify(XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]])));
};
if (rABS) reader.readAsBinaryString(f);
else reader.readAsArrayBuffer(f);
}
setTimeout(() => {
window.location.reload()
}, 2000);
}
function fixdata(data) {
var o = "", l = 0, w = 10240;
for (; l < data.byteLength / w; ++l) o += String.fromCharCode.apply(null, new Uint8Array(data.slice(l * w, l * w + w)));
o += String.fromCharCode.apply(null, new Uint8Array(data.slice(l * w)));
return o;
}
var lon = 0;
var lat = 0;
var jsono = JSON.parse(localStorage.getItem("datas"));
var qq = jsono.map(item => {
var pi = 3.14159265358979324;
function transformLat(x, y) {
var ret =
-100.0 +
2.0 * x +
3.0 * y +
0.2 * y * y +
0.1 * x * y +
0.2 * Math.sqrt(Math.abs(x));
ret +=
((20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0) /
3.0;
ret +=
((20.0 * Math.sin(y * pi) + 40.0 * Math.sin((y / 3.0) * pi)) * 2.0) / 3.0;
ret +=
((160.0 * Math.sin((y / 12.0) * pi) + 320 * Math.sin((y * pi) / 30.0)) *
2.0) /
3.0;
return ret;
}
function transformLon(x, y) {
var ret =
300.0 +
x +
2.0 * y +
0.1 * x * x +
0.1 * x * y +
0.1 * Math.sqrt(Math.abs(x));
ret +=
((20.0 * Math.sin(6.0 * x * pi) + 20.0 * Math.sin(2.0 * x * pi)) * 2.0) /
3.0;
ret +=
((20.0 * Math.sin(x * pi) + 40.0 * Math.sin((x / 3.0) * pi)) * 2.0) / 3.0;
ret +=
((150.0 * Math.sin((x / 12.0) * pi) + 300.0 * Math.sin((x / 30.0) * pi)) *
2.0) /
3.0;
return ret;
}
function delta(lat, lon) {
let a = 6378245.0; // a: 卫星椭球坐标投影到平面地图坐标系的投影因子。
let ee = 0.00669342162296594323; // ee: 椭球的偏心率。
let dLat = transformLat(lon - 105.0, lat - 35.0);
let dLon = transformLon(lon - 105.0, lat - 35.0);
let radLat = (lat / 180.0) * pi;
let magic = Math.sin(radLat);
magic = 1 - ee * magic * magic;
let sqrtMagic = Math.sqrt(magic);
dLat = (dLat * 180.0) / (((a * (1 - ee)) / (magic * sqrtMagic)) * pi);
dLon = (dLon * 180.0) / ((a / sqrtMagic) * Math.cos(radLat) * pi);
return {
lat: dLat,
lon: dLon,
};
}
function transformGCJ2WGS(item) {
//这里的lat,与lon是我表格里面固定的俩列的表头,要处理就是他俩
const gcjLat = item.lat;
const gcjLon = item.lon;
let d = delta(gcjLat, gcjLon);
lat = gcjLat - d.lat
lon = gcjLon - d.lon
return {
lat: gcjLat - d.lat,
lng: gcjLon - d.lon,
};
}
// console.log(transformGCJ2WGS(item));
// console.log(lat, lon);
item.lat = transformGCJ2WGS(item).lat.toFixed(8);
item.lon = transformGCJ2WGS(item).lng.toFixed(8);
return item;
});
// console.log(qq);
// localStorage.setItem("datass", qq);
document.querySelector('button').addEventListener('click', function (e) {
localStorage.setItem('d', JSON.stringify(qq));
window.location.reload()
window.location.href = './导出文件.html';
localStorage.removeItem('datas')
});
localStorage.removeItem('d')
</script>
</body>
</html>
文件导出
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>导出文件</title>
<script src="./xlsx.full.min.js"></script>
<style>
.daochu {
height: 50px;
width: 80px;
}
div {
display: flex;
justify-content: space-between;
}
</style>
</head>
<body>
<div>
<button class="daochu" onclick="downloadExl(jsono)">导出</button>
<button class="back">返回到导入</button>
</div>
<!--
以下a标签不需要内容
-->
<a href="" download="导出的文件.xlsx" id="hf"></a>
<script>
var jsono = JSON.parse(localStorage.getItem('d'));
var jsonolength = jsono.length;
var tmpDown; //导出的二进制对象
function downloadExl(json, type) {
var tmpdata = json[0];
if (json.length <= jsonolength) {
json.unshift({});
}
var keyMap = []; //获取keys
//keyMap =Object.keys(json[0]);
for (var k in tmpdata) {
keyMap.push(k);
json[0][k] = k;
}
var tmpdata = [];//用来保存转换好的json
json.map((v, i) => keyMap.map((k, j) => Object.assign({}, {
v: v[k],
position: (j > 25 ? getCharCol(j) : String.fromCharCode(65 + j)) + (i + 1)
}))).reduce((prev, next) => prev.concat(next)).forEach((v, i) => tmpdata[v.position] = {
v: v.v
});
var outputPos = Object.keys(tmpdata); //设置区域,比如表格从A1到D10
var tmpWB = {
SheetNames: ['mySheet'], //保存的表标题
Sheets: {
'mySheet': Object.assign({},
tmpdata, //内容
{
'!ref': outputPos[0] + ':' + outputPos[outputPos.length - 1] //设置填充区域
})
}
};
tmpDown = new Blob([s2ab(XLSX.write(tmpWB,
{ bookType: (type == undefined ? 'xlsx' : type), bookSST: false, type: 'binary' }//这里的数据是用来定义导出的格式类型
))], {
type: ""
}); //创建二进制对象写入转换好的字节流
var href = URL.createObjectURL(tmpDown); //创建对象超链接
document.getElementById("hf").href = href; //绑定a标签
document.getElementById("hf").click(); //模拟点击实现下载
setTimeout(function () { //延时释放
URL.revokeObjectURL(tmpDown); //用URL.revokeObjectURL()来释放这个object URL
}, 100);
}
function s2ab(s) { //字符串转字符流
var buf = new ArrayBuffer(s.length);
var view = new Uint8Array(buf);
for (var i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
return buf;
}
// 将指定的自然数转换为26进制表示。映射关系:[0-25] -> [A-Z]。
function getCharCol(n) {
let temCol = '',
s = '',
m = 0
while (n > 0) {
m = n % 26 + 1
s = String.fromCharCode(m + 64) + s
n = (n - m) / 26
}
return s
}
document.querySelector('.back').addEventListener('click', function () {
window.location.href = './导入文件.html';
})
</script>
</body>
</html>