Merge pull request 'master' (#364) from master into prod

Reviewed-on: http://git.feashow.cn/clay/mosr-web/pulls/364
This commit is contained in:
clay
2024-06-19 19:25:34 +00:00
4 changed files with 174 additions and 145 deletions

View File

@@ -1,7 +1,8 @@
<template>
<el-table ref="reportTable" :data="tableData" style="width: 100%;height: 300px" :span-method="objectSpanMethod" v-loading="loading">
<!-- <el-table-column label="四川省国有资产经营投资管理有限责任公司-->
<!-- 科技创新项目人工成本分摊明细表" align="center">-->
<el-button color="#DED0B2" style="float: right;margin: 0 10px 10px 0" @click="exportTable">导出</el-button>
<el-table ref="reportTable" :data="tableData" style="width: 100%;height: 479px" :span-method="objectSpanMethod" v-loading="loading">
<!-- <el-table-column label="四川省国有资产经营投资管理有限责任公司-->
<!-- 科技创新项目人工成本分摊明细表" align="center">-->
<el-table-column v-for="column in columnInfo" :prop="column.prop" :label="column.label" align="center"
:fixed="(!column.children) ? ((column.prop === 'totalSeparation' || column.prop === 'totalSeparationCost') ? 'right' : 'left') : false"
:width="(column.prop === 'totalSeparation' || column.prop === 'totalSeparationCost') ? 160:130">
@@ -26,18 +27,14 @@
</template>
</template>
</el-table-column>
<!-- </el-table-column>-->
<!-- </el-table-column>-->
</el-table>
<el-button @click="exportExcel">导出</el-button>
</template>
<script setup lang="jsx">
import {getResearchUser, getAllocationDetailList, getAllocationDetails} from "@/api/expense-manage";
import {ElNotification} from "element-plus";
// import * as XLSX from "xlsx";
import {utils} from "xlsx";
import FileSaver from 'file-saver'
import XLSX from "xlsx-style-vite";
import {exportExcel} from "@/utils/export-excel";
const route = useRoute()
const tableIns = ref()
@@ -162,118 +159,12 @@ getResearchOptions()
init()
const exportExcel = () => {
//如果导出后多出空白行则修改rowspan否则可不用
// var tds = document.querySelectorAll(".el-table__footer td");
// tds.forEach(td => td.setAttribute("rowspan", "1"));
const exportTable = () => {
const $e = reportTable.value.$el
let $table = $e.querySelector('.el-table__fixed')
if (!$table) {
$table = $e
}
//从el-table表生成工作簿对象
//使用原始的格式,保留表格中的格式如%、小数末尾的0等
let workbook = utils.table_to_book($table, {
raw: true
});
//列宽需要导出的表格有多少列这里的i就小于多少
let keys = Object.keys(tableData.value[0]).length
for (let i = 1; i < (5 + (keys - 5) * 5); i++) {
workbook.Sheets.Sheet1["!cols"].push({wpx: 100});
}
//设置单元格样式
for (const key in workbook.Sheets.Sheet1) {
if (
key !== "!cols" &&
key !== "!fullref" &&
key !== "!merges" &&
key !== "!ref" &&
key !== "!rows"
) {
//这里的s就是具体的样式如果想设置不一样的样式可以看xlsx-style文档
workbook.Sheets.Sheet1[key].s = {
//边框
border: {
top: {style: "thin"},
bottom: {style: "thin"},
left: {style: "thin",},
right: {style: "thin",}
},
//对齐
alignment: {
horizontal: "center",
vertical: "center",
wrapText: true
}
};
}
}
//修改合并单元格样式
let arr = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N",
"O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"];
//由于导出时合并单元格只识别左上角的单元格,合并单元格中其他单元格
//并不会存在,所以需要识别合并单元格中除左上角单元格外的单元格并添加
//带样式的单元格到其中不理解可以看四中的第2点。
for (let item of workbook.Sheets.Sheet1["!merges"]) {
let style = {
border: {
top: {style: "thin"},
bottom: {style: "thin"},
left: {style: "thin",},
right: {style: "thin",}
},
alignment: {
horizontal: "center",
vertical: "center",
wrapText: true
}
};
let merge_s = {t: "s", v: "", s: style};
if (item.s.c === item.e.c) {
//纵向合并其中c为字母r为数字
let star = item.s.r;
let end = item.e.r;
for (let i = star + 1; i <= end; i++) {
workbook.Sheets.Sheet1[arr[item.s.c] + (i + 1)] = merge_s;
}
} else {
//横向合并
let star = item.s.c;
let end = item.e.c;
for (let i = star; i < end; i++) {
workbook.Sheets.Sheet1[arr[i + 1] + Number(item.s.r + 1)] = merge_s;
}
}
}
//将表格数据中的字符串转ArrayBuffer
function s2ab(s) {
let buf = new ArrayBuffer(s.length);
let view = new Uint8Array(buf);
for (let i = 0; i !== s.length; ++i) view[i] = s.charCodeAt(i) & 0xff;
return buf;
}
//这里的属性可以参考xlsx-style文档
let wbout = XLSX.write(workbook, {
bookType: "xlsx",
bookSST: false,
type: "binary"
});
try {
FileSaver.saveAs(
new Blob([s2ab(wbout)], {type: "application/octet-stream"}),
"四川省国有资产经营投资管理有限责任公司科技创新项目人工成本分摊明细表.xlsx"
);
} catch (e) {
if (typeof console !== "undefined") console.log(e, wbout);
}
exportExcel($table, tableData.value[0], "四川省国有资产经营投资管理有限责任公司科技创新项目人工成本分摊明细表")
}
</script>
<style scoped>
:deep(.el-table--fit ) {
width: 100%;
height: 479px !important;
}
</style>

View File

@@ -17,6 +17,7 @@
</div>
<!-- 列显示配置 -->
<div v-if="isSettingCol" style="float: right">
<el-button v-if="tableConfig.export && tableConfig.export.open" @click="exportTable" color="#DED0B2" style="margin-bottom: 10px">导出</el-button>
<el-tooltip effect="dark" content="列配置" placement="bottom">
<el-button ref="buttonRef" link>
<el-icon size="18">
@@ -101,6 +102,7 @@
<script setup>
import {ElNotification} from 'element-plus';
import {requestList} from '../../api/common';
import {exportExcel} from "@/utils/export-excel";
const props = defineProps({
//表格配置
@@ -129,6 +131,20 @@ const tableInstance = ref()
const buttonRef = ref()
const popoverRef = ref()
const exportTable = () => {
const $e = tableInstance.value.$el
let $table = $e.querySelector('.el-table__fixed')
if (!$table) {
$table = $e
}
let fileName = ""
if (props.tableConfig.export && props.tableConfig.export) {
fileName = props.tableConfig.export.fileName
}
exportExcel($table, localData.list[0], fileName)
}
const localData = reactive({
list: [], // 表格数据
query: {
@@ -204,12 +220,12 @@ const getList = async () => {
try {
const {code, data, msg} = await requestList(api, queryParmas)
if (code === 1000) {
if(data.rows){
if (data.rows) {
localData.list = data.rows
}else {
} else {
localData.list = data
}
if(data.total){
if (data.total) {
localData.total = data.total
emits('getTotal', localData.total)
}

113
src/utils/export-excel.js Normal file
View File

@@ -0,0 +1,113 @@
import {utils} from "xlsx";
import FileSaver from 'file-saver'
import XLSX from "xlsx-style-vite";
export function exportExcel($table, row, excelName) {
//如果导出后多出空白行则修改rowspan否则可不用
// var tds = document.querySelectorAll(".el-table__footer td");
// tds.forEach(td => td.setAttribute("rowspan", "1"));
//从el-table表生成工作簿对象
//使用原始的格式,保留表格中的格式如%、小数末尾的0等
let workbook = utils.table_to_book($table, {
raw: true
});
//列宽需要导出的表格有多少列这里的i就小于多少
let keys = Object.keys(row).length
for (let i = 1; i < (5 + (keys - 5) * 5); i++) {
workbook.Sheets.Sheet1["!cols"].push({wpx: 100});
}
//设置单元格样式
for (const key in workbook.Sheets.Sheet1) {
if (
key !== "!cols" &&
key !== "!fullref" &&
key !== "!merges" &&
key !== "!ref" &&
key !== "!rows"
) {
//这里的s就是具体的样式如果想设置不一样的样式可以看xlsx-style文档
workbook.Sheets.Sheet1[key].s = {
//边框
border: {
top: {style: "thin"},
bottom: {style: "thin"},
left: {style: "thin",},
right: {style: "thin",}
},
//对齐
alignment: {
horizontal: "center",
vertical: "center",
wrapText: true
}
};
}
}
//修改合并单元格样式
let arr = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N",
"O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"];
//由于导出时合并单元格只识别左上角的单元格,合并单元格中其他单元格
//并不会存在,所以需要识别合并单元格中除左上角单元格外的单元格并添加
//带样式的单元格到其中不理解可以看四中的第2点。
try {
for (let item of workbook.Sheets.Sheet1["!merges"]) {
let style = {
border: {
top: {style: "thin"},
bottom: {style: "thin"},
left: {style: "thin",},
right: {style: "thin",}
},
alignment: {
horizontal: "center",
vertical: "center",
wrapText: true
}
};
let merge_s = {t: "s", v: "", s: style};
if (item.s.c === item.e.c) {
//纵向合并其中c为字母r为数字
let star = item.s.r;
let end = item.e.r;
for (let i = star + 1; i <= end; i++) {
workbook.Sheets.Sheet1[arr[item.s.c] + (i + 1)] = merge_s;
}
} else {
//横向合并
let star = item.s.c;
let end = item.e.c;
for (let i = star; i < end; i++) {
workbook.Sheets.Sheet1[arr[i + 1] + Number(item.s.r + 1)] = merge_s;
}
}
}
} catch (e) {
}
//将表格数据中的字符串转ArrayBuffer
function s2ab(s) {
let buf = new ArrayBuffer(s.length);
let view = new Uint8Array(buf);
for (let i = 0; i !== s.length; ++i) view[i] = s.charCodeAt(i) & 0xff;
return buf;
}
//这里的属性可以参考xlsx-style文档
let wbout = XLSX.write(workbook, {
bookType: "xlsx",
bookSST: false,
type: "binary"
});
try {
FileSaver.saveAs(
new Blob([s2ab(wbout)], {type: "application/octet-stream"}),
`${excelName}.xlsx`
);
} catch (e) {
if (typeof console !== "undefined") console.log(e, wbout);
}
}

View File

@@ -18,24 +18,24 @@
<expense-detail/>
</el-tab-pane>
<el-tab-pane label="分摊汇总" name="second" v-loading="loading">
<fvTable v-if="showTable" ref="tableRef" :tableConfig="tableConfig">
<fvTable v-if="showTable" border :tableConfig="tableConfig" :header-cell-style="{background:'#f5f7fa'}" >
<template #empty>
<el-empty description="暂无数据"/>
</template>
</fvTable>
</el-tab-pane>
</el-tabs>
<div v-if="shareData.taskId">
<baseTitle title="审核意见"></baseTitle>
<el-form-item prop="auditOpinion">
<el-input
v-model="auditOpinion"
:rows="3"
type="textarea"
placeholder="请输入审核意见"
/>
</el-form-item>
</div>
<div v-if="shareData.taskId">
<baseTitle title="审核意见"></baseTitle>
<el-form-item prop="auditOpinion">
<el-input
v-model="auditOpinion"
:rows="3"
type="textarea"
placeholder="请输入审核意见"
/>
</el-form-item>
</div>
<div class="approval-record">
<div class="approval-title">
<baseTitle title="审批记录"></baseTitle>
@@ -48,12 +48,15 @@
</div>
</div>
<div class="process">
<operation-render v-if="shareProcessViewer&& shareData.operationList && shareData.operationList.length > 0&&!changeDiagram" :operation-list="shareData.operationList"
:state="shareData.state"/>
<operation-render
v-if="shareProcessViewer&& shareData.operationList && shareData.operationList.length > 0&&!changeDiagram"
:operation-list="shareData.operationList"
:state="shareData.state"/>
<process-diagram-viewer v-if="shareProcessViewer&&changeDiagram" id-name="shareProcess"/>
</div>
</div>
<opinion v-if="shareData.taskId" :formData="shareData.formData" :taskId="shareData.taskId" v-model:value="auditOpinion"></opinion>
<opinion v-if="shareData.taskId" :formData="shareData.formData" :taskId="shareData.taskId"
v-model:value="auditOpinion"></opinion>
</template>
<script setup lang="jsx">
@@ -102,10 +105,10 @@ const tableConfig = reactive({
},
{
prop: 'researchStage',
label: '研发阶段',
label: '项目阶段',
align: 'center',
currentRender: ({row, index}) => {
if (row.researchStage&&row.researchStage !== null&&row.researchStage!==undefined) {
if (row.researchStage && row.researchStage !== null && row.researchStage !== undefined) {
return (<Tag dictType={'research_stage'} value={row.researchStage}/>)
} else {
return '--'
@@ -116,14 +119,18 @@ const tableConfig = reactive({
prop: 'afterTax',
label: '分摊金额',
align: 'center',
currentRender:({row})=>{
currentRender: ({row}) => {
return <span>{toThousands(row.afterTax)}</span>
}
}
],
api:'/workflow/mosr/cost/allocation/collect',
params:{
allocationId:route.query.id
api: '/workflow/mosr/cost/allocation/collect',
export: {
open: true,
fileName: "四川省国有资产经营投资管理有限责任公司科技创新项目费用分摊表"
},
params: {
allocationId: route.query.id
}
})
@@ -140,7 +147,7 @@ const getDetail = async () => {
processStore.noTakeList.value = data.noTakeList;
processStore.refuseList.value = data.refuseList;
processStore.passList.value = data.passList;
nextTick(()=>{
nextTick(() => {
shareProcessViewer.value = true
})
} else {
@@ -152,18 +159,20 @@ const getDetail = async () => {
}
}
const handleClick = (tab) => {
if (tab.index==0) {
if (tab.index == 0) {
getDetail()
}
}
getDetail()
</script>
<style scoped lang="scss">
:deep(.el-table--fit ){
:deep(.el-table--fit ) {
width: 100%;
height: 400px!important;
height: 479px !important;
}
:deep(.el-tabs__nav-scroll) {
width: 100%;
display: flex;