gmh excel文件拆分,功能完善

master
lenovo 2 years ago
parent c56599e042
commit 192c917ab7

@ -5,7 +5,7 @@
</template> </template>
<script> <script>
import GmhExcel from "@/components/GmhExcel" import GmhExcel from "@/components/gmhExcel"
export default { export default {
components: { components: {

@ -1,285 +0,0 @@
<template>
<div>
<el-card class="box-card bottom-10">
<el-steps :active="active" finish-status="success">
<el-step title="导入名单"></el-step>
<el-step title="导入模板"></el-step>
<el-step title="完成"></el-step>
</el-steps>
<!-- <el-button style="margin-top: 12px;" @click="next"></el-button> -->
</el-card>
<el-card>
<el-form ref="$form" :model="model" label-position="right" label-width="100px" size="small">
<el-form-item :rules="rules.upload" prop="upload" label="名单上传" v-if="active==0">
<el-upload
action="/api/excel/readData"
:multiple="false"
:on-preview="uploadPreview"
:on-remove="uploadRemove"
:on-success="uploadSuccess"
:on-error="uploadError"
:on-progress="uploadProgress"
:on-change="uploadChange"
:before-upload="uploadBefore"
:before-remove="uploadBeforeRemove"
:on-exceed="uploadOnExceed"
:file-list="nameFileList"
:limit="1"
>
<el-button type="primary" size="small">点击上传</el-button>
</el-upload>
</el-form-item>
<el-form-item prop="templateSheetNum" label="模板所在sheet页" v-if="active==1">
<el-input v-model="model.templateSheetNum" style="width=200px"></el-input>
</el-form-item>
<el-form-item
:rules="rules.uploadTemplate"
prop="uploadTemplate"
label="模板上传"
v-if="active==1"
>
<el-upload
:action="'/api/excel/template?templateSheetNum=' + model.templateSheetNum"
:multiple="false"
:on-success="uploadTemplateSuccess"
:file-list="templateFileList"
>
<el-button type="primary" size="small">点击上传</el-button>
</el-upload>
</el-form-item>
<el-form-item prop="cellNum" label="指定单元格" v-if="active==1">
<el-input v-model="model.cellNum" style="width=200px" :disabled="cellSearchDisable">
<el-button
slot="append"
icon="el-icon-search"
:disabled="cellSearchDisable"
@click="cellNumSearch"
></el-button>
</el-input>
</el-form-item>
<el-form-item prop="cellData" label="原始数据" v-if="active==1">
<el-input
type="textarea"
v-model="model.cellData"
:disabled="cellSearchDisable"
readonly
:rows="5"
></el-input>
</el-form-item>
<el-form-item prop="newCellData" label="替换后的数据" v-if="active==1">
<el-input
type="textarea"
v-model="model.newCellData"
:disabled="cellSearchDisable"
:rows="5"
></el-input>
</el-form-item>
<el-button type="primary" class="f-right" @click="executeTemplate" v-if="active==1"></el-button>
</el-form>
</el-card>
<el-dialog :visible.sync="dialogVisible" width="40%">
<el-tabs type="card" v-model="activeName" @tab-click="handleClick">
<el-tab-pane
v-for="(item, index) in namePreview"
:key="index"
:label="item.sheetName"
:name="item.index"
>
<div class="table-s">
<el-table :data="item.nameList" stripe style="width: 100%">
<el-table-column type="index" label="序号" min-width="20%" align="center"></el-table-column>
<el-table-column prop="name" label="姓名" min-width="50%" align="center"></el-table-column>
<el-table-column fixed="right" label="操作" min-width="30%" align="center">
<template slot-scope="scope">
<el-button type="primary" icon="el-icon-edit" circle size="small"></el-button>
<el-button type="danger" icon="el-icon-delete" circle size="small"></el-button>
</template>
</el-table-column>
</el-table>
</div>
<div class="top-10">
<span>{{item.sheetName}} 一共有{{item.nameList.length}}个人请检查一下对不对</span>
<span v-if="item.hasRepeat" class="f-right">{{item.repeatCount}}</span>
</div>
</el-tab-pane>
</el-tabs>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false"> </el-button>
<el-button type="primary" @click="nameListNext"></el-button>
</span>
</el-dialog>
</div>
</template>
<script>
export default {
data() {
return {
forms: ["$form"],
model: {
upload: "",
uploadTemplate: "",
cellNum: "",
cellData: "",
newCellData: "",
templateSheetNum: "1"
},
rules: {
upload: [],
uploadTemplate: []
},
active: 0,
dialogVisible: false,
namePreview: [],
activeName: 0,
nameFileList: [],
templateFileList: [],
cellSearchDisable: true
};
},
created() {
this.test();
},
mounted() {},
methods: {
test() {
this.$axios
.get("/api/test/test")
.then(res => {
const { data } = res;
})
.catch(err => {
console.log(err);
});
},
nameListNext() {
this.$confirm("请确认名单是否正确?", "提示", {
confirmButtonText: "没毛病",
cancelButtonText: "有问题",
type: "warning"
})
.then(() => {
this.dialogVisible = false;
if (this.active++ > 2) this.active = 0;
})
.catch(() => {
this.$message({
type: "info",
message: "有问题就改"
});
});
},
uploadPreview(file) {
this.dialogVisible = true;
},
uploadRemove(file, fileList) {},
uploadSuccess(response, file, fileList) {
if (response.success) {
this.namePreview = response.data;
this.dialogVisible = true;
this.$message.success("姓名导入成功");
} else {
this.$message.success("姓名导入出现了错误,请联系陈达解决");
}
},
uploadTemplateSuccess(response, file, fileList) {
if (response.success) {
this.$message.success("模板导入成功");
this.cellSearchDisable = false;
} else {
this.$message.success("模板导入出现了错误,请联系陈达解决");
}
},
uploadError(err, file, fileList) {},
uploadProgress(event, file, fileList) {},
uploadChange(file, fileList) {},
uploadBefore(file) {},
uploadBeforeRemove(file, fileList) {},
uploadOnExceed(files, fileList) {
this.$message.warning("只允许上传一个文件,想更换文件请先删除再重新上传");
},
handleClick() {},
import() {
this.$message.success("sss");
},
cellNumSearch() {
this.$axios
.get("/api/excel/cellNumSearch", {
params: {
cellRowStr: this.model.cellNum
}
})
.then(res => {
const { data } = res;
if (data.success) {
this.model.cellData = data.data;
} else {
this.$message.error(data.msg);
this.model.cellData = "";
}
})
.catch(err => {
console.log(err);
});
},
executeTemplate() {
this.active++;
let a = document.createElement("a"); //a
a.style.display = "none"; //
a.target = "_blank";
a.href = `/api/excel/executeTemplate?newCellData=${encodeURIComponent(
this.model.newCellData
)}&cellRowStr=${this.model.cellNum}`;
document.body.appendChild(a); //
a.click(); //,
document.body.removeChild(a) / 释放;
setTimeout(() => {
this.active++;
}, 2000);
// this.$axios
// .get("/api/excel/executeTemplate", {
// params: {
// newCellData: this.model.newCellData,
// cellRowStr: this.model.cellNum
// }
// })
// .then(res => {
// const { data } = res;
// if (data.success) {
// } else {
// this.$message.error(data.msg);
// }
// })
// .catch(err => {
// console.log(err);
// });
}
}
};
</script>
<style>
.table-s {
height: 400px;
overflow: auto;
}
.bottom-10 {
margin-bottom: 10px;
}
.top-10 {
margin-top: 10px;
}
.left-10 {
margin-left: 10px;
}
.f-right {
float: right;
}
</style>

@ -0,0 +1,135 @@
<template>
<!-- 数据源导入 -->
<div>
<el-card class="box-card bottom-10">
<div slot="header" class="clearfix">
<span>1导入名单</span>
</div>
<el-form
ref="$form"
:model="formData"
label-position="right"
label-width="100px"
size="small"
:rules="formRules"
:disabled="dataSourceImportDisabled"
>
<el-form-item prop="upload" label="名单上传">
<el-upload
:action="`/api/excel/dataSourceImport?dataSourceImportModel=${formData.dataSourceImportModel}`"
:multiple="false"
:on-preview="uploadPreview"
:on-remove="uploadRemove"
:on-success="uploadSuccess"
:on-error="uploadError"
:on-progress="uploadProgress"
:on-change="uploadChange"
:before-upload="uploadBefore"
:before-remove="uploadBeforeRemove"
:on-exceed="uploadOnExceed"
:file-list="dataSourceFileList"
:limit="1"
>
<el-button type="primary" size="small">点击上传</el-button>
</el-upload>
</el-form-item>
<el-button type="text" @click="moreSetting = !moreSetting" style="margin-left: 30px">更多设置👇</el-button>
<el-form-item prop="templateSheetNum" label="模式:" v-if="moreSetting">
<el-radio-group v-model="formData.dataSourceImportModel">
<el-radio label="0">自动识别姓名</el-radio>
<el-radio label="1">全部导入</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item prop="titleRowNum" label="表头所在行:" v-if="moreSetting">
<el-input v-model="formData.titleRowNum" style="width:200px"></el-input>
</el-form-item>
</el-form>
</el-card>
<!-- 数据预览弹窗 -->
<DataSourceImportDialog
:dialogVisible="dialogVisible"
:dataSourcePreview="dataSourcePreview"
@closeDialog="closeDialog"
@nextStep="nextStep"
:dataSourceImportDisabled="dataSourceImportDisabled"
></DataSourceImportDialog>
</div>
</template>
<script>
import DataSourceImportDialog from "@/components/gmhExcel/DataSourceImportDialog";
import { showLoading, hideLoading } from "@/utils/loading";
export default {
name: "DataSourceImport",
props: {
dataSourceImportDisabled: {
type: Boolean,
require: true,
default: false
}
},
components: { DataSourceImportDialog },
data() {
return {
//
formData: {
dataSourceImportModel: "0",
titleRowNum: ""
},
//
formRules: {},
//
dataSourceFileList: [],
//
moreSetting: false,
//
dialogVisible: false,
//
dataSourcePreview: []
};
},
computed: {},
watch: {},
methods: {
closeDialog() {
this.dialogVisible = false;
},
uploadPreview(file) {
this.dialogVisible = true;
},
uploadRemove(file, fileList) {},
uploadSuccess(response, file, fileList) {
if (response.success) {
this.dataSourcePreview = response.data;
this.dialogVisible = true;
this.$message.success("姓名导入成功");
} else {
this.$message.success("姓名导入出现了错误,请联系陈达解决");
}
hideLoading();
},
uploadError(err, file, fileList) {
hideLoading();
this.$message.error(err);
},
uploadProgress(event, file, fileList) {},
uploadChange(file, fileList) {},
uploadBefore(file) {
showLoading();
},
uploadBeforeRemove(file, fileList) {},
uploadOnExceed(files, fileList) {
this.$message.warning("只允许上传一个文件,想更换文件请先删除再重新上传");
},
// step
nextStep(val) {
this.$emit("nextStep", val);
}
}
};
</script>
<style scoped>
</style>

@ -0,0 +1,96 @@
<template>
<!-- 数据源导入预览弹框 -->
<el-dialog :visible.sync="dialogVisible" width="40%">
<el-tabs type="card" v-model="activeName" @tab-click="handleClick">
<el-tab-pane
v-for="(item, index) in dataSourcePreview"
:key="index"
:label="item.sheetName"
:name="item.index"
>
<div class="table-s">
<el-table :data="item.nameList" stripe style="width: 100%">
<el-table-column type="index" label="序号" min-width="20%" align="center"></el-table-column>
<el-table-column prop="name" label="姓名" min-width="50%" align="center"></el-table-column>
<el-table-column fixed="right" label="操作" min-width="30%" align="center">
<!-- <template slot-scope="scope"> -->
<template>
<el-button type="primary" icon="el-icon-edit" circle size="small"></el-button>
<el-button type="danger" icon="el-icon-delete" circle size="small"></el-button>
</template>
</el-table-column>
</el-table>
</div>
<div class="top-10">
<span>{{item.sheetName}} 一共有{{item.nameList.length}}个人请检查一下对不对</span>
<span v-if="item.hasRepeat" class="f-right">{{item.repeatCount}}</span>
</div>
</el-tab-pane>
</el-tabs>
<span slot="footer" class="dialog-footer">
<el-button @click="closeDialog"> </el-button>
<el-button type="primary" @click="nameListNext" v-if="!dataSourceImportDisabled"></el-button>
</span>
</el-dialog>
</template>
<script>
export default {
name: "DataSourceImportDialog",
props: {
//
dataSourcePreview: {
type: Array
},
//
dialogVisible: {
type: Boolean,
require: true,
default: false
},
dataSourceImportDisabled: {
type: Boolean
}
},
components: {},
data() {
return {
// tab
activeName: ""
};
},
computed: {},
watch: {},
methods: {
handleClick(val) {},
nameListNext() {
this.$confirm("请确认名单是否正确?", "提示", {
confirmButtonText: "没毛病",
cancelButtonText: "有问题",
type: "warning"
})
.then(() => {
this.closeDialog();
this.nextStep(1);
})
.catch(() => {
this.$message({
type: "info",
message: "有问题就改"
});
});
},
closeDialog() {
this.$emit("closeDialog");
},
// step
nextStep(val) {
this.$emit("nextStep", val);
}
}
};
</script>
<style scoped>
</style>

@ -0,0 +1,76 @@
<template>
<el-card class="box-card bottom-10">
<el-steps :active="active" finish-status="success">
<el-step title="导入名单🐸"></el-step>
<el-step title="导入模板💕"></el-step>
<el-step title="完成👍"></el-step>
</el-steps>
</el-card>
</template>
<script>
export default {
name: "ImportSteps",
props: {
active: {
type: Number,
require: true,
default: 0
}
},
components: {},
data() {
return {};
},
computed: {},
watch: {},
methods: {},
/**
* 在实例初始化之后组件属性计算之前如data属性等
*/
beforeCreate() {},
/**
* 组件实例创建完成属性已绑定但DOM还未生成$ el属性还不存在
*/
created() {},
/**
* 在挂载开始之前被调用相关的 render 函数首次被调用
*/
beforeMount() {},
/**
* el 被新创建的 vm.$ el 替换并挂载到实例上去之后调用该钩子
* 如果 root 实例挂载了一个文档内元素 mounted 被调用时 vm.$ el 也在文档内
*/
mounted() {},
/**
* 数据更新时调用发生在虚拟 DOM 重新渲染和打补丁之前
* 你可以在这个钩子中进一步地更改状态这不会触发附加的重渲染过程
*/
beforeUpdate() {},
/**
* 由于数据更改导致的虚拟 DOM 重新渲染和打补丁在这之后会调用该钩子
* 当这个钩子被调用时组件 DOM 已经更新所以你现在可以执行依赖于 DOM 的操作
*/
updated() {},
/**
* keep-alive 组件激活时调用 仅针对keep-alive 组件有效
*/
activated() {},
/**
* keep-alive 组件停用时调用 仅针对keep-alive 组件有效
*/
deactivated() {},
/**
* 实例销毁之前调用在这一步实例仍然完全可用
*/
beforeDestroy() {},
/**
* Vue 实例销毁后调用调用后Vue 实例指示的所有东西都会解绑定
* 所有的事件监听器会被移除所有的子实例也会被销毁
*/
destroyed() {}
};
</script>
<style scoped>
</style>

@ -0,0 +1,86 @@
<template>
</template>
<script>
export default {
//
name: 'demo',
//
props: {},
//
components: {},
//
data () {
return {}
},
//
computed: {},
//
watch: {},
//
methods: {},
//
/**
* 在实例初始化之后组件属性计算之前如data属性等
*/
beforeCreate () {
},
/**
* 组件实例创建完成属性已绑定但DOM还未生成$ el属性还不存在
*/
created () {
},
/**
* 在挂载开始之前被调用相关的 render 函数首次被调用
*/
beforeMount () {
},
/**
* el 被新创建的 vm.$ el 替换并挂载到实例上去之后调用该钩子
* 如果 root 实例挂载了一个文档内元素 mounted 被调用时 vm.$ el 也在文档内
*/
mounted () {
},
/**
* 数据更新时调用发生在虚拟 DOM 重新渲染和打补丁之前
* 你可以在这个钩子中进一步地更改状态这不会触发附加的重渲染过程
*/
beforeUpdate () {
},
/**
* 由于数据更改导致的虚拟 DOM 重新渲染和打补丁在这之后会调用该钩子
* 当这个钩子被调用时组件 DOM 已经更新所以你现在可以执行依赖于 DOM 的操作
*/
updated () {
},
/**
* keep-alive 组件激活时调用 仅针对keep-alive 组件有效
*/
activated () {
},
/**
* keep-alive 组件停用时调用 仅针对keep-alive 组件有效
*/
deactivated () {
},
/**
* 实例销毁之前调用在这一步实例仍然完全可用
*/
beforeDestroy () {
},
/**
* Vue 实例销毁后调用调用后Vue 实例指示的所有东西都会解绑定
* 所有的事件监听器会被移除所有的子实例也会被销毁
*/
destroyed () {
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<!--使用了scoped属性之后父组件的style样式将不会渗透到子组件中-->
<!--然而子组件的根节点元素会同时被设置了scoped的父css样式和设置了scoped的子css样式影响-->
<!--这么设计的目的是父组件可以对子组件根元素进行布局-->
<style scoped>
</style>

@ -0,0 +1,179 @@
<template>
<el-card>
<div slot="header" class="clearfix">
<span>2模板导入与处理</span>
</div>
<el-form
ref="$form"
:model="formData"
label-position="right"
label-width="100px"
size="small"
:rules="rules"
:disabled="templateImportDisabled"
>
<el-form-item prop="templateSheetNum" label="模板所在sheet页">
<el-input v-model="formData.templateSheetNum" style="width:200px"></el-input>
</el-form-item>
<el-form-item prop="uploadTemplate" label="模板上传">
<el-upload
:action="'/api/excel/template?templateSheetNum=' + formData.templateSheetNum"
:multiple="false"
:on-success="uploadTemplateSuccess"
:file-list="templateFileList"
>
<el-button type="primary" size="small">点击上传</el-button>
</el-upload>
</el-form-item>
<el-form-item prop="cellNum" label="指定单元格">
<el-input v-model="formData.cellNum" style="width=200px" :disabled="cellSearchDisable">
<el-button
slot="append"
icon="el-icon-search"
:disabled="cellSearchDisable"
@click="cellNumSearch"
></el-button>
</el-input>
</el-form-item>
<el-form-item prop="cellData" label="原始数据">
<el-input
type="textarea"
v-model="formData.cellData"
:disabled="cellSearchDisable"
readonly
:rows="5"
></el-input>
</el-form-item>
<el-form-item prop="newCellData" label="替换后的数据">
<el-input
type="textarea"
v-model="formData.newCellData"
:disabled="cellSearchDisable"
:rows="5"
></el-input>
</el-form-item>
<el-form-item prop="resultExcelName" label="处理后Excel的名字">
<el-input v-model="formData.resultExcelName"></el-input>
</el-form-item>
<el-button type="primary" class="f-right" @click="gotoDownload"></el-button>
<el-button type="primary" class="f-right right-10" @click="executeTemplate">Excel</el-button>
</el-form>
</el-card>
</template>
<script>
export default {
name: "TemplateImport",
props: {
templateImportDisabled: {
type: Boolean,
require: true,
default: false
}
},
components: {},
data() {
return {
formData: {
// sheet
templateSheetNum: "1",
cellNum: "",
cellData: "",
newCellData: ""
},
rules: {},
templateFileList: [],
cellSearchDisable: false,
resultExcelName: ""
};
},
computed: {},
watch: {},
methods: {
uploadTemplateSuccess(response, file, fileList) {
if (response.success) {
this.$message.success("模板导入成功");
this.cellSearchDisable = false;
} else {
this.$message.success("模板导入出现了错误,请联系陈达解决");
}
},
cellNumSearch() {
this.$axios
.get("/api/excel/cellNumSearch", {
params: {
cellRowStr: this.formData.cellNum
}
})
.then(res => {
const { data } = res;
if (data.success) {
this.$message.success("单元格数据获取成功");
this.formData.cellData = data.data;
} else {
this.$message.error(data.msg);
this.formData.cellData = "";
}
})
.catch(err => {
console.log(err);
});
},
executeTemplate() {
// this.active++;
// let a = document.createElement("a"); //a
// a.style.display = "none"; //
// a.target = "_blank";
// a.href = `/api/excel/executeTemplate?newCellData=${encodeURIComponent(
// this.model.newCellData
// )}&cellRowStr=${this.formData.cellNum}`;
// document.body.appendChild(a); //
// a.click(); //,
// document.body.removeChild(a) / ;
// setTimeout(() => {
// this.active++;
// }, 2000);
this.$axios
.post("/api/excel/executeTemplate", {
newCellData: this.formData.newCellData,
cellRowStr: this.formData.cellNum,
resultExcelName: this.formData.resultExcelName
})
.then(res => {
const { data } = res;
if (data.success) {
this.$message.success("Excel处理完成");
} else {
this.$message.error(data.msg);
}
})
.catch(err => {
console.log(err);
});
},
gotoDownload() {
this.$axios
.get("/api/excel/gotoDownload")
.then(res => {
const { data } = res;
if (data.success) {
this.$emit("nextStep", 2);
} else {
this.$message.error(data.msg);
}
})
.catch(err => {
console.log(err);
});
}
},
created() {},
mounted() {}
};
</script>
<style scoped>
</style>

@ -0,0 +1,81 @@
<template>
<div>
<import-steps :active="activeStep"></import-steps>
<data-source-import
:dataSourceImportDisabled="dataSourceImportDisabled"
@nextStep="nextStep"
v-if="activeStep == 1 || activeStep == 0"
></data-source-import>
<template-import
:templateImportDisabled="templateImportDisabled"
@nextStep="nextStep"
v-if="activeStep == 1 || activeStep == 0"
></template-import>
</div>
</template>
<script>
import ImportSteps from "@/components/gmhExcel/ImportSteps";
import DataSourceImport from "@/components/gmhExcel/DataSourceImport";
import TemplateImport from "@/components/gmhExcel/TemplateImport";
export default {
components: { ImportSteps, DataSourceImport, TemplateImport },
data() {
return {
activeStep: 0
};
},
created() {
this.test();
},
mounted() {},
methods: {
test() {
this.$axios
.get("/api/test/test")
.then(res => {
const { data } = res;
})
.catch(err => {
console.log(err);
});
},
nextStep(val) {
this.activeStep = val;
}
},
computed: {
// disabled
dataSourceImportDisabled() {
return !(this.activeStep == 0);
},
// disabled
templateImportDisabled() {
return !(this.activeStep == 1);
}
}
};
</script>
<style>
.table-s {
height: 400px;
overflow: auto;
}
.bottom-10 {
margin-bottom: 10px;
}
.top-10 {
margin-top: 10px;
}
.left-10 {
margin-left: 10px;
}
.right-10 {
margin-right: 10px;
}
.f-right {
float: right;
}
</style>

@ -0,0 +1,34 @@
import { Loading } from 'element-ui';
let loadingCount = 0;
let loading;
const startLoading = () => {
loading = Loading.service({
lock: true,
text: '拼命加载中...',//可以自定义文字
spinner: 'el-icon-loading',//自定义加载图标类名
background: 'rgba(0, 0, 0, 0.7)'//遮罩层背景色
});
};
const endLoading = () => {
loading.close();
};
export const showLoading = () => {
if (loadingCount === 0) {
startLoading();
}
loadingCount += 1;
};
export const hideLoading = () => {
if (loadingCount <= 0) {
return;
}
loadingCount -= 1;
if (loadingCount === 0) {
endLoading();
}
};
Loading…
Cancel
Save