1.安装
https://www.npmjs.com/package/@grapecity/spread-sheets
https://demo.grapecity.com.cn/spreadjs/SpreadJSTutorial/quickstart/quickstart-vue
2.代码
把主要文件放在了组件中
子组件
<template>
<div class="spreadcontainer">
<gc-spread-sheets class="spread-host" @workbookInitialized="workbookInitialized">
<gc-worksheet :dataSource="dataSource" :autoGenerateColumns="autoGenerateColumns">
<gc-column :dataField="' '" :width="80"></gc-column>
<gc-column :dataField="'项目代号'" :width="160"></gc-column>
<gc-column :dataField="'编号'" :width="170"></gc-column>
<gc-column :dataField="'名称、型号、规格'" :width="190"></gc-column>
<gc-column :dataField="'数量'" :width="110"></gc-column>
<gc-column :dataField="'备注'" :width="180"></gc-column>
</gc-worksheet>
</gc-spread-sheets>
</div>
</template>
<script>
import "@grapecity/spread-sheets/styles/gc.spread.sheets.excel2013white.css"
import "@grapecity/spread-sheets-vue/dist/gc.spread.sheets.vue.min.js"
import * as GC from "@grapecity/spread-sheets/dist/gc.spread.sheets.all.min.js"
import "@grapecity/spread-sheets-resources-zh"
GC.Spread.Common.CultureManager.culture("zh-cn")
export default {
name: "HelloWorld",
data() {
return {
autoGenerateColumns: false,
spread: null,
col: ["项目代号", "编号", "名称、型号、规格", "数量", "备注"]
}
},
props: ["dataSource", "status"],
methods: {
workbookInitialized(spread) {
this.spread = spread
let that = this
// 编辑的编号回车传递
spread.bind(GC.Spread.Sheets.Events.EditChange, function(sender, args) {
that.$parent.$parent.edittext(args.editingText)
})
// 输入完成切换单元格触发
spread.bind(GC.Spread.Sheets.Events.CellChanged, function(e, info) {
if (info.sheetArea === GC.Spread.Sheets.SheetArea.viewport) {
that.$parent.$parent.quiteedit()
}
})
// 点击的单元格
spread.bind(GC.Spread.Sheets.Events.CellClick, function(sender, args) {
that.$parent.$parent.clickposition(args.row, args.col)
})
// 点击插入行或者删除行重新渲染数据(为了页数可以展示)
spread.bind(GC.Spread.Sheets.Events.RowChanged, function(e, info) {
console.log(info)
if (info.propertyName === "addRows" || info.propertyName === "deleteRows") {
that.$parent.$parent.addpagenum()
console.log(that)
}
})
// 单元格失去焦点清除
// 去除sheet页
spread.options.tabStripVisible = false
spread.invalidateLayout()
spread.repaint()
// 表单保护
let sheet = spread.getActiveSheet()
sheet.getRange(-1, 3, -1, 1, GC.Spread.Sheets.SheetArea.viewport).wordWrap(true)
var defaultStyle = new GC.Spread.Sheets.Style()
defaultStyle.locked = false
sheet.setDefaultStyle(defaultStyle, GC.Spread.Sheets.SheetArea.viewport)
var style = new GC.Spread.Sheets.Style()
style.locked = true
sheet.setStyle(-1, 0, style)
let option = {
allowSelectLockedCells: true,
allowSelectUnlockedCells: true,
allowFilter: false,
allowSort: false,
allowResizeRows: true,
allowResizeColumns: false,
allowEditObjects: false,
allowDragInsertRows: false,
allowDragInsertColumns: false,
allowInsertRows: false,
allowInsertColumns: false,
allowDeleteRows: false,
allowDeleteColumns: false
}
sheet.options.protectionOptions = option
sheet.options.isProtected = true
// 删除回车键切换单元格的操作
spread.commandManager().setShortcutKey(undefined, GC.Spread.Commands.Key.enter, false, false, false, false)
// 注册键盘回车事件
spread.commandManager().register(
"myCmd",
function ColorAction() {
//单击一个单元格,然后按Enter键。
that.$parent.$parent.getdlbdata()
},
13
)
// 对右键的菜单栏更改
var menuData = spread.contextMenu.menuData
console.log(menuData)
var newMenuData = []
menuData.forEach(function(item) {
if (item) {
if (item.text === "全部粘贴") {
item.text = "粘贴"
}
if (item.name === "gc.spread.copy" || item.name === "gc.spread.cut" || item.name === "gc.spread.pasteAll") {
item.workArea = "viewportrowHeaderslicercorner"
}
if (item.name === "gc.spread.copy" || item.name === "gc.spread.cut" || item.name === "gc.spread.clearContents" || item.name === "gc.spread.pasteAll") {
item.workArea = "viewportslicercorner"
}
if (
item.name === "gc.spread.filter" ||
item.name === "gc.spread.sort" ||
item.workArea === "colHeader" ||
item.workArea === "sheetTab" ||
!item.name ||
item.workArea === "viewportcorner" ||
item.workArea === "slicer" ||
item.name === "gc.spread.pasteOptions" ||
item.name === "gc.spread.pasteFormula" ||
item.name === "gc.spread.pasteValues" ||
item.name === "gc.spread.pasteFormatting" ||
item.name === "gc.spread.hideRows" ||
item.name === "gc.spread.unhideRows"
) {
return
}
newMenuData.push(item)
}
})
spread.contextMenu.menuData = newMenuData
console.log(spread.contextMenu.menuData)
}
}
}
</script>
<style lang="scss" scoped>
.spreadcontainer {
height: 100%;
width: 100%;
.spread-host {
height: 100%;
width: 100%;
/deep/ table {
tr {
td {
.gc-scroll-container {
.gc-scrollbar-wrapper {
left: 0;
}
.gc-scroll-arrow {
left: 0;
}
}
}
}
}
}
}
</style>
父组件
<!--
* @Author: wangn
* @Date: 2020-06-10 13:51:21
* @LastEditors: wangn
* @Description:
-->
<template>
<div id="listcontainer">
<div class="searchbox">
<div class="picnum">
<span>图号</span>
<input type="text" v-model="PicNum" />
</div>
<div class="name">
<span>名称</span>
<input type="text" v-model="Name" />
</div>
</div>
<div class="btns">
<p @click="filterevent">查询</p>
<p @click="restart">重置</p>
</div>
<div class="curd">
<p @click="add">
<i class="el-icon-plus"></i>
<span>新增</span>
</p>
<p @click="quote">
<i class="el-icon-plus"></i>
<span>引用</span>
</p>
<p @click="change">
<i class="el-icon-edit"></i>
<span>修改</span>
</p>
<p @click="del">
<i class="el-icon-minus"></i>
<span>删除</span>
</p>
<p @click="outfile">
<i class="el-icon-download"></i>
<span>导出</span>
</p>
<p @click="showuploadbox">
<i class="el-icon-upload2"></i>
<span>导入</span>
</p>
</div>
<div class="tablebox">
<table border="0" cellspacing="0">
<thead>
<tr>
<th></th>
<th @click="allchosebtn">
<input type="checkbox" :checked="chosearr.length === nowpageleng" />
</th>
<th>操作</th>
<th>图号</th>
<th>名称</th>
<th>创建者</th>
<th>创建时间</th>
<th>状态</th>
</tr>
</thead>
<tbody>
<tr v-for="(item, index) in tableData" :key="index" :style="{ background: index % 2 == 0 ? '' : '#eeeeee' }">
<td>
{{ (tablecurrentPage - 1) * tablepagesize + index + 1 }}
</td>
<td @click="singlechose(item.id)">
<input type="checkbox" :checked="chosearr.indexOf(item.id) !== -1" />
</td>
<td class="look" title="查看" @click="lookdetail(item.id)"><i class="el-icon-view"></i></td>
<td>{{ item.dLBNumber }}</td>
<td>{{ item.dLBName }}</td>
<td>{{ item.firstFullName }}</td>
<td>{{ item.createTime }}</td>
<td>{{ item.dLBState }}</td>
</tr>
</tbody>
</table>
</div>
<div class="paginate">
<el-pagination
background
@size-change="changetablelang"
@current-change="changetablepage"
:current-page="tablecurrentPage"
:page-sizes="[10, 20, 30]"
:page-size="tablepagesize"
prev-text="< 上一页 "
next-text=" 下一页 >"
layout="total, sizes, prev, pager, next, jumper"
:total="tabletotal"
></el-pagination>
</div>
<el-dialog title="新增" :visible.sync="dialogVisible" width="60%" :before-close="handleClose" :close-on-click-modal="false">
<div class="dialogmain">
<div class="tabletop">
<p class="basisinfo">基础信息</p>
<div class="info">
<div class="picnum">
<span>图号</span>
<i v-if="status !== '查看'">*</i>
<input type="text" :disabled="status == '查看'" v-model="DLBNumber" />
</div>
<div class="name">
<span>名称</span>
<i v-if="status !== '查看'">*</i>
<input type="text" :disabled="status == '查看'" v-model="DLBName" />
</div>
<div>
<p @click="fromdlb" v-if="status !== '查看'">从DLB中选择数据</p>
</div>
</div>
<p>元件目录表</p>
</div>
<div class="dialogtable">
<spread ref="spread" :dataSource="dataSource" :status="status" />
<!-- <table border="0" cellspacing="0">
<thead>
<tr>
<th></th>
<th></th>
<th>项目代号</th>
<th>编号</th>
<th>名称、型号、规格</th>
<th>数量</th>
<th>备注</th>
</tr>
</thead>
<tbody>
<tr v-for="(item, index) in dialogData" :key="index" :style="{ background: index % 2 == 0 ? '' : '#eeeeee' }">
<td>
{{ (dialogcurrentPage - 1) * 33 + index + 1 }}
</td>
<td class="look" title="查看" @click="jumpdlb(index)"><span v-if="status !== '查看'">搜索</span></td>
<td><input type="text" v-model="item.projectNumber" :style="{ background: index % 2 == 0 ? '' : '#eeeeee' }" :disabled="!canedit" /></td>
<td><input type="text" v-model="item.itemNumber" :style="{ background: index % 2 == 0 ? '' : '#eeeeee' }" :disabled="!canedit" /></td>
<td><input type="text" v-model="item.itemName" :style="{ background: index % 2 == 0 ? '' : '#eeeeee' }" :disabled="!canedit" /></td>
<td><input type="text" v-model="item.itemQuantity" :style="{ background: index % 2 == 0 ? '' : '#eeeeee' }" :disabled="!canedit" /></td>
<td><input type="text" v-model="item.remarks" :style="{ background: index % 2 == 0 ? '' : '#eeeeee' }" :disabled="!canedit" /></td>
</tr>
</tbody>
</table> -->
</div>
<!-- <div class="paginate">
<el-pagination
background
@current-change="changedialogpage"
:current-page="dialogcurrentPage"
:page-sizes="[33]"
:page-size="dialogpagesize"
prev-text="< 上一页 "
next-text=" 下一页 >"
layout="total, sizes, prev, pager, next, jumper"
:total="dialogtotal"
></el-pagination>
</div> -->
</div>
<span slot="footer" class="dialog-footer">
<!-- <el-button type="primary" @click="addnewpage" v-if="status !== '查看'">新增一页</el-button> -->
<!-- <el-button type="primary" @click="delpage" v-if="status !== '查看'">删除本页</el-button> -->
<el-button type="primary" @click="submit" v-if="status !== '查看'">提交</el-button>
<el-button @click="closedialog">取消</el-button>
</span>
</el-dialog>
<el-dialog title="dlb" :visible.sync="showdlb" width="80%" :before-close="handleClosedlb" class="dlbpage" :close-on-click-modal="false">
<dlb />
</el-dialog>
<el-dialog title="文件上传" :visible.sync="uploadbox" width="20%" :before-close="handleCloseuploadbox" class="upload">
<input type="file" id="file" @change="importfile($event)" />
<button @click="uploadevent">确认上传</button>
</el-dialog>
</div>
</template>
<script>
import spread from "../../../../components/spread"
import dlb from "../dlb/index"
import { datagrid, findOneById, saveDLBItemData, checkDLBDatas, delByIds, doExportDatas, doImportExcel, lookshoucang, findByMaterId } from "../../../../api/index"
export default {
components: {
spread,
dlb
},
data() {
return {
PicNum: "",
Name: "",
localPicNum: "",
localName: "",
tablecurrentPage: 1,
tablepagesize: 10,
dialogcurrentPage: 1,
dialogpagesize: 10,
tabletotal: 0,
dialogtotal: 0,
dialogVisible: false,
tableData: [],
dialogData: [],
canedit: true,
status: "",
chosearr: [],
dlbshow: false,
DLBNumber: "",
DLBName: "",
id: "",
alladdData: [],
nowpageleng: 10,
uploadbox: false,
formData: {},
menushow: false,
dlbindex: 0,
showdlb: false,
dlbsrc: "",
dataSource: [],
position: 0,
positioncol: 0,
editingText: ""
}
},
methods: {
// // 鼠标右击
// showmenuevent(e, item, index) {
// // console.log(index)
// // console.log((this.dialogcurrentPage - 1) * 33 + index)
// if (this.status !== "查看") {
// this.menuTop = e.clientY + "px"
// this.menuLeft = e.clientX + "px"
// this.menushow = true
// this.readydata = item
// this.pasteindex = index
// }
// },
// copy() {
// console.log("复制")
// console.log(this.pasteindex)
// console.log((this.dialogcurrentPage - 1) * 33 + this.pasteindex)
// },
// paste() {
// console.log("粘贴")
// console.log(this.pasteindex)
// },
fromdlb() {
// 从dlb中获取数据后,调取子组件中的方法,将获取的数据传入子组件
this.jumpdlb()
console.log(111)
},
handleClose(done) {
done()
this.canedit = true
this.status = ""
this.DLBNumber = ""
this.DLBName = ""
},
handleCloseuploadbox(done) {
done()
},
handleClosedlb(done) {
done()
},
closedialog() {
this.dialogVisible = false
this.canedit = true
this.status = ""
this.DLBNumber = ""
this.DLBName = ""
},
changelang(val) {
console.log(val)
},
changepage(val) {
console.log(val)
},
getdialogevent() {
console.log(this.dialogData)
},
// table的分页
changetablelang(val) {
this.chosearr = []
this.tablepagesize = val
this.tablecurrentPage = 1
this.gettableData(this.localPicNum, this.localName, this.tablecurrentPage, this.tablepagesize)
},
changetablepage(val) {
this.chosearr = []
this.tablecurrentPage = val
this.gettableData(this.localPicNum, this.localName, this.tablecurrentPage, this.tablepagesize)
},
lookdetail(id) {
this.status = "查看"
this.canedit = false
this.dialogVisible = true
this.id = id
// 获取查看数据
this.getdialogData(this.id)
},
// 查看dialogData
getdialogData(id) {
findOneById(id).then(res => {
console.log(res)
if (res.data.obj) {
this.dataSource = res.data.obj.dlbItemList
this.DLBNumber = res.data.obj.dlbInfo.DLBNumber
this.DLBName = res.data.obj.dlbInfo.DLBName
}
})
},
// 获取tableData
gettableData(PicNum, Name, page, rows) {
datagrid(PicNum, Name, page, rows).then(res => {
if (res.data) {
this.tableData = res.data.rows
this.nowpageleng = res.data.rows.length
this.tabletotal = res.data.total
}
})
},
filterevent() {
this.localPicNum = this.PicNum
this.localName = this.Name
this.tablepagesize = 10
this.tablecurrentPage = 1
this.gettableData(this.localPicNum, this.localName, this.tablecurrentPage, this.tablepagesize)
},
restart() {
this.PicNum = ""
this.Name = ""
this.localPicNum = this.PicNum
this.localName = this.Name
this.tablepagesize = 10
this.tablecurrentPage = 1
this.gettableData(this.localPicNum, this.localName, this.tablecurrentPage, this.tablepagesize)
},
allchosebtn() {
if (this.chosearr.length == this.nowpageleng) {
this.chosearr = []
} else {
this.chosearr = []
for (let i = 0; i < this.tableData.length; i++) {
this.chosearr.push(this.tableData[i].id)
}
}
},
singlechose(id) {
if (this.chosearr.indexOf(id) == -1) {
this.chosearr.push(id)
} else {
this.chosearr.splice(this.chosearr.indexOf(id), 1)
}
},
jumpdlb() {
console.log("跳到DLB")
this.showdlb = true
console.log(process.env.NODE_ENV)
if (process.env.NODE_ENV === "development") {
this.dlbsrc = "http://localhost:8888/#/dlb"
} else {
this.dlbsrc = "webpage/com/glaway/ims/dist/index.html#/dlb"
}
},
buildblankform() {
// 新增的时候先提前创建一个空白的表格
for (let i = 0; i < 100; i++) {
this.dataSource[i] = {
" ": "",
行号: i + 1,
项目代号: "", //项目代号
编号: "", //编号
"名称、型号、规格": "", //名称
数量: "", //数量
备注: "" //备注
}
if (i % 33 == 0) {
this.dataSource[i][" "] = "第" + Math.ceil(i / 33 + 1) + "页"
}
}
},
addpagenum() {
for (let i = 0; i < this.dataSource.length; i++) {
if (i % 33 == 0) {
this.dataSource[i][" "] = "第" + Math.ceil(i / 33 + 1) + "页"
} else {
this.dataSource[i][" "] = ""
}
}
},
add() {
this.id = ""
console.log("新增")
this.DLBName = ""
this.DLBNumber = ""
this.canedit = true
this.dialogVisible = true
this.dataSource = []
this.buildblankform()
},
adddlbdata(addData) {
// 关闭adddlb窗口
this.showdlb = false
// 得到数据
// 更具position位置更改this.dataSource
let newArray = this.dataSource.slice(0, this.dataSource.length)
newArray[this.position]["编号"] = addData.code
newArray[this.position]["名称、型号、规格"] = addData.name
newArray[this.position]["项目代号"] = ""
newArray[this.position]["数量"] = "1"
newArray[this.position]["备注"] = ""
this.dataSource = []
this.dataSource = newArray
},
getdlbarr(dlbarr) {
console.log(this.position)
// 关闭adddlb窗口
this.showdlb = false
// 得到数据
// 更具position位置更改this.dataSource
let newArray = this.dataSource.slice(0, this.dataSource.length)
for (let i = 0; i < dlbarr.length; i++) {
newArray[this.position + i]["编号"] = dlbarr[i].CODE
newArray[this.position + i]["名称、型号、规格"] = dlbarr[i].BASISFORMATIONNAME
newArray[this.position + i]["项目代号"] = ""
newArray[this.position + i]["数量"] = dlbarr[i].COUNT
newArray[this.position + i]["备注"] = ""
}
this.dataSource = []
this.dataSource = newArray
},
getdlbdata() {
console.log(this.position)
console.log(this.editingText)
if (this.positioncol == 2) {
if (this.editingText !== "") {
findByMaterId(this.editingText).then(res => {
if (res.data.obj.length > 0) {
let newArray = this.dataSource.slice(0, this.dataSource.length)
newArray[this.position]["编号"] = res.data.obj[0].ITEMNUMBER
newArray[this.position]["名称、型号、规格"] = res.data.obj[0].ITEMNAME
newArray[this.position]["项目代号"] = ""
newArray[this.position]["数量"] = "1"
newArray[this.position]["备注"] = ""
this.dataSource = []
this.dataSource = newArray
}
})
}
}
},
edittext(editingText) {
this.editingText = editingText
},
quiteedit() {
this.editingText = ""
},
addnewpage() {
// 新增加一页
console.log("新增一页")
for (let i = 0; i < 33; i++) {
this.alladdData.push({
projectNumber: "", //项目代号
itemNumber: "", //编号
itemName: "", //名称
itemQuantity: "", //数量
remarks: "" //备注
})
}
// 总数改变分页改变
this.alladdDatatotal = this.alladdData.length
this.dialogtotal = this.alladdDatatotal
this.dialogData = this.alladdData.slice((this.dialogcurrentPage - 1) * 33, this.dialogcurrentPage * 33)
console.log(this.alladdData)
console.log(this.dialogData)
},
delpage() {
// 删除操作
if (this.dialogcurrentPage == 1) {
if (this.alladdDatatotal > 33) {
this.alladdData = this.alladdData.slice(33)
this.alladdDatatotal = this.alladdDatatotal - 33
this.dialogtotal = this.alladdDatatotal
this.dialogData = this.alladdData.slice((this.dialogcurrentPage - 1) * 33, this.dialogcurrentPage * 33)
} else {
this.$message({
message: "只剩一页了,不能删了",
type: "warning"
})
}
} else {
this.alladdData.splice((this.dialogcurrentPage - 1) * 33, 33)
this.alladdDatatotal = this.alladdDatatotal - 33
this.dialogtotal = this.alladdDatatotal
this.dialogcurrentPage = this.dialogcurrentPage - 1
this.dialogData = this.alladdData.slice((this.dialogcurrentPage - 1) * 33, this.dialogcurrentPage * 33)
}
console.log(this.alladdData)
console.log(this.dialogData)
},
clickposition(position, positioncol) {
this.position = position
this.positioncol = positioncol
},
submit() {
if (this.DLBNumber == "" || this.DLBName == "") {
this.$message({
message: "图号或名称不能为空!",
type: "warning"
})
return
}
// 增加或引用或更改时校验
// 先判断有数据
let result = []
for (let i = this.dataSource.length - 1; i >= 0; i--) {
if (
this.dataSource[i]["项目代号"] !== "" ||
this.dataSource[i]["编号"] !== "" ||
this.dataSource[i]["名称、型号、规格"] !== "" ||
this.dataSource[i]["数量"] !== "" ||
this.dataSource[i]["备注"] !== ""
) {
result.push(i)
}
}
if (result.length === 0) {
this.$message({
message: "至少要有一条数据",
type: "warning"
})
return
}
checkDLBDatas(this.DLBNumber, this.id).then(res => {
if (res.data.msg !== "操作成功") {
// 保存失败
this.$message({
message: "保存失败,图号不能与之前图号重复!",
type: "warning"
})
} else {
let pagenum = Math.ceil(this.dataSource.length / 33)
for (let i = this.dataSource.length - 1; i >= 0; i--) {
if (
this.dataSource[i]["项目代号"] == "" &&
this.dataSource[i]["编号"] == "" &&
this.dataSource[i]["名称、型号、规格"] == "" &&
this.dataSource[i]["数量"] == "" &&
this.dataSource[i]["备注"] == ""
) {
this.dataSource.splice(i, 1)
}
}
console.log(this.dataSource)
saveDLBItemData(this.DLBNumber, this.DLBName, JSON.stringify(this.dataSource), pagenum, this.id).then(res => {
this.gettableData(this.localPicNum, this.localName, this.tablecurrentPage, this.tablepagesize)
this.dialogVisible = false
this.DLBNumber = ""
this.DLBName = ""
})
}
})
},
quote() {
this.id = ""
// 引用只能引用单挑数据
if (this.chosearr.length === 1) {
console.log(this.chosearr)
let id = this.chosearr[0]
this.dialogcurrentPage = 1
// 开始引用数据
this.getdialogData(id)
this.dialogVisible = true
} else {
this.$message({
message: "能且只能引用一条数据",
type: "warning"
})
}
},
change() {
// 修改只能修改单挑数据
if (this.chosearr.length === 1) {
this.id = this.chosearr[0]
let id = this.chosearr[0]
this.dialogcurrentPage = 1
// 开始引用数据
this.getdialogData(id)
this.dialogVisible = true
} else {
this.$message({
message: "一次能且只能修改一条数据",
type: "warning"
})
}
},
del() {
let str = this.chosearr.join(",")
delByIds(str).then(res => {
if (this.tablecurrentPage == 1) {
this.tablecurrentPage = 1
} else {
if (this.chosearr.length == this.nowpageleng) {
this.tablecurrentPage = this.tablecurrentPage - 1
}
}
this.chosearr = []
// 判断如果删除的是最后一页
this.gettableData(this.localPicNum, this.localName, this.tablecurrentPage, this.tablepagesize)
})
},
outfile() {
let suffix = ""
if (this.chosearr.length > 1) {
suffix = "zip"
} else if (this.chosearr.length == 1) {
suffix = "xlsx"
} else {
this.$message({
message: "先选择要导出的数据",
type: "warning"
})
return
}
let str = this.chosearr.join(",")
doExportDatas(str).then(res => {
if (window.navigator.msSaveOrOpenBlob) {
// 兼容IE10
const blob = res.data
window.navigator.msSaveBlob(blob, "DLB报表." + suffix)
} else {
const blob = res.data
const reader = new FileReader()
reader.readAsDataURL(blob)
reader.onload = e => {
const a = document.createElement("a")
a.download = decodeURIComponent("DLB报表." + suffix)
a.href = e.target.result
document.body.appendChild(a)
a.click()
document.body.removeChild(a)
}
}
})
},
importfile(e) {
let file = e.target.files[0]
this.formData = new FormData()
this.formData.append("FileData", file)
this.formData.append("Filename", file.name)
this.formData.append("Upload", "Submit Query")
},
uploadevent() {
if (this.formData.__proto__.append) {
doImportExcel(this.formData).then(res => {
// console.log(res)
if (res.data.msg) {
// 判断导入成功还是导入失败
let str = res.data.msg.slice(0, 4)
// console.log(str)
if (str === "导入失败") {
this.$message({
message: "导入失败!",
type: "warning"
})
} else {
this.$message({
message: "导入成功",
type: "success"
})
this.uploadbox = false
}
}
})
} else {
this.$message({
message: "先选取需要导入的文件",
type: "warning"
})
}
},
showuploadbox() {
this.uploadbox = true
}
},
mounted() {
this.chosearr = []
this.PicNum = ""
this.Name = ""
this.canedit = true
this.gettableData("", "", 1, 10)
window.addEventListener("click", () => {
this.menushow = false
})
},
watch: {
dataSource: {
deep: true,
handler: function(newV) {
// 先判断tablelength和newV.length的长度
// 如果newV.length大于tablelength说明是进行了插入操作
// 如果newV.length小于tablelength说明是进行了插入操作
if (newV.length > this.tablelength) {
console.log("插入行")
// 表示插入了几行
let lang = newV.length - this.tablelength
// 判断插入的行数
// console.log(Math.floor(lang / 33) + "页" + (lang - Math.floor(lang / 33) * 33) + "行")
// 应该补充的行数为33-(lang - Math.floor(lang / 33) * 33)
// console.log("应该再插入" + (33 - (lang - Math.floor(lang / 33) * 33)) + "行")
if (33 - (lang - Math.floor(lang / 33) * 33) !== 33) {
// console.log("再加" + (33 - (lang - Math.floor(lang / 33) * 33)) + "行")
let newpage = []
for (let i = 0; i < 33 - (lang - Math.floor(lang / 33) * 33); i++) {
newpage[i] = {
" ": "",
行号: "",
项目代号: "", //项目代号
编号: "", //编号
"名称、型号、规格": "", //名称
数量: "", //数量
备注: "" //备注
}
}
newV = [...newV, ...newpage]
}
}
if (newV.length < this.tablelength) {
console.log("删除行")
let lang = this.tablelength - newV.length
if (Math.ceil(lang / 33) > 1) {
console.log("表示删除的数量超过33")
console.log("应该再插入" + (33 - (lang - Math.floor(lang / 33) * 33)) + "行")
let newpage = []
for (let i = 0; i < lang - Math.floor(lang / 33) * 33; i++) {
newpage[i] = {
" ": "",
行号: "",
项目代号: "", //项目代号
编号: "", //编号
"名称、型号、规格": "", //名称
数量: "", //数量
备注: "" //备注
}
}
newV = [...newV, ...newpage]
// 加上删除的数量
} else if (lang === 33) {
console.log("表示删除的数量等于33")
// 不需要不加了
} else {
console.log("表示删除的数量小于33")
// 加上删除的数量
console.log("应该再插入" + (lang - Math.floor(lang / 33) * 33) + "行")
let newpage = []
for (let i = 0; i < lang - Math.floor(lang / 33) * 33; i++) {
newpage[i] = {
" ": "",
行号: "",
项目代号: "", //项目代号
编号: "", //编号
"名称、型号、规格": "", //名称
数量: "", //数量
备注: "" //备注
}
}
newV = [...newV, ...newpage]
}
}
// 遍历数组中的对象有没有所有属性
for (let i = 0; i < newV.length; i++) {
let objarr = []
for (let j in newV[i]) {
objarr.push(j)
}
if (
objarr.indexOf(" ") == -1 ||
objarr.indexOf("行号") == -1 ||
objarr.indexOf("项目代号") == -1 ||
objarr.indexOf("编号") == -1 ||
objarr.indexOf("名称、型号、规格") == -1 ||
objarr.indexOf("数量") == -1 ||
objarr.indexOf("备注") == -1
) {
newV[i][" "] = ""
newV[i]["行号"] = ""
newV[i]["项目代号"] = ""
newV[i]["编号"] = ""
newV[i]["名称、型号、规格"] = ""
newV[i]["数量"] = ""
newV[i]["备注"] = ""
}
}
// 现在的newV没有行数和页码要给加上
for (let i = 0; i < newV.length; i++) {
newV[i]["行号"] = i + 1
if (i % 33 == 0) {
newV[i][" "] = "第" + Math.ceil(i / 33 + 1) + "页"
}
}
// 赋值
// console.log(newV)
this.dataSource = newV
// // 操作完成之后将新的长度赋值给保存的长度
this.tablelength = newV.length
}
}
}
}
</script>
<style lang="scss" scoped>
#listcontainer {
width: 100%;
height: 100%;
background-color: #fff;
padding: 0 20px;
box-sizing: border-box;
display: flex;
flex-direction: column;
position: relative;
.menu {
// position: absolute;
z-index: 99999;
position: fixed;
width: 150px;
height: 60px;
border: 1px solid #ccc;
background-color: #fff;
li {
height: 30px;
line-height: 30px;
}
li:hover {
background-color: #108ee9;
color: #fff;
cursor: pointer;
}
}
.searchbox {
height: 50px;
width: 100%;
display: flex;
justify-content: start;
align-items: center;
div {
margin-right: 30px;
overflow: hidden;
display: flex;
justify-content: space-between;
span {
margin-right: 10px;
display: inline-block;
}
input {
outline: none;
height: 20px;
line-height: 20px;
}
}
}
.btns {
height: 50px;
width: 100%;
display: flex;
justify-content: flex-end;
p {
height: 30px;
line-height: 30px;
width: 100px;
background-color: #0c60aa;
cursor: pointer;
color: #fff;
margin-right: 30px;
}
p:hover {
background-color: #108ee9;
}
}
.curd {
height: 30px;
width: 100%;
display: flex;
p {
height: 30px;
line-height: 30px;
width: 60px;
margin-right: 10px;
cursor: pointer;
i {
color: #108ee9;
margin-right: 2px;
}
}
}
.tablebox {
flex: 1;
overflow-x: auto;
margin-top: 10px;
table {
height: 100%;
thead {
height: 40px;
width: 100%;
overflow-y: scroll;
display: block;
tr {
height: 40px;
display: flex;
background: #e5e5e5;
th {
width: 250px;
line-height: 40px;
border: 1px solid #ccc;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
th:nth-child(1) {
width: 50px;
}
th:nth-child(2) {
width: 50px;
}
th:nth-child(3) {
width: 150px;
}
}
}
tbody {
width: 100%;
height: 400px;
overflow-y: scroll;
overflow-x: hidden;
display: block;
tr {
display: flex;
height: 40px;
.look {
cursor: pointer;
}
td {
line-height: 40px;
width: 250px;
border: 1px solid #ccc;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
display: block;
}
td:nth-child(1) {
width: 50px;
}
td:nth-child(2) {
width: 50px;
}
td:nth-child(3) {
width: 150px;
}
}
}
}
}
.paginate {
height: 50px;
width: 100%;
margin-top: 10px;
display: flex;
justify-content: space-between;
.el-pagination {
button {
padding: 0 10px;
}
.el-pager {
.active {
background-color: #0c60aa;
}
}
}
}
/deep/ .el-dialog__wrapper {
.el-dialog {
height: 70%;
overflow: hidden;
.el-dialog__header {
height: 30px;
width: 100%;
padding: 0 10px;
.el-dialog__title {
float: left;
font-weight: 600;
font-size: 14px;
}
.el-dialog__headerbtn {
right: 7px;
top: 7px;
}
}
.el-dialog__body {
height: calc(100% - 150px);
width: 100%;
padding: 0;
.dialogmain {
height: 100%;
width: 100%;
padding: 0 10px;
box-sizing: border-box;
.tabletop {
height: 100px;
width: 100%;
p {
text-align: left;
height: 30px;
line-height: 30px;
color: #0c60aa;
font-weight: 600;
}
.info {
height: 40px;
width: 100%;
display: flex;
justify-content: start;
align-items: center;
div {
margin-right: 30px;
overflow: hidden;
display: flex;
justify-content: space-between;
span {
display: inline-block;
}
i {
color: red;
}
input {
margin-left: 10px;
outline: none;
height: 20px;
line-height: 20px;
}
p {
height: 30px;
background-color: #0c60aa;
color: #fff;
padding: 0 10px;
}
p:hover {
cursor: pointer;
background-color: #108ee9;
}
}
}
}
.dialogtable {
height: calc(100% - 100px);
width: 100%;
overflow: hidden;
table {
thead {
height: 35px;
width: 100%;
tr {
height: 35px;
display: flex;
background: #e5e5e5;
th {
width: 200px;
line-height: 35px;
border: 1px solid #ccc;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
box-sizing: border-box;
}
th:nth-child(1) {
width: 50px;
}
th:nth-child(2) {
width: 50px;
}
th:nth-child(3) {
width: 150px;
}
th:nth-last-child(1) {
width: 100px;
}
th:nth-last-child(2) {
width: 100px;
}
}
}
tbody {
height: 350px;
overflow: auto;
display: block;
.spread-host {
width: 100%;
height: 100%;
}
tr {
display: flex;
width: 100%;
height: 35px;
table-layout: fixed;
position: relative;
.look {
cursor: pointer;
}
td {
line-height: 35px;
padding: 0;
box-sizing: border-box;
width: 200px;
border: 1px solid #ccc;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
input {
width: 100%;
height: 100%;
outline: none;
border: none;
text-align: center;
padding: 0;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
}
td:nth-child(1) {
width: 50px;
}
td:nth-child(2) {
width: 50px;
}
td:nth-child(3) {
width: 150px;
}
td:nth-last-child(1) {
width: 100px;
}
td:nth-last-child(2) {
width: 100px;
}
}
}
::-webkit-scrollbar {
width: 1px;
}
}
}
}
}
.el-dialog__footer {
height: 50px;
width: 100%;
button {
height: 30px;
padding: 0 10px;
}
}
}
}
/deep/ .upload {
overflow: hidden;
.el-dialog {
height: 25%;
overflow: hidden;
.el-dialog__header {
height: 30px;
width: 100%;
padding: 0 10px;
.el-dialog__title {
float: left;
font-weight: 600;
font-size: 14px;
}
.el-dialog__headerbtn {
right: 7px;
top: 7px;
}
}
.el-dialog__body {
height: calc(100% - 30px);
width: 100%;
position: relative;
#file {
border: 1px solid #ccc;
outline: none;
}
button {
position: absolute;
right: 30px;
bottom: 30px;
}
}
}
}
/deep/ .dlbpage {
overflow: hidden;
.el-dialog {
height: 80%;
overflow: hidden;
.el-dialog__header {
height: 30px;
width: 100%;
padding: 0 10px;
.el-dialog__title {
float: left;
font-weight: 600;
font-size: 14px;
}
.el-dialog__headerbtn {
right: 7px;
top: 7px;
}
}
.el-dialog__body {
height: calc(100% - 30px);
width: 100%;
padding: 0;
}
}
}
}
</style>
可参考网址:
https://www.grapecity.com.cn/blogs/create-a-spreadjs-vue-project-in-3-minutes
https://www.npmjs.com/package/@grapecity/spread-sheets
https://demo.grapecity.com.cn/spreadjs/help/api/
https://demo.grapecity.com.cn/spreadjs/SpreadJSTutorial/#/samples