850e14f7 by lxs

入表功能调整

1 parent f20053f0
...@@ -299,7 +299,13 @@ const getCostData = () => { ...@@ -299,7 +299,13 @@ const getCostData = () => {
299 loading.value = true; 299 loading.value = true;
300 getCostList().then((res: any) => { 300 getCostList().then((res: any) => {
301 loading.value = false; 301 loading.value = false;
302 tableData.value = res.data || []; 302 const data = res.data || [];
303 tableData.value = data.map(item => {
304 item.checked1 = false;
305 item.checked2 = false;
306 item.checked3 = false;
307 return item;
308 })
303 getMergeRow(); 309 getMergeRow();
304 }).catch((res) => { 310 }).catch((res) => {
305 loading.value = false; 311 loading.value = false;
...@@ -736,7 +742,7 @@ const setTableFields = (info) => { ...@@ -736,7 +742,7 @@ const setTableFields = (info) => {
736 } 742 }
737 arrYear.forEach(item => { 743 arrYear.forEach(item => {
738 const field = `${item}`; 744 const field = `${item}`;
739 fields.push({ label: `${item}年`, field: field, type: 'input', width: 100, columClass: 'edit_cell' },) 745 fields.push({ label: `${item}年`, field: field, type: 'input', width: 100, align: 'right', columClass: 'edit_cell' },)
740 row[field] = ''; 746 row[field] = '';
741 }) 747 })
742 costFileds.value = row; 748 costFileds.value = row;
...@@ -744,7 +750,7 @@ const setTableFields = (info) => { ...@@ -744,7 +750,7 @@ const setTableFields = (info) => {
744 const currDay = date.toLocaleDateString('zh-CN', { year: 'numeric', month: 'long' }); 750 const currDay = date.toLocaleDateString('zh-CN', { year: 'numeric', month: 'long' });
745 tableField.value.at(-1).visible = true; 751 tableField.value.at(-1).visible = true;
746 tableField.value = tableField.value.filter(item => item.field.indexOf('name') > -1 || item.field == 'total'); 752 tableField.value = tableField.value.filter(item => item.field.indexOf('name') > -1 || item.field == 'total');
747 tableField.value.splice(-1, 0, ...fields, { label: currDay, field: 'baseNum', type: 'input', width: 120, columClass: 'edit_cell' }); 753 tableField.value.splice(-1, 0, ...fields, { label: currDay, field: 'baseNum', type: 'input', width: 120, align: 'right', columClass: 'edit_cell' });
748 // 设置table数据 754 // 设置table数据
749 let datas: any = []; 755 let datas: any = [];
750 tableData.value.map(t => { 756 tableData.value.map(t => {
...@@ -930,10 +936,10 @@ const s2ab = (s) => { ...@@ -930,10 +936,10 @@ const s2ab = (s) => {
930 936
931 // 定义边框样式 - 实线边框 937 // 定义边框样式 - 实线边框
932 const borderStyle = { 938 const borderStyle = {
933 top: { style: 'thin', color: { rgb: 'D9D9D9' } }, 939 top: { style: 'thin', color: { rgb: '888888' } },
934 bottom: { style: 'thin', color: { rgb: 'D9D9D9' } }, 940 bottom: { style: 'thin', color: { rgb: '888888' } },
935 left: { style: 'thin', color: { rgb: 'D9D9D9' } }, 941 left: { style: 'thin', color: { rgb: '888888' } },
936 right: { style: 'thin', color: { rgb: 'D9D9D9' } } 942 right: { style: 'thin', color: { rgb: '888888' } }
937 }; 943 };
938 944
939 // 字体配置 945 // 字体配置
...@@ -966,6 +972,11 @@ const exportDetailsToExcel = async () => { ...@@ -966,6 +972,11 @@ const exportDetailsToExcel = async () => {
966 const headers = fields.map(item => item.label) 972 const headers = fields.map(item => item.label)
967 wsData.push(headers) 973 wsData.push(headers)
968 974
975 // 判断哪些列是数值类型
976 const numField = fields.filter(item => item.field.indexOf('name') == -1);
977 const numericFields = numField.map(f => f.field);
978 const isNumericColumn = fields.map(field => numericFields.includes(field.field));
979
969 // 处理数据行 980 // 处理数据行
970 checkedData.value.forEach(item => { 981 checkedData.value.forEach(item => {
971 const row = fields.map(f => { 982 const row = fields.map(f => {
...@@ -982,8 +993,6 @@ const exportDetailsToExcel = async () => { ...@@ -982,8 +993,6 @@ const exportDetailsToExcel = async () => {
982 993
983 // 添加合计行 994 // 添加合计行
984 const totalRow = ['合计', '', '', '']; 995 const totalRow = ['合计', '', '', ''];
985 const numField = fields.filter(item => item.field.indexOf('name') == -1);
986 const numericFields = numField.map(f => f.field);
987 let totalValues = {} 996 let totalValues = {}
988 997
989 // 初始化合计值 998 // 初始化合计值
...@@ -1021,7 +1030,7 @@ const exportDetailsToExcel = async () => { ...@@ -1021,7 +1030,7 @@ const exportDetailsToExcel = async () => {
1021 // 自动调整列宽 1030 // 自动调整列宽
1022 const colWidths = fields.map((field, index) => { 1031 const colWidths = fields.map((field, index) => {
1023 const defaultWidth = field.width || 100 // 默认宽度100 1032 const defaultWidth = field.width || 100 // 默认宽度100
1024 const colWidth = defaultWidth * 0.75; // 留一些余地 1033 const colWidth = 100 * 0.75; // 留一些余地
1025 1034
1026 // 取表头宽度和内容宽度的较大值 1035 // 取表头宽度和内容宽度的较大值
1027 return { wpx: colWidth } // 使用像素宽度 1036 return { wpx: colWidth } // 使用像素宽度
...@@ -1092,8 +1101,14 @@ const exportDetailsToExcel = async () => { ...@@ -1092,8 +1101,14 @@ const exportDetailsToExcel = async () => {
1092 1101
1093 // 表头样式 1102 // 表头样式
1094 if (R === 0) { 1103 if (R === 0) {
1104 // 如果该列是数值列,则表头也右对齐
1105 const isNumeric = isNumericColumn[C];
1095 ws[cellAddress].s = { 1106 ws[cellAddress].s = {
1096 ...defaultStyle, 1107 ...defaultStyle,
1108 alignment: {
1109 vertical: 'center',
1110 horizontal: isNumeric ? 'right' : 'left'
1111 },
1097 fill: { fgColor: { rgb: 'F2F2F2' } } // 表头背景色(可选) 1112 fill: { fgColor: { rgb: 'F2F2F2' } } // 表头背景色(可选)
1098 } 1113 }
1099 continue 1114 continue
...@@ -1105,8 +1120,9 @@ const exportDetailsToExcel = async () => { ...@@ -1105,8 +1120,9 @@ const exportDetailsToExcel = async () => {
1105 ...defaultStyle, 1120 ...defaultStyle,
1106 alignment: { 1121 alignment: {
1107 vertical: 'center', 1122 vertical: 'center',
1108 horizontal: C > 3 ? 'right' : 'left' 1123 horizontal: isNumericColumn[C] ? 'right' : 'left'
1109 } 1124 },
1125 // fill: { fgColor: { rgb: 'FFF1D4' } } // 合计行背景色(可选)
1110 } 1126 }
1111 continue 1127 continue
1112 } 1128 }
...@@ -1116,7 +1132,7 @@ const exportDetailsToExcel = async () => { ...@@ -1116,7 +1132,7 @@ const exportDetailsToExcel = async () => {
1116 const field = fields[fieldIndex] 1132 const field = fields[fieldIndex]
1117 1133
1118 // 数值列右对齐 1134 // 数值列右对齐
1119 if (numericFields.includes(field.field)) { 1135 if (isNumericColumn[C]) {
1120 ws[cellAddress].s = { 1136 ws[cellAddress].s = {
1121 ...defaultStyle, 1137 ...defaultStyle,
1122 alignment: { 1138 alignment: {
...@@ -1200,8 +1216,8 @@ const exportBookToExcel = async () => { ...@@ -1200,8 +1216,8 @@ const exportBookToExcel = async () => {
1200 1216
1201 // 设置单元格样式 1217 // 设置单元格样式
1202 const range = XLSXS.utils.decode_range(ws['!ref']) 1218 const range = XLSXS.utils.decode_range(ws['!ref'])
1203 // 数值字段(除title外的所有字段) 1219 // 确定哪些列是数值列(field不包含'title'的列)
1204 const numericFields = bookHeaders.value.slice(1).map(f => f.field); 1220 const isNumericColumn = bookHeaders.value.map(f => f.field.indexOf('title') === -1);
1205 1221
1206 for (let R = range.s.r; R <= range.e.r; ++R) { 1222 for (let R = range.s.r; R <= range.e.r; ++R) {
1207 for (let C = range.s.c; C <= range.e.c; ++C) { 1223 for (let C = range.s.c; C <= range.e.c; ++C) {
...@@ -1222,40 +1238,35 @@ const exportBookToExcel = async () => { ...@@ -1222,40 +1238,35 @@ const exportBookToExcel = async () => {
1222 border: borderStyle // 添加边框样式 1238 border: borderStyle // 添加边框样式
1223 } 1239 }
1224 1240
1241 // 判断当前列是否为数值列
1242 const isNumeric = isNumericColumn[C];
1243 // 数值列的对齐方式
1244 const alignment = {
1245 vertical: 'center',
1246 horizontal: isNumeric ? 'right' : 'left'
1247 };
1225 // 表头样式(第1行) 1248 // 表头样式(第1行)
1226 if (R === 0) { 1249 if (R === 0) {
1227 ws[cellAddress].s = { 1250 ws[cellAddress].s = {
1228 ...defaultStyle, 1251 ...defaultStyle,
1252 alignment: alignment, // 使用统一对齐方式
1229 fill: { fgColor: { rgb: 'F2F2F2' } } // 表头背景色(可选) 1253 fill: { fgColor: { rgb: 'F2F2F2' } } // 表头背景色(可选)
1230 } 1254 }
1231 continue 1255 continue
1232 } 1256 }
1233 1257
1234 // 获取当前列对应的字段 1258 // 数据行样式
1235 const field = bookHeaders.value[C];
1236
1237 // 判断是否为数值列(包括最后一行)
1238 const isNumeric = numericFields.includes(field?.field);
1239 const cellValue = ws[cellAddress].v; 1259 const cellValue = ws[cellAddress].v;
1240 1260
1241 // 数值列特殊处理(无论是否最后一行) 1261 ws[cellAddress].s = {
1242 if (isNumeric) { 1262 ...defaultStyle,
1243 ws[cellAddress].s = { 1263 alignment: alignment // 使用统一对齐方式
1244 ...defaultStyle, 1264 };
1245 alignment: {
1246 vertical: 'center',
1247 horizontal: 'right'
1248 },
1249 };
1250 1265
1251 // 确保数值被正确识别为数字类型 1266 // 确保数值被正确识别为数字类型
1252 if (cellValue !== undefined && cellValue !== "" && !isNaN(cellValue)) { 1267 if (isNumeric && cellValue !== undefined && cellValue !== "" && !isNaN(cellValue)) {
1253 ws[cellAddress].t = 'n'; // 数字类型 1268 ws[cellAddress].t = 'n'; // 数字类型
1254 ws[cellAddress].z = '#,##0.00'; // 数字格式 1269 ws[cellAddress].z = '#,##0.00'; // 数字格式
1255 }
1256 } else {
1257 // 文本列保持默认样式
1258 ws[cellAddress].s = defaultStyle;
1259 } 1270 }
1260 } 1271 }
1261 } 1272 }
...@@ -1373,7 +1384,7 @@ onUpdated(() => { ...@@ -1373,7 +1384,7 @@ onUpdated(() => {
1373 show-overflow-tooltip> 1384 show-overflow-tooltip>
1374 <template #default="scope"> 1385 <template #default="scope">
1375 <div class="input_cell" v-if="item.type == 'input'"> 1386 <div class="input_cell" v-if="item.type == 'input'">
1376 <el-input v-model.trim="scope.row[item.field]" placeholder="--" size="small" 1387 <el-input v-model.trim="scope.row[item.field]" :placeholder="scope.row.edit?'':'--'"
1377 :maxlength="item.maxlength ?? ''" @change="(val) => inputChange(val, scope, item.field)" 1388 :maxlength="item.maxlength ?? ''" @change="(val) => inputChange(val, scope, item.field)"
1378 @input="(val) => inputEventChange(val, scope, item.field)" 1389 @input="(val) => inputEventChange(val, scope, item.field)"
1379 :disabled="scope.row.edit ? false : true" clearable></el-input> 1390 :disabled="scope.row.edit ? false : true" clearable></el-input>
...@@ -1403,24 +1414,12 @@ onUpdated(() => { ...@@ -1403,24 +1414,12 @@ onUpdated(() => {
1403 </template> 1414 </template>
1404 </el-table> 1415 </el-table>
1405 <el-table id="entry-table" ref="entryTableRef" :data="transposedData" stripe border v-show="step == 1"> 1416 <el-table id="entry-table" ref="entryTableRef" :data="transposedData" stripe border v-show="step == 1">
1406 <!-- <el-table-column prop="title" label="项目" :width="140">
1407 <template v-slot="{ row }">
1408 <span>{{ setLabel(row.title) }}</span>
1409 </template>
1410 </el-table-column> -->
1411 <el-table-column v-for="(item, index) in bookHeaders" :key="index" :prop="item.field" 1417 <el-table-column v-for="(item, index) in bookHeaders" :key="index" :prop="item.field"
1412 :label="item.label" :width="item.width" :align="item.align"> 1418 :label="item.label" :width="item.width" :align="item.align">
1413 <template #default="scope"> 1419 <template #default="scope">
1414 <span v-if="item.field == 'title'">{{ setLabel(scope.row[item.field]) }}</span> 1420 <span v-if="item.field == 'title'">{{ setLabel(scope.row[item.field]) }}</span>
1415 <span v-else>{{ changeNum(scope.row[item.field], 2, true) }}</span> 1421 <span v-else>{{ changeNum(scope.row[item.field], 2, true) }}</span>
1416 </template> 1422 </template>
1417 <!-- <template v-slot:header>
1418 <span v-html="item.label"></span>
1419 </template>
1420 <template v-slot="{ row }">
1421 <span v-if="typeof row[item.field] == 'number'">{{ changeNum(row[item.field], 2, true) }}</span>
1422 <span v-else></span>
1423 </template> -->
1424 </el-table-column> 1423 </el-table-column>
1425 </el-table> 1424 </el-table>
1426 </div> 1425 </div>
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!