基于 Nuxt.js实现在线Excel
本帖最后由 Richard.Ma 于 2022-12-30 18:10 编辑Nuxt.js 是一个基于 Vue.js 的通用应用框架,一个用于Vue.js 开发SSR应用的一站式解决方案。它的优点是将原来几个配置文件要完成的内容,都整合在了一个nuxt.config.js,封装与扩展性完美的契合。
简单来说,nuxtjs项目就是一个vue的项目融合一个node.js server项目,这里node服务有两个作用,第一点是代替浏览器的工作,笼统理解就是在created时的请求数据和页面渲染,第二点是当作静态文件服务器,把渲染好的页面返回给用户。
要在 Nuxt.js中实现在线Excel,通过引入SpreadJS可以轻松实现这一点,这篇文章会分享如何通过SpreadJS在Nuxt.js中实现在线Excel
在将 SpreadJS 放入Nuxt.js之前,我们必须首先创建一个Nuxt.js项目。在本教程中,我们将使用 Nuxt.js提供的脚手架工具create-nuxt-app使用npx create-nuxt-app <项目名>即可快速创建一个 Nuxt.js项目。创建过程中会有一些选项,创建完成后的项目文件结构如下
在创建成功后通过npm run build编译后,即可通过npm start运行。接下来,我们在项目中引入spreadjs,
1.在package.json文件中添加spreadjs相关包 "@grapecity/spread-excelio": "15.2.1",
"@grapecity/spread-sheets": "15.2.1",
"@grapecity/spread-sheets-resources-zh": "15.2.1",
"@grapecity/spread-sheets-vue": "15.2.1"
2.在component文件夹中添加一个SpreadJS.vue文件和我们在普通的vue项目中一样通过在template中添加gc-spread-sheets标签即可添加spreadjs 的工作簿,这里需要注意的一点是,由于Nuxt.js默认会把组件作为服务端组件来编译,所以这里需要给外层额外添加一个<client-only>标签来让nuxt编译时作为客户端组件编译,另外,我们也顺便加入了用于导入导出功能的按钮和文件输入框<template>
<div class="sample-tutorial">
<button @click="exportexcel">导出excel</button>
<input type="file" id="fileDemo" class="input" @change="changeFileDemo">
<input type="button" id="loadExcel" value="import" class="button" @click="loadExcel">
<client-only placeholder="loading...">
<gc-spread-sheets :hostClass="hostClass" @workbookInitialized="initwb">
<gc-worksheet>
</gc-worksheet>
<gc-worksheet> </gc-worksheet>
</gc-spread-sheets>
</client-only>
</div>
</template>
3.导入spreadjs相关组件
在普通的vue项目中,我们只需要通过import所需的 spreadjs包即可,但是在Nuxt.js中,如果直接import到我们刚刚创建的vue文件中,会提示"document is not defined"错误,原因和上面提到的类似。解决办法是。新建一个js文件。在其中import相关的包。然后在配置文件nuxt.config.js中,将其做为plugins引入,ssr设置为false,这样就可以避免上述问题。我们新建了一个spreadjs.js文件,写入了下面的内容
import "@grapecity/spread-sheets-vue";
最后是vue文件中的script部分,可以看到只有css是通过import 引入的,这个不会受到影响
对导入导出功能需要使用的spread-excelio包,我们通过require方法,在加载时再动态导入,避免了编译时提到的上述问题。
<script >
import "@grapecity/spread-sheets/styles/gc.spread.sheets.excel2016colorful.css";
var ExcelIO={};
export default {
name: "SpreadJS",
data() {
return {
hostClass: "spread-host",
autoGenerateColumns: true,
width: 300,
visible: true,
resizable: true,
formatter: "$ #.00",
};
},
computed: {
dataTable() {
let dataTable = [];
for (let i = 0; i < 42; i++) {
dataTable.push(i + 0.56);
}
return dataTable;
},
},
methods: {
initwb: function (spread) {
this.spread = spread;
spread.getSheet(0).setArray(0, 0, this.dataTable);
spread.getSheet(1).visible(false);
},
exportexcel: function () {
let spread = this.spread;
let excelIo = new ExcelIO.IO();
let fileName = "test.xlsx";
let password = this.password;
if (fileName.substr(-5, 5) !== ".xlsx") {
fileName += ".xlsx";
}
let json = spread.toJSON();
// here is excel IO API
excelIo.save(
json,
function (blob) {
let url = window.URL.createObjectURL(blob);
let link = document.createElement("a");
link.style.display = "none";
link.href = url;
link.setAttribute("download", fileName);
document.body.appendChild(link);
link.click();
document.body.removeChild(link); // 下载完成移除元素
window.URL.revokeObjectURL(url);
//saveAs(blob, fileName);
},
function (e) {
// process error
console.log(e);
},
{
password: password,
}
);
},
changeFileDemo(e) {
this.importExcelFile = e.target.files;
},
loadExcel(e) {
let spread = this.spread;
let excelIo = new ExcelIO.IO();
let excelFile = this.importExcelFile;
// here is excel IO API
excelIo.open(excelFile, function (json) {
let workbookObj = json;
spread.fromJSON(workbookObj);
}, function (e) {
// process error
alert(e.errorMessage);
});
}
},
mounted:function(){
ExcelIO=require("@grapecity/spread-excelio");
}
};
</script>
最终运行效果
最后附上demo
页:
[1]