123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 |
- <template>
- <div class="app-container p-2">
- <el-row :gutter="20">
- <el-col :lg="30" :xs="24" style="">
- <el-row :span="24" :gutter="10">
- <el-col :span="18" label="任务名称">
- <h2 v-if="detailData.title" key="business" style="font-weight: bolder">{{ detailData.title }}</h2>
- <p class="report-period">【填报周期】:{{ detailData.start }} 至 {{ detailData.end }}</p>
- </el-col>
- <el-col :span="1.5">
- <el-button type="primary" @click="exportToExcel()"> 导出表格 </el-button>
- </el-col>
- <el-col :span="1.5">
- <el-button type="danger" @click="handleReturn()"> 返回 </el-button>
- </el-col>
- </el-row>
- </el-col>
- <el-col :lg="30" :xs="24">
- <div :style="{ height: tableHeight + 'px' }">
- <hot-table v-if="tableData.length > 0" ref="wrapper" :data="tableData" :settings="hotSettings" />
- </div>
- </el-col>
- </el-row>
- </div>
- </template>
- <script setup lang="ts">
- import * as XLSX from 'xlsx';
- import { fillDetail } from '@/api/dataFilling/datafilling';
- import { HotTable } from '@handsontable/vue3';
- import 'handsontable/languages';
- import 'handsontable/dist/handsontable.full.css';
- import { registerAllModules } from 'handsontable/registry';
- import { deepClone } from '@/utils';
- registerAllModules();
- const emits = defineEmits(['close']);
- const props = defineProps<{
- eventId: string | number;
- }>();
- // 更新表头以匹配新的数据结构
- const editableHeaders = ref([]);
- const tableData = ref([]);
- const hotData = ref([]);
- const detailData = ref({
- title: '表单数据',
- start: '',
- end: ''
- });
- let tableHeight = window.innerHeight - 230;
- const exportToExcel = () => {
- const data = deepClone(tableData.value);
- data.unshift(editableHeaders.value);
- const worksheet = XLSX.utils.aoa_to_sheet(data, {});
- const workbook = { Sheets: { data: worksheet }, SheetNames: ['data'] };
- XLSX.utils.book_append_sheet(workbook, worksheet, 'Sheet1');
- XLSX.writeFile(workbook, '导出数据.xlsx');
- };
- const fetchFillDetail = async () => {
- fillDetail({ report_id: props.eventId }).then((res: any) => {
- detailData.value.start = res.start_time;
- detailData.value.end = res.end_time;
- const headers = [];
- const data = [];
- res.data.forEach((item, index) => {
- let arr = [];
- for (let key in item) {
- if (item.hasOwnProperty(key)) {
- const value = item[key];
- if (index === 0) {
- headers.push(value);
- } else {
- arr.push(value);
- }
- }
- }
- if (arr.length > 0) {
- data.push(arr);
- }
- });
- editableHeaders.value = headers;
- tableData.value = data;
- });
- };
- const handleReturn = () => {
- emits('close');
- };
- const hotSettings = reactive({
- language: 'zh-CN',
- colHeaders: editableHeaders,
- readOnly: true,
- rowHeaders: true,
- autoColumnSize: true,
- width: '100%', // auto or 100%
- height: '100%', // auto or 100%
- licenseKey: 'non-commercial-and-evaluation', // 隐藏版权文字
- colWidths: 129, // 默认单元格宽度
- rowHeights: 28, // 默认单元格高度
- wordWrap: true // 单元格文字是否换行展示
- });
- onMounted(() => {
- fetchFillDetail();
- });
- </script>
- <style scoped>
- .app-container {
- font-family: Avenir, Helvetica, Arial, sans-serif;
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale;
- color: #2c3e50;
- }
- .report-period {
- margin-top: 10px;
- font-size: 14px;
- color: #606266;
- }
- .editable-span {
- cursor: default;
- }
- .editable-header {
- cursor: default;
- }
- </style>
|