123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624 |
- <script setup>
- // import Sheet from '@/components/Sheet.vue'
- import { ref, computed, onMounted } from 'vue'
- const props = defineProps({
- TableInfo:{
- type:Object,
- default:{}
- }
- })
- const tableHeight = ref(0)
- const rowTable = ref(null)
- const disabled = ref(true)
- const EdbKeys = ref(["EdbName", "Unit"])
- const cellRef = ref(null)
- const dateArr = computed (() => {
- return props.TableInfo.TableData.Data.length ? props.TableInfo.TableData.Data[0].Data.map(_ => _.DataTime) : []
- })
- const columnHeader = computed(() => {
- return getColumnHeaderCode(
- props.TableInfo.TableData.Data ? props.TableInfo.TableData.Data.length : 0
- );
- });
- const rowHeader = computed(() => {
- let total_length = dateArr.value.length + props.TableInfo.TableData.TextRowData.length;
- return getRowHeaderCode(total_length);
- });
- const minRow = computed(() => {
- return Math.min(props.TableInfo.ExtraConfig.TableFreeze.FreezeStartRow, props.TableInfo.ExtraConfig.TableFreeze.FreezeEndRow)
- });
- const maxRow = computed(() => {
- return Math.max(props.TableInfo.ExtraConfig.TableFreeze.FreezeStartRow, props.TableInfo.ExtraConfig.TableFreeze.FreezeEndRow)
- });
- const maxCol = computed(() => {
- return Math.max(props.TableInfo.ExtraConfig.TableFreeze.FreezeStartCol, props.TableInfo.ExtraConfig.TableFreeze.FreezeEndCol)
- });
- const minCol = computed(() => {
- return Math.min(props.TableInfo.ExtraConfig.TableFreeze.FreezeStartCol, props.TableInfo.ExtraConfig.TableFreeze.FreezeEndCol)
- });
- //手机端pc端不同样式
- const dynamicSty = computed(()=>{
- return isMobile() ? 'mobile-sty' : 'pc-sty';
- })
- //判断是否是手机设备
- function isMobile() {
- // 判断是否是移动设备的正则表达式
- const mobileRegex = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i;
-
- // 获取用户代理信息
- const userAgent = navigator.userAgent;
-
- // 使用正则表达式检查用户代理信息
- return mobileRegex.test(userAgent);
- }
-
- // 字母列标
- function getColumnHeaderCode(len) {
- let tag_arr = [];
- for(let i=0;i<len;i++) tag_arr.push(String.fromCharCode(65+i));
- return tag_arr;
- }
- // 行标
- function getRowHeaderCode(len) {
- let tag_arr = [];
- for(let i=0;i<len;i++) tag_arr.push(String(1+i));
- return tag_arr;
- }
- // 判断展示小数位数值还是原来的值
- function showCellValue(cell){
- // console.log(cell)
- let Value=''
- if("Decimal" in cell&&cell.Decimal!=-1){
- const multiplier = Math.pow(10, cell.Decimal);
- const cellValue=+cell.Value
- Value= cell.Decimal == 0 ? Math.round(cellValue) : Math.round(cellValue * multiplier) / multiplier;
- }else{
- Value=cell.ShowValue
- }
- return Value
- }
- onMounted(() => {
- console.log('rowTable', rowTable.value.offsetHeight);
-
- tableHeight.value = rowTable.value ? rowTable.value.offsetHeight : 35;
- })
- // 是否固定列
- function isWithinColRange (index) {
- return rowHeader.value[index] >= minCol.value && rowHeader.value[index] <= maxCol.value
- }
- // 获取某一列的宽度
- function getColumnHeaderWidth (index) {
- return cellRef.value && cellRef.value ? cellRef.value[index].offsetWidth : 104
- }
- </script>
- <template>
- <div class="sheet-show-wrapper">
- <div :class="['table-wrapper',dynamicSty ]" v-if="props.TableInfo.ExcelType === 1">
- <table width="auto" border="0" class="table" :style="disabled ? 'width:100%':''" style="position: relative;">
- <thead>
- <tr ref="rowTable">
- <!-- 行头 -->
- <th class="th-tg sm"></th>
- <th class="th-tg"></th>
- <!-- 列头 -->
- <th
- ref="cellRef"
- v-for="(item, index) in columnHeader"
- :key="index"
- class="th-tg th-col"
- :data-cindex="item"
- :data-rindex="-1">
- {{item}}
- </th>
- </tr>
- </thead>
- <tbody>
- <tr v-for="(item, index) in EdbKeys" :key="item">
- <!-- 行头 -->
- <th class="th-tg sm"></th>
- <td rowspan="2" v-if="index === 0" class="head-column">
- 日期
- </td>
- <td
- v-for="(edb, sub_index) in TableInfo.TableData.Data"
- :key="sub_index"
- :data-rindex="-1"
- :data-cindex="columnHeader[sub_index]"
- :class="['data-cell',{
- 'one-bg':(index+1)%2&&index>0,
- 'tow-bg': (index+1)%2!==0&&index>0,
- 'head-column': index === 0,
- }]"
- >
- <template v-if="item === 'EdbName'">
- <span :class="{'edbname-td':disabled}" @click="edbJumpToBase(edb)">{{ edb.EdbAliasName||edb[item] }}</span>
- </template>
- <template v-else>{{ edb[item] }} / {{edb.Frequency }}</template>
- </td>
- </tr>
- <!-- 数据行 第一列日期-->
- <tr v-for="(date, dateIndex) in dateArr" :key="date" :style="TableInfo.ExtraConfig.TableFreeze ? `top: ${(dateIndex- minRow+1)*tableHeight}px;` : ''" :class="TableInfo.ExtraConfig.TableFreeze && rowHeader[dateIndex] >= minRow && rowHeader[dateIndex] <= maxRow ? 'fix' : ''">
- <!-- 行头 -->
- <th
- class="th-tg th-row sm"
- :data-cindex="-1"
- :data-rindex="rowHeader[dateIndex]"
- @contextmenu.prevent="rightClickHandle"
- >{{rowHeader[dateIndex]}}</th>
- <td
- :data-rindex="rowHeader[dateIndex]"
- :data-cindex="-1"
- :style="TableInfo.ExtraConfig.TableFreeze && isWithinColRange(dateIndex) ? `left: 0px;` : ''"
- :class="[TableInfo.ExtraConfig.TableFreeze && isWithinColRange(dateIndex) ? 'fix-col' : '']"
- >{{date}}</td>
- <td
- v-for="(edb, edb_index) in TableInfo.TableData.Data"
- :key="edb_index"
- :data-rindex="rowHeader[dateIndex]"
- :data-cindex="columnHeader[edb_index]"
- :style="TableInfo.ExtraConfig.TableFreeze && isWithinColRange(edb_index+dateArr.length) ? `left: ${(edb_index+dateArr.length- minCol+1)*getColumnHeaderWidth(edb_index+dateArr.length)}px;` : ''"
- :class="[([2,3,5].includes(edb.Data.find(_ =>_.DataTime === date)?.DataType)&&edb.Data.find(_ =>_.DataTime === date)?.ShowValue)?'insert': '', TableInfo.ExtraConfig.TableFreeze && isWithinColRange(edb_index+dateArr.length) ? 'fix-col' : '']"
- >
- <!-- 实际值/插值 -->
- <span
- :data-rindex="rowHeader[dateIndex]"
- :data-cindex="columnHeader[edb_index]"
- v-if="(edb.Data.find(_ =>_.DataTime === date)?.ShowValue&&!edb.Data.find(_ =>_.DataTime === date).CanEdit)||disabled"
- >
- {{showCellValue(edb.Data.find(_ =>_.DataTime === date)) || '-'}}
- </span>
- </td>
- </tr>
- <!-- 文本行 -->
- <tr v-for="(row,index) in TableInfo.TableData.TextRowData" :key="index" :style="TableInfo.ExtraConfig.TableFreeze ? `top: ${(index+dateArr.length-minRow+1)*tableHeight}px;` : ''" :class="TableInfo.ExtraConfig.TableFreeze && rowHeader[index+dateArr.length] >= minRow && rowHeader[index+dateArr.length] <= maxRow ? 'fix' : ''">
- <!-- 行头 -->
- <th
- class="th-tg th-row sm"
- @contextmenu.prevent="rightClickHandle"
- :data-rindex="rowHeader[index+dateArr.length]"
- :data-cindex="-1"
- >{{rowHeader[index+dateArr.length]}}</th>
- <td
- v-for="(cell, cell_index) in row"
- :key="`${index}_${cell_index}`"
- :data-rindex="rowHeader[index+dateArr.length]"
- :data-cindex="cell_index===0?-1:columnHeader[cell_index-1]"
- :style="TableInfo.ExtraConfig.TableFreeze && isWithinColRange(cell_index+dateArr.length) ? `left: ${(cell_index+dateArr.length- minCol+1)*getColumnHeaderWidth(cell_index+dateArr.length)}px;` : ''"
- :class="[([2,3,5].includes(cell.DataType)&&cell.ShowValue)?'insert': '', TableInfo.ExtraConfig.TableFreeze && isWithinColRange(cell_index+dateArr.length) ? 'fix-col' : '']"
- >
- <span
- :data-rindex="rowHeader[index+dateArr.length]"
- :data-cindex="cell_index===0?-1:columnHeader[cell_index-1]"
- v-if="(cell.ShowValue&&!cell.CanEdit)||disabled"
- > {{cell.ShowValue}}</span>
- </td>
- </tr>
- </tbody>
- </table>
- </div>
- <div :class="['table-wrapper',dynamicSty ]" v-else>
- <table width="auto" border="0" class="table" :style="disabled ? 'width:100%':''" style="position: relative;">
- <thead>
- <tr ref="rowTable">
- <!-- 行头 -->
- <th class="th-tg sm"></th>
- <th class="th-tg"></th>
- <th class="th-tg"></th>
- <!-- 列头 -->
- <th
- v-for="(item, index) in rowHeader"
- :key="index"
- ref="cellRef"
- class="th-tg th-col"
- :data-cindex="-1"
- :data-rindex="rowHeader[index]">
- {{item}}
- </th>
- </tr>
- </thead>
- <tbody>
- <tr>
- <!-- 行头 -->
- <th class="th-tg sm"></th>
- <td colspan="2" class="head-column">
- 日期
- </td>
- <!-- 日期列 -->
- <td
- v-for="(date, sub_index) in dateArr"
- :key="date"
- :data-rindex="rowHeader[sub_index]"
- :data-cindex="-1"
-
- :style="TableInfo.ExtraConfig.TableFreeze && isWithinColRange(sub_index) ? `left: ${(sub_index- minCol+1)*getColumnHeaderWidth(sub_index)}px;` : ''"
- :class="['data-cell','head-column',
- TableInfo.ExtraConfig.TableFreeze && isWithinColRange(sub_index) ? 'fix-col' : '']"
- >{{ date }}</td>
- <!-- 文本列 -->
- <td
- v-for="(column,index) in TableInfo.TableData.TextRowData"
- :key="index"
- :data-cindex="-1"
- :data-rindex="rowHeader[index+dateArr.length]"
- :style="TableInfo.ExtraConfig.TableFreeze && isWithinColRange(index+dateArr.length) ? `left: ${(index+dateArr.length- minCol+1)*getColumnHeaderWidth(index+dateArr.length)}px;` : ''"
- :class="'head-column', [([2,3,5].includes(column[0].DataType)&&column[0].ShowValue)?'insert': '', TableInfo.ExtraConfig.TableFreeze && isWithinColRange(index+dateArr.length) ? 'fix-col' : '']"
- @click="clickCell($event,column[0])"
- @dblclick="dblClickCell($event,column[0])"
- @copy="copyCellHandle($event,column[0])"
- @paste="pasteCellHandle($event,column[0])"
- >
- <span
- :data-cindex="-1"
- :data-rindex="rowHeader[index+dateArr.length]"
- > {{column[0].ShowValue}}</span>
- </td>
- </tr>
- <!-- 指标行 -->
- <tr v-for="(edb, edb_index) in TableInfo.TableData.Data" :key="edb.EdbInfoId" :style="TableInfo.ExtraConfig.TableFreeze ? `top: ${(edb_index- minRow+1)*tableHeight}px;` : ''" :class="TableInfo.ExtraConfig.TableFreeze && rowHeader[edb_index] >= minRow && rowHeader[edb_index] <= maxRow ? 'fix' : ''">
- <!-- 行头 -->
- <th
- class="th-tg th-row sm"
- :data-cindex="columnHeader[edb_index]"
- :data-rindex="-1"
- @contextmenu.prevent="rightClickHandle"
- >
- {{columnHeader[edb_index]}}
- </th>
-
- <!-- 名称 单位 -->
- <td
- v-for="(item, index) in EdbKeys"
- :key="index"
- :data-rindex="-1"
- :data-cindex="columnHeader[edb_index]"
- @click="() => { !disabled && item==='EdbName' && clickEdbName(edb)}"
- >
- <template v-if="item === 'EdbName'">
- <span :class="{'edbname-td':disabled}" @click="edbJumpToBase(edb)">{{ edb.EdbAliasName||(edb[item]) }}</span>
- </template>
- <template v-else>{{ edb[item] }}/{{edb.Frequency }}</template>
- </td>
- <!-- 数据列 -->
- <td
- v-for="(data, data_index) in edb.Data"
- :key="`${edb.EdbInfoId}_${rowHeader[data_index]}_${columnHeader[edb_index]}`"
- :data-rindex="rowHeader[data_index]"
- :data-cindex="columnHeader[edb_index]"
- :style="TableInfo.ExtraConfig.TableFreeze && isWithinColRange(data_index) ? `left: ${(data_index- minCol+1)*getColumnHeaderWidth(data_index)}px;` : ''"
- :class="[([2,3,5].includes(data.DataType)&&data.ShowValue)?'insert': '', TableInfo.ExtraConfig.TableFreeze && isWithinColRange(data_index) ? 'fix-col' : '']"
- @click="clickCell($event,data)"
- @dblclick="dblClickCell($event,data)"
- @copy="copyCellHandle($event,data)"
- @paste="pasteCellHandle($event,data)"
- >
- <!-- 实际值/插值 -->
- <span
- :data-rindex="rowHeader[data_index]"
- :data-cindex="columnHeader[edb_index]"
- >
- {{data.ShowValue || '-'}}
- </span>
- </td>
- <!-- 文本列 -->
- <td
- v-for="(column,column_index) in TableInfo.TableData.TextRowData"
- :key="`${rowHeader[column_index+dateArr.length]}_${columnHeader[edb_index]}`"
- :data-rindex="rowHeader[column_index+dateArr.length]"
- :data-cindex="columnHeader[edb_index]"
- :style="TableInfo.ExtraConfig.TableFreeze && isWithinColRange(column_index+dateArr.length) ? `left: ${(column_index+dateArr.length- minCol+1)*getColumnHeaderWidth(column_index+dateArr.length)}px;` : ''"
- :class="[([2,3,5].includes(column[edb_index+1].DataType)&&column[edb_index+1].ShowValue)?'insert': '', TableInfo.ExtraConfig.TableFreeze && isWithinColRange(column_index+dateArr.length) ? 'fix-col' : '']"
- @click="clickCell($event,column[edb_index+1])"
- @dblclick="dblClickCell($event,column[edb_index+1])"
- @copy="copyCellHandle($event,column[edb_index+1])"
- @paste="pasteCellHandle($event,column[edb_index+1])"
- >
- <span
- :data-rindex="rowHeader[column_index+dateArr.length]"
- :data-cindex="columnHeader[edb_index]"
- > {{column[edb_index+1].ShowValue}}</span>
- />
- </td>
-
- </tr>
- </tbody>
- </table>
- </div>
- <div class="tool sheet-bottom">
- <div class="sheet-source"
- v-if="TableInfo.SourcesFrom&&JSON.parse(TableInfo.SourcesFrom).isShow"
- :style="`
- color: ${ JSON.parse(TableInfo.SourcesFrom).color };
- font-size: ${ JSON.parse(TableInfo.SourcesFrom).fontSize }px;
- `"
- >
- source:<em>{{ JSON.parse(TableInfo.SourcesFrom).text}}</em>
- </div>
- </div>
- </div>
- </template>
- <style lang='scss' scoped>
- // sheet-show-wrapper 相关样式
- .sheet-show-wrapper {
- max-width: 1200px;
- overflow: hidden;
- position: relative;
- margin: 0 auto;
- background: #fff;
- // table-wrapper 样式
- .table-wrapper {
- max-width: calc(100vw - 20px);
- max-height: calc(100vh - 400px);
- margin: 0 auto;
- overflow: auto;
- -webkit-overflow-scrolling: touch; /* ios滚动条 */
- }
- .tool {
- margin-top: 5px;
- span {
- cursor: pointer;
- }
- }
- .sheet-bottom {
- display: flex;
- align-items: center;
- justify-content: space-between;
- white-space: nowrap;
- padding: 0 10px;
- .sheet-source {
- width: 30%;
- min-width: 150px;
- overflow: hidden;
- text-overflow: ellipsis;
- }
- }
- }
- // 表格相关样式
- .table {
- width: 100%;
- font-size: 14px;
- color: #333;
- td, th {
- width: 104px;
- min-width: 104px;
- height: 35px;
- background: #fff;
- text-align: center;
- word-break: break-all;
- border: none;
- outline-color: #dcdfe6;
- outline-style: solid;
- outline-width: 1px;
- word-wrap: break-word;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
- position: relative;
- &:first-child {
- border-left: 1px solid #dcdfe6;
- }
- &.td-chose::after {
- position: absolute;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- content: "";
- display: block;
- outline: 0;
- border: 2px solid #0033FF;
- box-shadow: 0 0 5px rgba(73, 177, 249, .5);
- }
- &.insert {
- background: #FFEFDD;
- }
- .edbname-td {
- &:hover {
- text-decoration: underline;
- }
- }
- &.fix-col {
- position: sticky;
- left: 0;
- z-index: 98; // 表格右键操作弹窗为99
- }
- }
- .th-tg {
- background: #EBEEF5;
- &:hover {
- cursor: pointer;
- background: #ddd;
- }
- &.sm {
- width: 36px;
- min-width: 36px;
- max-width: 36px;
- }
- }
- .data-cell {
- color: #333;
- &.one-bg {
- background-color: #EFEEF1;
- }
- &.two-bg {
- background-color: #fff;
- }
- }
- .thead-sticky {
- position: sticky;
- top: 0;
- }
- .head-column {
- background-color: #505B78;
- color: #fff;
- }
- .split-word {
- span {
- display: inline;
- }
- }
- }
- tr {
- &.fix {
- position: sticky;
- top: 0;
- z-index: 98; // 表格右键操作弹窗为99
- }
- }
- // 滚动条样式
- ::-webkit-scrollbar {
- width: 6px;
- height: 6px;
- }
- ::-webkit-scrollbar-track {
- background: rgb(239, 239, 239);
- border-radius: 2px;
- }
- ::-webkit-scrollbar-thumb {
- background: #ccc;
- border-radius: 10px;
- &:hover {
- background: #888;
- }
- }
- ::-webkit-scrollbar-corner {
- background: #666;
- }
- // PC端表格样式
- .pc-sty table {
- table-layout: auto;
- td, th {
- width: auto;
- height: auto;
- padding: 0.4em 0;
- }
- }
- // 移动端表格样式
- .mobile-sty table {
- table-layout: auto;
- td, th {
- min-width: 120px;
- height: 40px;
- }
- }
- // 背景水印样式
- .background-watermark {
- background-repeat: no-repeat;
- background-position: center center;
- background-size: 100%;
- }
- @media screen and (min-width: 650px) {
- .sheet-show-wrapper {
- .table-wrapper {
- max-height: calc(100vh - 220px);
- }
- .tool {
- margin-top: 3px;
- }
- .sheet-bottom {
- padding: 0 5px;
- .sheet-source {
- width: 15%;
- min-width: 75px;
- }
- }
- }
- // 表格相关样式
- .table {
- width: 100%;
- font-size: 7px;
- color: #333;
- td, th {
- width: 52px;
- min-width: 52px;
- height: 17px;
- }
- .th-tg {
- &.sm {
- width: 18px;
- min-width: 18px;
- max-width: 18px;
- }
- }
- }
- // 滚动条样式
- ::-webkit-scrollbar {
- width: 3px;
- height: 3px;
- }
- ::-webkit-scrollbar-track {
- background: rgb(239, 239, 239);
- border-radius: 1px;
- }
- ::-webkit-scrollbar-thumb {
- background: #ccc;
- border-radius: 5px;
- }
- // 移动端表格样式
- .mobile-sty table {
- td, th {
- min-width: 60px;
- height: 20px;
- }
- }
- }
- </style>
|