first commit

This commit is contained in:
liyunjia 2025-01-04 12:59:36 +08:00
parent fbe1f56cca
commit 13fc866e8e
6 changed files with 1130 additions and 76 deletions

909
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -8,8 +8,11 @@
"lint": "vue-cli-service lint" "lint": "vue-cli-service lint"
}, },
"dependencies": { "dependencies": {
"axios": "^1.7.9",
"core-js": "^3.8.3", "core-js": "^3.8.3",
"vue": "^2.6.14" "vue": "^2.6.14",
"x-data-spreadsheet": "^1.1.9",
"xlsx": "^0.16.0"
}, },
"devDependencies": { "devDependencies": {
"@babel/core": "^7.12.16", "@babel/core": "^7.12.16",
@ -19,6 +22,8 @@
"@vue/cli-service": "~5.0.0", "@vue/cli-service": "~5.0.0",
"eslint": "^7.32.0", "eslint": "^7.32.0",
"eslint-plugin-vue": "^8.0.3", "eslint-plugin-vue": "^8.0.3",
"less": "^4.2.1",
"less-loader": "^12.2.0",
"vue-template-compiler": "^2.6.14" "vue-template-compiler": "^2.6.14"
}, },
"eslintConfig": { "eslintConfig": {

View File

@ -1,17 +1,16 @@
<template> <template>
<div id="app"> <div id="app">
<img alt="Vue logo" src="./assets/logo.png"> <ExcelComponent msg="Welcome to Your Vue.js App"/>
<HelloWorld msg="Welcome to Your Vue.js App"/>
</div> </div>
</template> </template>
<script> <script>
import HelloWorld from './components/HelloWorld.vue' import ExcelComponent from './components/ExcelComponent.vue';
export default { export default {
name: 'App', name: 'App',
components: { components: {
HelloWorld ExcelComponent
} }
} }
</script> </script>
@ -23,6 +22,5 @@ export default {
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;
text-align: center; text-align: center;
color: #2c3e50; color: #2c3e50;
margin-top: 60px;
} }
</style> </style>

View File

@ -0,0 +1,103 @@
<template>
<div>
<button @click="loadExcel">从MinIO加载Excel文件</button>
<button @click="saveExcel">将Excel文件保存至MinIO</button>
<div id="x-spreadsheet"></div>
</div>
</template>
<script>
import axios from 'axios';
import 'x-data-spreadsheet/dist/xspreadsheet.css';
import zhCN from 'x-data-spreadsheet/src/locale/zh-cn';
import x_spreadsheet from 'x-data-spreadsheet';
import XLSX from 'xlsx';
import { stox, xtos } from '@/utils/xlsxspread';
export default {
name: 'ExcelComponent',
data() {
return {
spreadsheet: null,
};
},
mounted() {
x_spreadsheet.locale('zh-cn', zhCN);
this.spreadsheet = new x_spreadsheet('#x-spreadsheet', {
mode: 'edit',
showToolbar: true,
showGrid: true,
showContextmenu: true,
showBottomBar: true,
view: {
height: () => document.documentElement.clientHeight * 0.9,
width: () => document.documentElement.clientWidth,
},
row: {
len: 100,
height: 25,
},
col: {
len: 26,
width: 100,
indexWidth: 60,
minWidth: 60,
},
style: {
bgcolor: '#ffffff',
align: 'left',
valign: 'middle',
textwrap: false,
strike: false,
underline: false,
color: '#0a0a0a',
font: {
name: 'Helvetica',
size: 10,
bold: false,
italic: false,
},
},
});
},
methods: {
loadExcel() {
const minioUrl = 'http://47.95.198.7:30000/tmp/123.xlsx';
axios.get(minioUrl, { responseType: 'arraybuffer' })
.then(response => {
const data = new Uint8Array(response.data);
const workbook = XLSX.read(data, { type: 'array' });
this.spreadsheet.loadData(stox(workbook));
})
.catch(error => console.error('加载文件失败:', error));
},
saveExcel() {
const data = this.spreadsheet.getData();
const workbook = xtos(data);
const excelBuffer = XLSX.write(workbook, { bookType: 'xlsx', type: 'array' });
const blob = new Blob([excelBuffer], { type: 'application/octet-stream' });
const minioUploadUrl = 'http://47.95.198.7:30000/tmp/123.xlsx';
axios.put(minioUploadUrl, blob, {
headers: {
'Content-Type': 'application/octet-stream',
}
})
.then(response => {
console.log('文件上传成功', response);
})
.catch(error => console.error('文件上传失败:', error));
}
}
};
</script>
<style scoped>
#x-spreadsheet {
width: 100%;
height: 500px;
margin-bottom: 20px;
}
</style>

