From 4f238e1ff525b6aa1f8c9981f044d606a89734ce Mon Sep 17 00:00:00 2001 From: riku <risaku@163.com> Date: 星期四, 24 十月 2024 08:27:19 +0800 Subject: [PATCH] 1. 新增完成展示下载的excel文件功能 --- src/views/fysp/data-product/components/BaseDataProduct.vue | 216 ++++++++++++++++++++++++++++++++++++++++++++++++------ 1 files changed, 192 insertions(+), 24 deletions(-) diff --git a/src/views/fysp/data-product/components/BaseDataProduct.vue b/src/views/fysp/data-product/components/BaseDataProduct.vue index 9030b38..b53953e 100644 --- a/src/views/fysp/data-product/components/BaseDataProduct.vue +++ b/src/views/fysp/data-product/components/BaseDataProduct.vue @@ -34,7 +34,7 @@ <el-form ref="expandRef" :inline="true"> <CompQuickSet @quick-set="setOptions"></CompQuickSet> </el-form> - <el-space> + <el-space ref="segmentedRef"> <el-segmented :model-value="activeSheet" :options="sheetNames" @@ -43,32 +43,69 @@ </el-space> <el-table ref="tableRef" - :data="excelData" + :data="activeExcelData.data" v-loading="loading" - table-layout="fixed" + table-layout="auto" size="small" :height="tableHeight" + fit + flexible + stripe border > - <template v-if="excelData"> + <template v-if="activeExcelData.head"> <el-table-column - v-for="(value, key, index) in excelData[0]" + v-for="(item, index) in activeExcelData.head" :key="index" - :prop="key" - :label="key" + :prop="item.name" + :label="item.name" > + <template v-if="item.children" #default="{ row }"> + <span v-html="row[item.name]"></span> + <el-table-column + v-for="(item1, index1) in item.children" + :key="index1" + :prop="item1.name" + :label="item1.name" + > + <template v-if="item1.children" #default="{ row1 }"> + <span v-html="row1[item1.name]"></span> + <el-table-column + v-for="(item2, index2) in item1.children" + :key="index2" + :prop="item2.name" + :label="item2.name" + > + <template v-if="item2.children" #default="{ row2 }"> + <span v-html="row2[item2.name]"></span> + </template> + </el-table-column> + </template> + </el-table-column> + </template> </el-table-column> </template> </el-table> - <div v-if="excelHtml" v-html="excelHtml"></div> + <!-- <vue-office-excel + :src="excel" + :style="'height: ' + tableHeight" + @rendered="renderedHandler" + @error="errorHandler" + /> --> </template> <script setup> /** * 闂鍔ㄦ�佽窡韪� */ +//寮曞叆VueOfficeExcel缁勪欢 +import VueOfficeExcel from '@vue-office/excel'; +//寮曞叆鐩稿叧鏍峰紡 +import '@vue-office/excel/lib/index.css'; + import { ref, onMounted } from 'vue'; import dayjs from 'dayjs'; import * as XLSX from 'xlsx'; +import * as ExcelJS from 'exceljs'; import dataproductApi from '@/api/fysp/dataproductApi'; import CompReportDownloadDialog from './CompReportDownloadDialog.vue'; @@ -100,12 +137,14 @@ const tableHeight = ref('500'); let workbook; const sheetNames = ref(); +const excelDatas = ref(new Map()); const activeSheet = ref(); -const excelData = ref(); -const excelHtml = ref(); +const activeExcelData = ref({}); +const excel = ref(''); const searchRef = ref(null); const expandRef = ref(null); +const segmentedRef = ref(null); function setOptions(param) { formSearch.value.locations = param.locations; @@ -134,28 +173,66 @@ scensetypeid: scenetype.value }; + excelDatas.value.clear(); loading.value = true; dataproductApi .downloadProduct(area, props.productType, forceUpdate ? forceUpdate : false) - .then((res) => { - const data = new Uint8Array(res); - workbook = XLSX.read(data, { type: 'array' }); - sheetNames.value = workbook.SheetNames; - activeSheet.value = sheetNames.value[0]; - getTable(activeSheet.value); + .then(async (res) => { + // const data = new Uint8Array(res); + res.arrayBuffer().then((data) => { + workbook = XLSX.read(data, { type: 'array' }); + sheetNames.value = workbook.SheetNames; + activeSheet.value = sheetNames.value[0]; + getTable(activeSheet.value); + }); + + // const workbook = new ExcelJS.Workbook(); + // await workbook.xlsx.load(res); + // workbook.eachSheet(function (worksheet, sheetId) { + // console.log(worksheet.name); + // }); + // const sheet1 = workbook.worksheets[0] + // const row = sheet1.getRow(1) + // console.log(row); + + // console.log(res); + // console.log(new ArrayBuffer(res)); + // res.arrayBuffer().then(r=>{ + // excel.value = r + // }) + + // excel.value = new ArrayBuffer(res) }) .finally(() => (loading.value = false)); } function getTable(sheetName) { - const worksheet = workbook.Sheets[sheetName]; - const tableData = XLSX.utils.sheet_to_json(worksheet, { header: 3 }); - // const tableData = XLSX.utils.sheet_to_csv(worksheet); - console.log(tableData); - console.log(tableData[0]); - combineTableHead(tableData); + if (!excelDatas.value.has(sheetName)) { + const worksheet = workbook.Sheets[sheetName]; + // const tableData = XLSX.utils.sheet_to_json(worksheet, { header: 3 }); + let tableData = XLSX.utils.sheet_to_txt(worksheet); + // console.log(tableData); - excelData.value = props.beforeDataShow(tableData); + const regx = new RegExp(/"([^"]|\n)+"/, 'g'); + let matchTxt = tableData.match(regx); + + if (matchTxt) { + matchTxt.forEach((txt) => { + let newTxt = txt.replace(new RegExp(/\n/, 'g'), '<br />'); + newTxt = newTxt.replace(new RegExp(/"/, 'g'), ''); + tableData = tableData.replace(txt, newTxt); + }); + // console.log(tableData); + } + + const t = strToTableObj(tableData); + // console.log(head); + // console.log(data); + excelDatas.value.set(sheetName, t); + } + activeExcelData.value = excelDatas.value.get(sheetName); + + // activeExcelData.value = props.beforeDataShow(tableData); } // 鏍规嵁琛ㄥご鐨勮鏁帮紝鍚堝苟琛ㄥご @@ -173,11 +250,102 @@ function calcTableHeight() { const h1 = searchRef.value.$el.offsetHeight; const h2 = expandRef.value.$el.offsetHeight; + const h3 = segmentedRef.value.$el.offsetHeight; - const h = h1 + h2; + const h = h1 + h2 + h3; return `calc(100vh - ${h}px - 60px - var(--el-main-padding) * 2)`; } +function renderedHandler() { + console.log('娓叉煋瀹屾垚'); +} +function errorHandler(e) { + console.log('娓叉煋澶辫触', e); +} + +function strToTableObj(data, headNum) { + const rows = data.split('\n').map((r) => r.split('\t')); + if (rows.length == 0) return; + + let header = 1; + for (let i = 1; i < rows.length; i++) { + const row = rows[i]; + if (row.length == 0) { + break; + } + if (row[0] == '') { + header++; + } else { + break; + } + } + + if (rows.length < header) { + throw new Error(`鏂囦欢琛屾暟灏忎簬${header}`); + } + // 琛ㄥご + let lastHead = []; + // 灞炴�у悕 + const dataKeys = []; + let offset = 1; + for (let i = header - 1; i >= 0; i--) { + const row = rows[i]; + if (lastHead.length == 0) { + row.forEach((r, y) => { + lastHead.push({ name: r }); + dataKeys.push(r); + }); + } else { + const newHead = []; + row.forEach((r, y) => { + if (dataKeys[y] == '') { + dataKeys[y] = r; + } + + const last = lastHead[y]; + if (!last) { + console.log(last); + } + if (last.name == '') { + newHead.push({ name: r }); + offset++; + } else if (r != '') { + newHead.push({ + name: r, + children: [last] + }); + offset = 1; + } else { + newHead.push({ name: '' }); + let _index = newHead.length - 1 - offset; + _index = _index >= 0 ? _index : 0; + newHead[_index].children.push(last); + offset++; + } + }); + lastHead = newHead; + } + } + const heads = []; + lastHead.forEach((h) => { + if (h && h.name != '') { + heads.push(h); + } + }); + + const tableData = []; + for (let i = header; i < rows.length; i++) { + const row = rows[i]; + const data = {}; + row.forEach((r, y) => { + data[dataKeys[y]] = r; + }); + tableData.push(data); + } + + return { head: heads, data: tableData }; +} + onMounted(() => { tableHeight.value = calcTableHeight(); // handleSearch() -- Gitblit v1.9.3