View File

@ -1,58 +0,0 @@
<template>
<div class="hello">
<h1>{{ msg }}</h1>
<p>
For a guide and recipes on how to configure / customize this project,<br>
check out the
<a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
</p>
<h3>Installed CLI Plugins</h3>
<ul>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" target="_blank" rel="noopener">babel</a></li>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint" target="_blank" rel="noopener">eslint</a></li>
</ul>
<h3>Essential Links</h3>
<ul>
<li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a></li>
<li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a></li>
<li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a></li>
<li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a></li>
<li><a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a></li>
</ul>
<h3>Ecosystem</h3>
<ul>
<li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li>
<li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li>
<li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtools</a></li>
<li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li>
<li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li>
</ul>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
props: {
msg: String
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h3 {
margin: 40px 0 0;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>

121
src/utils/xlsxspread.js Normal file
View File

@ -0,0 +1,121 @@
import XLSX from "xlsx";
/**
* 将SheetJS数据转换成x-spreadsheet数据
*/
export function stox(wb) {
var out = [];
wb.SheetNames.forEach(function (name) {
var o = { name: name, rows: {} };
var ws = wb.Sheets[name];
if (!ws || !ws["!ref"]) return;
var range = XLSX.utils.decode_range(ws['!ref']);
// sheet_to_json will lost empty row and col at begin as default
range.s = { r: 0, c: 0 };
var aoa = XLSX.utils.sheet_to_json(ws, {
raw: false,
header: 1,
range: range
});
aoa.forEach(function (r, i) {
var cells = {};
r.forEach(function (c, j) {
cells[j] = { text: c || String(c) };
var cellRef = XLSX.utils.encode_cell({ r: i, c: j });
if (ws[cellRef] != null && ws[cellRef].f != null) {
cells[j].text = "=" + ws[cellRef].f;
}
});
o.rows[i] = { cells: cells };
});
o.rows.len = aoa.length + 1;
o.merges = [];
(ws["!merges"] || []).forEach(function (merge, i) {
//Needed to support merged cells with empty content
if (o.rows[merge.s.r] == null) {
o.rows[merge.s.r] = { cells: {} };
}
if (o.rows[merge.s.r].cells[merge.s.c] == null) {
o.rows[merge.s.r].cells[merge.s.c] = {};
}
o.rows[merge.s.r].cells[merge.s.c].merge = [
merge.e.r - merge.s.r,
merge.e.c - merge.s.c
];
o.merges[i] = XLSX.utils.encode_range(merge);
});
out.push(o);
});
return out;
}
/**
* x-spreadsheet数据转换成SheetJS数据
*/
export function xtos(sdata) {
var out = XLSX.utils.book_new();
sdata.forEach(function (xws) {
var ws = {};
var rowobj = xws.rows;
var minCoord = { r: 0, c: 0 }, maxCoord = { r: 0, c: 0 };
for (var ri = 0; ri < rowobj.len; ++ri) {
var row = rowobj[ri];
if (!row) continue;
Object.keys(row.cells).forEach(function (k) {
var idx = +k;
if (isNaN(idx)) return;
var lastRef = XLSX.utils.encode_cell({ r: ri, c: idx });
if (ri > maxCoord.r) maxCoord.r = ri;
if (idx > maxCoord.c) maxCoord.c = idx;
var cellText = row.cells[k].text, type = "s";
if (!cellText) {
cellText = "";
type = "z";
} else if (!isNaN(Number(cellText))) {
cellText = Number(cellText);
type = "n";
} else if (cellText.toLowerCase() === "true" || cellText.toLowerCase() === "false") {
cellText = Boolean(cellText);
type = "b";
}
ws[lastRef] = { v: cellText, t: type };
if (type == "s" && cellText[0] == "=") {
ws[lastRef].f = cellText.slice(1);
}
if (row.cells[k].merge != null) {
if (ws["!merges"] == null) ws["!merges"] = [];
ws["!merges"].push({
s: { r: ri, c: idx },
e: {
r: ri + row.cells[k].merge[0],
c: idx + row.cells[k].merge[1]
}
});
}
});
}
ws["!ref"] = minCoord ? XLSX.utils.encode_range({
s: minCoord,
e: maxCoord
}) : "A1";
XLSX.utils.book_append_sheet(out, ws, xws.name);
});
return out;
}