From 1e30eacbdc6845398b760b348d5eb31193ebdd48 Mon Sep 17 00:00:00 2001 From: yaojn Date: Wed, 25 Oct 2023 09:55:52 +0800 Subject: [PATCH 1/6] =?UTF-8?q?-=20[=E5=8A=9F=E8=83=BD]=E5=B7=A5=E5=8D=95?= =?UTF-8?q?=E8=BE=93=E5=85=A5=E8=A1=A8=E6=A0=BC=E6=94=AF=E6=8C=81=E5=AF=BC?= =?UTF-8?q?=E5=87=BA=E5=AF=BC=E5=85=A5execl=20=20-=20[=E5=85=B3=E8=81=94]#?= =?UTF-8?q?[998327821238272]=E5=B7=A5=E5=8D=95=E8=BE=93=E5=85=A5=E8=A1=A8?= =?UTF-8?q?=E6=A0=BC=E6=94=AF=E6=8C=81=E5=AF=BC=E5=87=BA=E5=AF=BC=E5=85=A5?= =?UTF-8?q?execl=20http://192.168.0.96:8090/demo/rdm.html#/story-detail/93?= =?UTF-8?q?9050947543040/939050947543042/998327821238272?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 2 + src/resources/assets/js/util.js | 2 +- .../form/component/formtableinputer/index.vue | 152 ++++++++++++++++++ 3 files changed, 155 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index cdf99259..5a8daf0e 100755 --- a/package.json +++ b/package.json @@ -40,6 +40,8 @@ "d3": "^5.14.2", "d3-graphviz": "^3.2.0", "docx-preview": "^0.1.13", + "exceljs": "^4.4.0", + "file-saver": "^2.0.5", "github-markdown-css": "^5.2.0", "handsontable": "^6.2.2", "highlight.js": "^11.8.0", diff --git a/src/resources/assets/js/util.js b/src/resources/assets/js/util.js index 01488e70..046e8338 100644 --- a/src/resources/assets/js/util.js +++ b/src/resources/assets/js/util.js @@ -104,7 +104,7 @@ const methods = { } else if (format == 'MMdd') { timestr = [month, day].join(''); } else if (format == 'yyyyMMddHHmmss') { - timestr = year + month + day + hours + minutes + seconds; + timestr = `${year}${month}${day}${hours}${minutes}${seconds}`; } return timestr; }, diff --git a/src/resources/plugins/TsSheet/form/component/formtableinputer/index.vue b/src/resources/plugins/TsSheet/form/component/formtableinputer/index.vue index a9f4c4a8..6c911ce9 100644 --- a/src/resources/plugins/TsSheet/form/component/formtableinputer/index.vue +++ b/src/resources/plugins/TsSheet/form/component/formtableinputer/index.vue @@ -7,6 +7,24 @@
+ 导出 Excel模板 + 导出 Excel + + 导入excel + { + if (item?.key && item?.title) { + theadList.push({ + header: item.title, + key: item.key, + width: 20 + }); + } + }); + _sheet1.columns = theadList; + let headerRow = _sheet1.getRow(1); // 获取第一行 + headerRow.eachCell((cell, colNum) => { + // 设置背景色 + cell.fill = { + type: 'pattern', + pattern: 'solid' + }; + // 设置字体 + cell.font = { + bold: true, + size: 12, + name: '微软雅黑', + color: {argb: '000'} + }; + // 设置对齐方式 + cell.alignment = {vertical: 'middle', horizontal: 'center', wrapText: false }; + }); + // 导出表格 + _workbook.xlsx.writeBuffer().then((buffer) => { + let _file = new Blob([buffer], { + type: 'application/octet-stream' + }); + FileSaver.saveAs(_file, '输入表格模板.xlsx'); + }); + }, + exportExcel() { + const _workbook = new ExcelJS.Workbook(); // 创建工作簿 + const _sheet1 = _workbook.addWorksheet('sheet1'); // 添加工作表 + let columnsList = []; + this.tableData.theadList.forEach((item) => { + if (item?.key && item?.title) { + columnsList.push({ + header: item.title, + key: item.key, + width: 20 + }); + } + }); + _sheet1.columns = columnsList; + columnsList.forEach(({ header, key }, columnIndex) => { + const headerCell = _sheet1.getCell(`${this.convertToExcelColumn(columnIndex + 1)}1`); + headerCell.name = key; // 将key作为每列的名称,作为导入进行数据匹配的字段 + }); + // 添加数据 + this.tableData.tbodyList.forEach((item) => { + if (item) { + _sheet1.addRow({...item}); + } + }); + // 数据验证 + // _sheet1.getCell('B2').dataValidation = { + // type: 'list', + // allowBlank: true, + // formulae: ['"软件一班,软件二班,软件三班"'] + // }; + + // 导出表格 + _workbook.xlsx.writeBuffer().then((buffer) => { + let _file = new Blob([buffer], { + type: 'application/octet-stream' + }); + FileSaver.saveAs(_file, `${this.$utils.getCurrenttime('yyyyMMddHHmmss')}输入表格.xlsx`); + }); + }, + convertToExcelColumn(number) { + let result = ''; + while (number > 0) { + const remainder = (number - 1) % 26; + result = String.fromCharCode(65 + remainder) + result; + number = Math.floor((number - 1) / 26); + } + return result; + }, + handleSuccess(res, file) { + console.log('上传成功', res, file); + }, + handleFormatError(file) { + this.$Notice.warning({ + title: '格式不正确', + desc: `格式${file.name}不正确,请选择正确的格式` + }); + }, + handleMaxSize(file) { + this.$Notice.warning({ + title: '超出文件大小限制', + desc: `${file.name}` + }); + }, + async handleBeforeUpload(file) { + const workbook = new ExcelJS.Workbook(); + let columnsList = []; + workbook.xlsx.load(file).then((workbook) => { + workbook?.eachSheet((sheet, id) => { + sheet?.eachRow({ includeEmpty: true }, (row, rowIndex) => { + // includeEmpty:true表示把空行的单元格内容也包含在内 + if (rowIndex == 1) { + // 首行表头的数据 + row.eachCell((cell) => { + if (cell?.name) { + columnsList.push(cell.name); + } + }); + } else { + console.log('第二行的数据', row.values, columnsList); + this.tableData.tbodyList.forEach((item, index) => { + item[columnsList[index]] = row.values[index]; + console.log('返回的值', row.values[index], index); + }); + console.log('改变值', this.tableData.tbodyList); + } + }); + }); + }); } }, filter: {}, -- Gitee From 401df976978e6588afa8a4afc69b7105d530d63b Mon Sep 17 00:00:00 2001 From: yaojn Date: Mon, 30 Oct 2023 18:26:00 +0800 Subject: [PATCH 2/6] =?UTF-8?q?-=20[=E4=BF=AE=E5=A4=8D]=E8=A1=A5=E5=85=85?= =?UTF-8?q?=E8=A7=A3=E6=9E=90excel=E5=86=85=E5=AE=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../form/component/formtableinputer/index.vue | 58 ++++++++++++------- 1 file changed, 38 insertions(+), 20 deletions(-) diff --git a/src/resources/plugins/TsSheet/form/component/formtableinputer/index.vue b/src/resources/plugins/TsSheet/form/component/formtableinputer/index.vue index 6c911ce9..d2a155bd 100644 --- a/src/resources/plugins/TsSheet/form/component/formtableinputer/index.vue +++ b/src/resources/plugins/TsSheet/form/component/formtableinputer/index.vue @@ -271,11 +271,14 @@ export default { let theadList = []; this.tableData.theadList.forEach((item) => { if (item?.key && item?.title) { - theadList.push({ - header: item.title, - key: item.key, - width: 20 - }); + if (item.key != 'number') { + // 序号是否需要显示 + theadList.push({ + header: item.title, + key: item.key, + width: 20 + }); + } } }); _sheet1.columns = theadList; @@ -310,18 +313,20 @@ export default { let columnsList = []; this.tableData.theadList.forEach((item) => { if (item?.key && item?.title) { - columnsList.push({ - header: item.title, - key: item.key, - width: 20 - }); + if (item.key != 'number') { + columnsList.push({ + header: item.title, + key: item.key, + width: 20 + }); + } } }); _sheet1.columns = columnsList; - columnsList.forEach(({ header, key }, columnIndex) => { - const headerCell = _sheet1.getCell(`${this.convertToExcelColumn(columnIndex + 1)}1`); - headerCell.name = key; // 将key作为每列的名称,作为导入进行数据匹配的字段 - }); + // columnsList.forEach(({ header, key }, columnIndex) => { + // const headerCell = _sheet1.getCell(`${this.convertToExcelColumn(columnIndex + 1)}1`); + // headerCell.name = key; // 将key作为每列的名称,作为导入进行数据匹配的字段 + // }); // 添加数据 this.tableData.tbodyList.forEach((item) => { if (item) { @@ -372,7 +377,7 @@ export default { let columnsList = []; workbook.xlsx.load(file).then((workbook) => { workbook?.eachSheet((sheet, id) => { - sheet?.eachRow({ includeEmpty: true }, (row, rowIndex) => { + sheet?.eachRow((row, rowIndex) => { // includeEmpty:true表示把空行的单元格内容也包含在内 if (rowIndex == 1) { // 首行表头的数据 @@ -382,12 +387,25 @@ export default { } }); } else { - console.log('第二行的数据', row.values, columnsList); - this.tableData.tbodyList.forEach((item, index) => { - item[columnsList[index]] = row.values[index]; - console.log('返回的值', row.values[index], index); + let rowValues = this.$utils.deepClone(row.values); + rowValues.splice(0, 1); + let rowValue = {}; + this.tableData.theadList.forEach((item, tIndex) => { + if (item.key != 'selection' && item.key != 'number') { + this.$set(rowValue, [item.key], rowValues[tIndex - 2]); + } + }); + console.log('rowValues', rowValues, rowIndex); + console.log('rowValue', rowValue); + this.tableData.tbodyList?.forEach((item, tIndex) => { + if (item && (tIndex == (rowIndex - 2))) { + item = Object.assign(item, rowValue); + console.log('1', tIndex, item); + } else { + console.log('2', tIndex, item); + this.tableData.tbodyList.push({...Object.assign(item, rowValue)}); + } }); - console.log('改变值', this.tableData.tbodyList); } }); }); -- Gitee From 792fa878347c40de4380ec3ed50120043bf24ee9 Mon Sep 17 00:00:00 2001 From: yaojn Date: Tue, 31 Oct 2023 18:57:04 +0800 Subject: [PATCH 3/6] =?UTF-8?q?-=20[=E5=8A=9F=E8=83=BD]=E5=A4=84=E7=90=86?= =?UTF-8?q?=E6=97=A5=E6=9C=9F/=E6=97=B6=E9=97=B4=E5=AF=BC=E5=85=A5?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E6=98=AFDate=E7=9A=84=E9=97=AE=E9=A2=98?= =?UTF-8?q?=EF=BC=8C=E4=BB=A5=E5=8F=8A=E6=95=B0=E6=8D=AE=E6=9C=89=E6=95=88?= =?UTF-8?q?=E6=80=A7=E4=B8=8B=E6=8B=89=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../form/component/formtableinputer/index.vue | 111 ++++++++++++------ 1 file changed, 72 insertions(+), 39 deletions(-) diff --git a/src/resources/plugins/TsSheet/form/component/formtableinputer/index.vue b/src/resources/plugins/TsSheet/form/component/formtableinputer/index.vue index d2a155bd..979a3a81 100644 --- a/src/resources/plugins/TsSheet/form/component/formtableinputer/index.vue +++ b/src/resources/plugins/TsSheet/form/component/formtableinputer/index.vue @@ -13,7 +13,6 @@ ref="upload" :show-upload-list="false" :default-file-list="[]" - :on-success="handleSuccess" :format="['xlsx']" :max-size="2048" :on-format-error="handleFormatError" @@ -308,37 +307,48 @@ export default { }); }, exportExcel() { + // 导出excel带表格数据 const _workbook = new ExcelJS.Workbook(); // 创建工作簿 const _sheet1 = _workbook.addWorksheet('sheet1'); // 添加工作表 let columnsList = []; + let theadUuidList = []; // 获取所有表头的uuid列表 this.tableData.theadList.forEach((item) => { if (item?.key && item?.title) { if (item.key != 'number') { columnsList.push({ header: item.title, key: item.key, - width: 20 - }); + style: this.handleCellType(item.key) // 单元格格式为文本类型,解决日期和时间导入时类型是Date日期的类型 + }); + theadUuidList.push(item.key); } } }); _sheet1.columns = columnsList; - // columnsList.forEach(({ header, key }, columnIndex) => { - // const headerCell = _sheet1.getCell(`${this.convertToExcelColumn(columnIndex + 1)}1`); - // headerCell.name = key; // 将key作为每列的名称,作为导入进行数据匹配的字段 - // }); - // 添加数据 this.tableData.tbodyList.forEach((item) => { + // 添加数据 if (item) { _sheet1.addRow({...item}); } }); // 数据验证 - // _sheet1.getCell('B2').dataValidation = { - // type: 'list', - // allowBlank: true, - // formulae: ['"软件一班,软件二班,软件三班"'] - // }; + let selectCpmponentList = ['formselect', 'formradio', 'formcheckbox']; // 数据有效性列表 + const startRow = 2; + const endRow = 10; + this.extraList.forEach((item, index) => { + if (theadUuidList.includes(item.uuid) && selectCpmponentList.includes(item.handler)) { + // 遍历每一行,设置数据有效性 + for (let row = startRow; row <= endRow; row++) { + const worksheetRow = _sheet1.getRow(row); + const cell = worksheetRow.getCell(`${this.convertToExcelColumn(index + 1)}`); + cell.dataValidation = { + type: 'list', + allowBlank: false, + formulae: this.handleFormulae(item.config) + }; + } + } + }); // 导出表格 _workbook.xlsx.writeBuffer().then((buffer) => { @@ -348,7 +358,17 @@ export default { FileSaver.saveAs(_file, `${this.$utils.getCurrenttime('yyyyMMddHHmmss')}输入表格.xlsx`); }); }, + handleCellType(uuid) { + // 设置单元格类型 + let componentsList = ['formdate', 'formtime']; + const foundItem = this.extraList.find((item) => { + return item.uuid && item.uuid === uuid && componentsList.includes(item.handler); + }); + const formatObj = foundItem ? { numFmt: '@' } : {}; + return formatObj; + }, convertToExcelColumn(number) { + // 将数字转化成A-Z的值 let result = ''; while (number > 0) { const remainder = (number - 1) % 26; @@ -357,8 +377,20 @@ export default { } return result; }, - handleSuccess(res, file) { - console.log('上传成功', res, file); + handleFormulae(config) { + // 处理数据有效性下拉 + if (config?.dataSource !== 'static') { + return []; // 不是静态数据源,返回空数组 + } + + const resultArray = [ + `"${config.dataList + .filter(item => item?.value) + .map(item => `${item.value}/${item.text}`) + .join(',')}"` + ]; + + return resultArray; }, handleFormatError(file) { this.$Notice.warning({ @@ -374,42 +406,43 @@ export default { }, async handleBeforeUpload(file) { const workbook = new ExcelJS.Workbook(); - let columnsList = []; workbook.xlsx.load(file).then((workbook) => { workbook?.eachSheet((sheet, id) => { sheet?.eachRow((row, rowIndex) => { - // includeEmpty:true表示把空行的单元格内容也包含在内 - if (rowIndex == 1) { - // 首行表头的数据 - row.eachCell((cell) => { - if (cell?.name) { - columnsList.push(cell.name); - } - }); - } else { - let rowValues = this.$utils.deepClone(row.values); - rowValues.splice(0, 1); + if (rowIndex != 1) { let rowValue = {}; + let rowValuesList = this.$utils.deepClone(row.values); + rowValuesList.splice(0, 1); // 删除excel第一列的序号 this.tableData.theadList.forEach((item, tIndex) => { if (item.key != 'selection' && item.key != 'number') { - this.$set(rowValue, [item.key], rowValues[tIndex - 2]); - } - }); - console.log('rowValues', rowValues, rowIndex); - console.log('rowValue', rowValue); - this.tableData.tbodyList?.forEach((item, tIndex) => { - if (item && (tIndex == (rowIndex - 2))) { - item = Object.assign(item, rowValue); - console.log('1', tIndex, item); - } else { - console.log('2', tIndex, item); - this.tableData.tbodyList.push({...Object.assign(item, rowValue)}); + this.$set(rowValue, [item.key], this.byComponentTypeSetValue(rowValuesList[tIndex - 2])); } }); + let item = {...(this.tableData.tbodyList[rowIndex - 2] || {}), ...rowValue}; + if (!this.$utils.isEmpty(this.tableData.tbodyList[rowIndex - 2])) { + // 不为空时,修改数组对象里面的值 + this.tableData.tbodyList.splice(rowIndex - 2, 1, item); + } else { + // 空数组时,新增一条新的数据 + this.tableData.tbodyList.push(item); + } } }); }); }); + }, + byComponentTypeSetValue(item) { + // 根据组件的类型,设置回显值 + if (typeof item === 'string') { + try { + const parsedArray = JSON.parse(item); + return parsedArray; + } catch (error) { + return item; + } + } else { + return item; + } } }, filter: {}, -- Gitee From ba65b805bc7928bb947bc6743268fa08b19a4bc7 Mon Sep 17 00:00:00 2001 From: yaojn Date: Wed, 1 Nov 2023 18:45:53 +0800 Subject: [PATCH 4/6] =?UTF-8?q?-=20[=E5=8A=9F=E8=83=BD]=E8=A1=A5=E5=85=85?= =?UTF-8?q?=E7=9F=A9=E9=98=B5=E6=95=B0=E6=8D=AE=E4=B8=8B=E6=8B=89=E5=AF=BC?= =?UTF-8?q?=E5=85=A5=E5=80=BC=E5=9B=9E=E6=98=BE=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../form/component/formtableinputer/index.vue | 102 +++++++++++++----- 1 file changed, 76 insertions(+), 26 deletions(-) diff --git a/src/resources/plugins/TsSheet/form/component/formtableinputer/index.vue b/src/resources/plugins/TsSheet/form/component/formtableinputer/index.vue index 979a3a81..2efc1ca3 100644 --- a/src/resources/plugins/TsSheet/form/component/formtableinputer/index.vue +++ b/src/resources/plugins/TsSheet/form/component/formtableinputer/index.vue @@ -306,7 +306,7 @@ export default { FileSaver.saveAs(_file, '输入表格模板.xlsx'); }); }, - exportExcel() { + async exportExcel() { // 导出excel带表格数据 const _workbook = new ExcelJS.Workbook(); // 创建工作簿 const _sheet1 = _workbook.addWorksheet('sheet1'); // 添加工作表 @@ -318,6 +318,7 @@ export default { columnsList.push({ header: item.title, key: item.key, + width: 20, style: this.handleCellType(item.key) // 单元格格式为文本类型,解决日期和时间导入时类型是Date日期的类型 }); theadUuidList.push(item.key); @@ -325,9 +326,24 @@ export default { } }); _sheet1.columns = columnsList; - this.tableData.tbodyList.forEach((item) => { + let tbodyList = this.$utils.deepClone(this.tableData.tbodyList); + tbodyList.forEach((item) => { // 添加数据 if (item) { + for (let key in item) { + if (key != 'uuid' && key != '_selected') { + let selectedItem = this.extraList.find((extraItem) => extraItem.uuid == key); + let {config = {}, handler = ''} = selectedItem || {}; + let {dataSource = '', isMultiple = false} = config; + if (dataSource == 'matrix' && isMultiple) { + // 矩阵数据源并且是多选,需要处理值去掉&=& + this.$set(item, [key], this.handleSpecialValue(item[key])); + } else if (dataSource == 'static' && (isMultiple || handler == 'formcheckbox')) { + // 静态数据源并且是多选 + this.$set(item, [key], item[key].join(',')); + } + } + } _sheet1.addRow({...item}); } }); @@ -335,27 +351,28 @@ export default { let selectCpmponentList = ['formselect', 'formradio', 'formcheckbox']; // 数据有效性列表 const startRow = 2; const endRow = 10; - this.extraList.forEach((item, index) => { + for (let [index, item] of this.extraList.entries()) { if (theadUuidList.includes(item.uuid) && selectCpmponentList.includes(item.handler)) { // 遍历每一行,设置数据有效性 + let formulaeList = await this.handleFormulae(item.config); for (let row = startRow; row <= endRow; row++) { const worksheetRow = _sheet1.getRow(row); const cell = worksheetRow.getCell(`${this.convertToExcelColumn(index + 1)}`); cell.dataValidation = { type: 'list', allowBlank: false, - formulae: this.handleFormulae(item.config) + formulae: formulaeList }; } } - }); + } // 导出表格 _workbook.xlsx.writeBuffer().then((buffer) => { let _file = new Blob([buffer], { type: 'application/octet-stream' }); - FileSaver.saveAs(_file, `${this.$utils.getCurrenttime('yyyyMMddHHmmss')}输入表格.xlsx`); + FileSaver.saveAs(_file, `${this.formItem?.label || ''}_${this.$utils.getCurrenttime('yyyyMMddHHmmss')}.xlsx`); }); }, handleCellType(uuid) { @@ -377,20 +394,40 @@ export default { } return result; }, - handleFormulae(config) { + async handleFormulae(config) { // 处理数据有效性下拉 - if (config?.dataSource !== 'static') { - return []; // 不是静态数据源,返回空数组 + let {dataSource = '', matrixUuid = '', mapping = {}, dataList = [] } = config || {}; + if (dataSource === 'matrix') { + let param = { + matrixUuid: matrixUuid, + valueField: mapping.value, + textField: mapping.text + }; + return await this.$api.framework.matrix.getMatrixDataForSelect(param).then(res => { + if (res.Status == 'OK') { + return [`"${res.Return?.dataList?.filter((item) => this.handleSpecialValue(item.value)).map((item) => this.handleSpecialValue(item.value)).join(',')}"`]; + } + }); + } else { + const resultArray = [ + `"${dataList + .filter(item => item?.value) + .map(item => item.value) + .join(',')}"` + ]; + return resultArray; } + }, + handleSpecialValue(value) { + let valueList = []; - const resultArray = [ - `"${config.dataList - .filter(item => item?.value) - .map(item => `${item.value}/${item.text}`) - .join(',')}"` - ]; + if (typeof value == 'string') { + return value?.split('&=&')?.[0] || value; + } else if (Array.isArray(value)) { + valueList = value.map((item) => item?.split('&=&')?.[0] || item).filter(Boolean); + } - return resultArray; + return valueList.join(','); }, handleFormatError(file) { this.$Notice.warning({ @@ -415,7 +452,7 @@ export default { rowValuesList.splice(0, 1); // 删除excel第一列的序号 this.tableData.theadList.forEach((item, tIndex) => { if (item.key != 'selection' && item.key != 'number') { - this.$set(rowValue, [item.key], this.byComponentTypeSetValue(rowValuesList[tIndex - 2])); + this.$set(rowValue, [item.key], this.byComponentTypeSetValue(item.key, rowValuesList[tIndex - 2])); } }); let item = {...(this.tableData.tbodyList[rowIndex - 2] || {}), ...rowValue}; @@ -431,18 +468,31 @@ export default { }); }); }, - byComponentTypeSetValue(item) { + byComponentTypeSetValue(uuid, item) { // 根据组件的类型,设置回显值 - if (typeof item === 'string') { - try { - const parsedArray = JSON.parse(item); - return parsedArray; - } catch (error) { - return item; + console.log(item); + let resultValue; + let selectedItem = this.extraList.find((extraItem) => extraItem.uuid == uuid); + let {config = {}, handler = ''} = selectedItem || {}; + if (item) { + let {dataSource = '', isMultiple = false} = config || {}; + if (dataSource === 'matrix' && isMultiple) { + // 矩阵 + resultValue = []; + let valueList = item.split(','); + valueList.forEach((valueItem) => { + if (valueItem) { + resultValue.push(`${valueItem}&=&${valueItem}`); + } + }); + } else if (dataSource == 'static' && (isMultiple || (handler == 'formcheckbox'))) { + resultValue = []; + resultValue.push(item); + } else { + resultValue = item; } - } else { - return item; } + return resultValue; } }, filter: {}, -- Gitee From 2eee3edc8a10fa47ac292d500e645c12fbe527c9 Mon Sep 17 00:00:00 2001 From: yaojn Date: Thu, 2 Nov 2023 17:12:14 +0800 Subject: [PATCH 5/6] =?UTF-8?q?-=20[=E4=BF=AE=E5=A4=8D]=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E5=AF=BC=E5=87=BA=E6=A8=A1=E6=9D=BF=E6=A0=B7=E5=BC=8F=E8=A1=A5?= =?UTF-8?q?=E5=85=85=E5=A4=9A=E8=AF=AD=E8=A8=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/resources/assets/languages/term/en.json | 5 +- src/resources/assets/languages/term/zh.json | 5 +- .../form/component/formtableinputer/index.vue | 57 +++++++++++-------- 3 files changed, 40 insertions(+), 27 deletions(-) diff --git a/src/resources/assets/languages/term/en.json b/src/resources/assets/languages/term/en.json index 74c1834d..6288d116 100644 --- a/src/resources/assets/languages/term/en.json +++ b/src/resources/assets/languages/term/en.json @@ -1138,7 +1138,10 @@ "heartbeattime": "Last heartbeat time", "heartbeatrate": "heart rate ", "heartbeatthreshold": "Heartbeat threshold", - "versionlog": "Version Log" + "versionlog": "Version Log", + "exporttable": "Export Table", + "importtable": "Import Table", + "excelinputtemplate": "Table Input Template" }, "knowledge": { "document": "Document", diff --git a/src/resources/assets/languages/term/zh.json b/src/resources/assets/languages/term/zh.json index 9572d938..c9398b4b 100644 --- a/src/resources/assets/languages/term/zh.json +++ b/src/resources/assets/languages/term/zh.json @@ -1137,7 +1137,10 @@ "heartbeattime": "最近一次心跳时间", "heartbeatrate": "心跳频率", "heartbeatthreshold": "心跳阈值", - "versionlog": "版本日志" + "versionlog": "版本日志", + "exporttable": "导出表格", + "importtable": "导入表格", + "excelinputtemplate": "表格输入模板" }, "knowledge": { "document": "文档", diff --git a/src/resources/plugins/TsSheet/form/component/formtableinputer/index.vue b/src/resources/plugins/TsSheet/form/component/formtableinputer/index.vue index 2efc1ca3..8b01f821 100644 --- a/src/resources/plugins/TsSheet/form/component/formtableinputer/index.vue +++ b/src/resources/plugins/TsSheet/form/component/formtableinputer/index.vue @@ -7,8 +7,8 @@
- 导出 Excel模板 - 导出 Excel + {{ $t('term.pbc.exporttemplate') }} + {{ $t('term.framework.exporttable') }} - 导入excel + {{ $t('term.framework.importtable') }} { @@ -283,27 +282,24 @@ export default { _sheet1.columns = theadList; let headerRow = _sheet1.getRow(1); // 获取第一行 headerRow.eachCell((cell, colNum) => { - // 设置背景色 - cell.fill = { - type: 'pattern', - pattern: 'solid' - }; - // 设置字体 cell.font = { bold: true, size: 12, name: '微软雅黑', color: {argb: '000'} }; - // 设置对齐方式 - cell.alignment = {vertical: 'middle', horizontal: 'center', wrapText: false }; + cell.alignment = { + horizontal: 'center', + vertical: 'middle', + wrapText: true // 单元格自动换行 + }; }); // 导出表格 _workbook.xlsx.writeBuffer().then((buffer) => { let _file = new Blob([buffer], { type: 'application/octet-stream' }); - FileSaver.saveAs(_file, '输入表格模板.xlsx'); + FileSaver.saveAs(_file, `${this.$t('term.framework.excelinputtemplate')}.xlsx`); }); }, async exportExcel() { @@ -470,7 +466,6 @@ export default { }, byComponentTypeSetValue(uuid, item) { // 根据组件的类型,设置回显值 - console.log(item); let resultValue; let selectedItem = this.extraList.find((extraItem) => extraItem.uuid == uuid); let {config = {}, handler = ''} = selectedItem || {}; @@ -479,12 +474,17 @@ export default { if (dataSource === 'matrix' && isMultiple) { // 矩阵 resultValue = []; - let valueList = item.split(','); - valueList.forEach((valueItem) => { - if (valueItem) { - resultValue.push(`${valueItem}&=&${valueItem}`); - } - }); + let valueList = []; + if (typeof item == 'string') { + valueList = item.split(','); + valueList.forEach((valueItem) => { + if (valueItem) { + resultValue.push(`${valueItem}&=&${valueItem}`); + } + }); + } else { + resultValue.push(`${item}&=&${item}`); + } } else if (dataSource == 'static' && (isMultiple || (handler == 'formcheckbox'))) { resultValue = []; resultValue.push(item); @@ -583,4 +583,11 @@ export default { } }; - + -- Gitee From 6d884157860fc6cb0c5102d2ec5f0896fdd64a49 Mon Sep 17 00:00:00 2001 From: yaojn Date: Fri, 3 Nov 2023 18:54:32 +0800 Subject: [PATCH 6/6] =?UTF-8?q?-=20[=E5=8A=9F=E8=83=BD]=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E5=AF=BC=E5=85=A5excel=E8=A1=A8=E6=A0=BC=EF=BC=8C=E5=89=94?= =?UTF-8?q?=E9=99=A4=E5=9B=9E=E6=98=BE=E5=A4=B1=E8=B4=A5=E9=BB=98=E8=AE=A4?= =?UTF-8?q?=E5=80=BC=20-=20[=E5=8A=9F=E8=83=BD]=E8=A1=A5=E5=85=85=E4=B8=8B?= =?UTF-8?q?=E8=BD=BD=E4=BA=A4=E4=BA=92=E6=95=88=E6=9E=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/resources/mixins/formMixins.js | 7 +- .../plugins/TsForm/TsFormCheckbox.vue | 16 +++ src/resources/plugins/TsForm/TsFormRadio.vue | 49 +++++--- src/resources/plugins/TsForm/TsFormSelect.vue | 23 +++- src/resources/plugins/TsSheet/form-item.vue | 6 + .../plugins/TsSheet/form/component/base.vue | 7 +- .../TsSheet/form/component/formcheckbox.vue | 1 + .../TsSheet/form/component/formradio.vue | 1 + .../TsSheet/form/component/formselect.vue | 1 + .../form/component/formtableinputer/index.vue | 118 ++++++++++++++---- 10 files changed, 189 insertions(+), 40 deletions(-) diff --git a/src/resources/mixins/formMixins.js b/src/resources/mixins/formMixins.js index f0d75d7a..2cf753ae 100644 --- a/src/resources/mixins/formMixins.js +++ b/src/resources/mixins/formMixins.js @@ -40,7 +40,12 @@ export default { desc: String, descType: String, //描述用alert组件进行包裹 info、success、warning、error clearable: Boolean, - readonlyTextIsHighlight: { type: Boolean, default: false } // 只读模式下,是否需要高亮显示值 + readonlyTextIsHighlight: { type: Boolean, default: false }, // 只读模式下,是否需要高亮显示值 + isClearEchoFailedDefaultValue: { + // 是否清空回显失败默认值 + type: Boolean, + default: false + } }, methods: { dispatch(componentName, eventName, params) { diff --git a/src/resources/plugins/TsForm/TsFormCheckbox.vue b/src/resources/plugins/TsForm/TsFormCheckbox.vue index a45c8199..674f592e 100755 --- a/src/resources/plugins/TsForm/TsFormCheckbox.vue +++ b/src/resources/plugins/TsForm/TsFormCheckbox.vue @@ -155,6 +155,7 @@ export default { } }); } else if (_this.nodeList && _this.nodeList.length) { + this.handleEchoFailedDefaultValue(); // if (!_this.value.length) { // //如果没有值的 // let selectedItem = _this.nodeList.filter(n => { @@ -167,6 +168,20 @@ export default { // } } }, + handleEchoFailedDefaultValue() { + // 处理回显失败默认值,回显失败清空默认值 + let selectedList = []; + let valueList = this.currentValue instanceof Array ? this.currentValue : [this.currentValue]; + valueList.forEach((item, index) => { + if (item && !this.nodeList.find((n) => n[this.valueName] == item)) { + selectedList.push(item[this.valueName]); + this.currentValue.splice(index, 1); + } + }); + if (!this.$utils.isEmpty(selectedList) && this.isClearEchoFailedDefaultValue) { + this.onChangeValue(); + } + }, onChangeValue(val, item) { let isSame = JSON.stringify(this.value) == JSON.stringify(this.currentValue); let value = JSON.parse(JSON.stringify(this.currentValue)); @@ -222,6 +237,7 @@ export default { } }, 100); } + this.handleEchoFailedDefaultValue(); } }, computed: { diff --git a/src/resources/plugins/TsForm/TsFormRadio.vue b/src/resources/plugins/TsForm/TsFormRadio.vue index 93cb6529..4584d58c 100755 --- a/src/resources/plugins/TsForm/TsFormRadio.vue +++ b/src/resources/plugins/TsForm/TsFormRadio.vue @@ -155,6 +155,7 @@ export default { _this.nodeList = _this.dealDataByUrl(_this.nodeList); } _this.setSelectList(); + _this.handleEchoFailedDefaultValue(); } }); } else if (_this.nodeList && _this.nodeList.length) { @@ -168,33 +169,48 @@ export default { _this.onChangeValue(); } } + + this.handleEchoFailedDefaultValue(); + } + }, + handleEchoFailedDefaultValue() { + // 处理回显失败默认值,回显失败清空默认值 + let selectedList = []; + if (this.currentValue) { + let selectedItem = this.nodeList.find((item) => item[this.valueName] == this.currentValue); + if (!selectedItem) { + this.currentValue = null; + } + } + if (!this.$utils.isEmpty(selectedList) && this.isClearEchoFailedDefaultValue) { + this.onChangeValue(); } }, onChangeValue() { - let _this = this; - let isSame = _this.value === _this.currentValue; + let isSame = this.value == this.currentValue; + let value = this.currentValue; //20210129_zqp_新增支持on-change方法第二个参数获取选中的选项的完整数据 let selectedItem = []; - if (this.nodeList && this.nodeList.length && _this.currentValue) { + if (this.nodeList && this.nodeList.length && value) { selectedItem = this.nodeList.find(n => { - return n[_this.valueName] === _this.currentValue; + return n[this.valueName] === value; }); } - _this.$emit('update:value', _this.currentValue); - _this.$emit('change', _this.currentValue, selectedItem || null); + this.$emit('update:value', value); + this.$emit('change', value, selectedItem || null); if (!(!this.isChangeWrite && isSame)) { //改变值时出发on-change事件 - _this.$emit('on-change', _this.currentValue, selectedItem || null); + this.$emit('on-change', value, selectedItem || null); } if (!isSame) { - typeof _this.onChange == 'function' && _this.onChange(_this.currentValue, selectedItem || null); - if (_this.currentValidList.length > 0) { - _this.valid(_this.currentValue); + typeof this.onChange == 'function' && this.onChange(value, selectedItem || null); + if (this.currentValidList.length > 0) { + this.valid(value); } } else { - _this.validMesage = ''; + this.validMesage = ''; } - this.setSelectList(selectedItem[_this.textName] || ''); + this.setSelectList(selectedItem[this.textName] || ''); }, setSelectList(selectedLabel) { let _this = this; @@ -233,11 +249,11 @@ export default { }, watch: { value(newValue, oldValue) { - let _this = this; - if (newValue != _this.currentValue) { - _this.currentValue = newValue; - _this.validMesage = ''; + if (newValue != this.currentValue) { + this.currentValue = newValue; + this.validMesage = ''; this.setSelectList(); + this.handleEchoFailedDefaultValue(); } }, dataList: { @@ -245,6 +261,7 @@ export default { if (!this.url) { this.$set(this, 'nodeList', newValue); this.setSelectList(); + this.handleEchoFailedDefaultValue(); } }, deep: true diff --git a/src/resources/plugins/TsForm/TsFormSelect.vue b/src/resources/plugins/TsForm/TsFormSelect.vue index ccc4731e..5e6222ab 100755 --- a/src/resources/plugins/TsForm/TsFormSelect.vue +++ b/src/resources/plugins/TsForm/TsFormSelect.vue @@ -534,7 +534,7 @@ export default { }; }, beforeCreate() {}, - created: function() { + created() { this.initDataListByUrl(false); }, mounted() {}, @@ -710,6 +710,7 @@ export default { this.setDefaultValue(); this.initValueByNodeList(); this.isSingel = !!(this.isSquare && this.currentSearch); // 解决文本占位符显示不出来问题 + this.handleEchoFailedDefaultValue(); } }, initValueByNodeList() { @@ -898,8 +899,10 @@ export default { }); } this.selectedList = selectedList.length > 1 ? list : selectedList; + this.handleEchoFailedDefaultValue(); } else { _this.selectedList = []; + this.handleEchoFailedDefaultValue(); } if (!_this.multiple) { @@ -914,6 +917,24 @@ export default { } }); }, + handleEchoFailedDefaultValue() { + // 处理回显失败默认值,回显失败清空默认值 + let selectedList = []; + let valueList = this.multiple ? this.currentValue : this.currentValue instanceof Array ? this.currentValue : [this.currentValue]; + valueList.forEach((item, index) => { + if (item && !this.selectedList.find((n) => n[this.valueName] == item)) { + selectedList.push(item[this.valueName]); + if (this.currentValue instanceof Array) { + this.currentValue.splice(index, 1); + } else if (this.currentValue) { + this.currentValue = null; + } + } + }); + if (!this.$utils.isEmpty(selectedList) && this.isClearEchoFailedDefaultValue) { + this.onChangeValue(); + } + }, dynamicSearch(query, isFirst) { //query:搜索的关键字,isFirst 是否第一次初始化下拉值,主要为了必填时只有一个下拉值时默认填充 let _this = this; diff --git a/src/resources/plugins/TsSheet/form-item.vue b/src/resources/plugins/TsSheet/form-item.vue index c1e45663..b5f0dd81 100644 --- a/src/resources/plugins/TsSheet/form-item.vue +++ b/src/resources/plugins/TsSheet/form-item.vue @@ -62,6 +62,7 @@ :required="(mode != 'defaultvalue'?formItem.config && formItem.config.isRequired:false)" :formData="formData" :readonlyTextIsHighlight="readonlyTextIsHighlight" + :isClearEchoFailedDefaultValue="isClearEchoFailedDefaultValue" @setValue="setValue" @resize="$emit('resize')" @select="selectFormItem" @@ -119,6 +120,11 @@ export default { default: function() { return {}; } + }, + isClearEchoFailedDefaultValue: { + // 默认值对应不上下列列表时,是否需要清空默认值 + type: Boolean, + default: false } }, data() { diff --git a/src/resources/plugins/TsSheet/form/component/base.vue b/src/resources/plugins/TsSheet/form/component/base.vue index 14e1436a..eec41998 100644 --- a/src/resources/plugins/TsSheet/form/component/base.vue +++ b/src/resources/plugins/TsSheet/form/component/base.vue @@ -10,7 +10,12 @@ export default { disabled: { type: Boolean, default: false }, required: { type: Boolean, default: false }, formData: Object, - readonlyTextIsHighlight: {type: Boolean, default: false} // 只读模式下,是否需要高亮显示值 + readonlyTextIsHighlight: {type: Boolean, default: false}, // 只读模式下,是否需要高亮显示值 + isClearEchoFailedDefaultValue: { + // 是否清空回显失败默认值 + type: Boolean, + default: false + } }, data() { return { diff --git a/src/resources/plugins/TsSheet/form/component/formcheckbox.vue b/src/resources/plugins/TsSheet/form/component/formcheckbox.vue index 085cc4c8..cb483415 100644 --- a/src/resources/plugins/TsSheet/form/component/formcheckbox.vue +++ b/src/resources/plugins/TsSheet/form/component/formcheckbox.vue @@ -9,6 +9,7 @@ :vertical="config.direction === 'vertical'" :validateList="validateList" :readonlyTextIsHighlight="readonlyTextIsHighlight" + :isClearEchoFailedDefaultValue="isClearEchoFailedDefaultValue" @change=" val => { setValue(val); diff --git a/src/resources/plugins/TsSheet/form/component/formradio.vue b/src/resources/plugins/TsSheet/form/component/formradio.vue index 3dbb1f18..5e48b56b 100644 --- a/src/resources/plugins/TsSheet/form/component/formradio.vue +++ b/src/resources/plugins/TsSheet/form/component/formradio.vue @@ -10,6 +10,7 @@ :validateList="validateList" :allowToggle="true" :readonlyTextIsHighlight="readonlyTextIsHighlight" + :isClearEchoFailedDefaultValue="isClearEchoFailedDefaultValue" @change=" val => { setValue(val); diff --git a/src/resources/plugins/TsSheet/form/component/formselect.vue b/src/resources/plugins/TsSheet/form/component/formselect.vue index aa19e5d0..1546141d 100644 --- a/src/resources/plugins/TsSheet/form/component/formselect.vue +++ b/src/resources/plugins/TsSheet/form/component/formselect.vue @@ -9,6 +9,7 @@ :value="actualValue" :validateList="validateList" :readonlyTextIsHighlight="readonlyTextIsHighlight" + :isClearEchoFailedDefaultValue="isClearEchoFailedDefaultValue" border="border" search @change=" diff --git a/src/resources/plugins/TsSheet/form/component/formtableinputer/index.vue b/src/resources/plugins/TsSheet/form/component/formtableinputer/index.vue index 8b01f821..ab02664e 100644 --- a/src/resources/plugins/TsSheet/form/component/formtableinputer/index.vue +++ b/src/resources/plugins/TsSheet/form/component/formtableinputer/index.vue @@ -7,14 +7,31 @@
- {{ $t('term.pbc.exporttemplate') }} - {{ $t('term.framework.exporttable') }} + {{ $t('term.pbc.exporttemplate') }} + + + {{ $t('term.pbc.exporttemplate') }} + + {{ $t('term.framework.exporttable') }} + + + {{ $t('term.framework.exporttable') }} + + @@ -91,7 +109,10 @@ export default { isTableSelectorDialogShow: false, selectedIndexList: [], tableData: { theadList: [], tbodyList: [] }, - rowFormItem: {} //保存每行的定义数据,避免每次都deepClone新数据,导致reaction失效 + rowFormItem: {}, //保存每行的定义数据,避免每次都deepClone新数据,导致reaction失效 + maxSize: 1024 * 10, + isShowExportExcelTemplate: true, + isShowExportExcel: true }; }, beforeCreate() {}, @@ -261,12 +282,14 @@ export default { let beforeVal = this.tableData.tbodyList.splice(event.oldIndex, 1)[0]; this.tableData.tbodyList.splice(event.newIndex, 0, beforeVal); }, - exportExcelTemplate() { + async exportExcelTemplate() { // 导出excel模板 + this.isShowExportExcelTemplate = false; const _workbook = new ExcelJS.Workbook(); const _sheet1 = _workbook.addWorksheet('sheet1'); // 添加工作表 // 设置表头 let theadList = []; + let theadUuidList = []; this.tableData.theadList.forEach((item) => { if (item?.key && item?.title) { if (item.key != 'number') { @@ -274,8 +297,10 @@ export default { theadList.push({ header: item.title, key: item.key, - width: 20 + width: 20, + style: this.handleCellType(item.key) }); + theadUuidList.push(item.key); } } }); @@ -294,16 +319,45 @@ export default { wrapText: true // 单元格自动换行 }; }); + // 数据验证 + let selectCpmponentList = ['formselect', 'formradio', 'formcheckbox']; // 数据有效性列表 + const startRow = 2; + const endRow = 10; + for (let [index, item] of this.extraList.entries()) { + if (theadUuidList.includes(item.uuid) && selectCpmponentList.includes(item.handler)) { + // 遍历每一行,设置数据有效性 + let formulaeList = await this.handleFormulae(item.config); + for (let row = startRow; row <= endRow; row++) { + const worksheetRow = _sheet1.getRow(row); + const cell = worksheetRow.getCell(`${this.convertToExcelColumn(index + 1)}`); + cell.dataValidation = { + type: 'list', + allowBlank: false, + formulae: formulaeList + }; + } + } + } // 导出表格 _workbook.xlsx.writeBuffer().then((buffer) => { let _file = new Blob([buffer], { type: 'application/octet-stream' }); - FileSaver.saveAs(_file, `${this.$t('term.framework.excelinputtemplate')}.xlsx`); + new Promise((resolve, reject) => { + try { + FileSaver.saveAs(_file, `${this.$t('term.framework.excelinputtemplate')}.xlsx`); + resolve(this.$t('page.success')); + } catch (error) { + reject(this.$t('page.fail')); + } + }).finally((message) => { + this.isShowExportExcelTemplate = true; + }); }); }, async exportExcel() { // 导出excel带表格数据 + this.isShowExportExcel = false; const _workbook = new ExcelJS.Workbook(); // 创建工作簿 const _sheet1 = _workbook.addWorksheet('sheet1'); // 添加工作表 let columnsList = []; @@ -322,6 +376,20 @@ export default { } }); _sheet1.columns = columnsList; + let headerRow = _sheet1.getRow(1); // 获取第一行 + headerRow.eachCell((cell, colNum) => { + cell.font = { + bold: true, + size: 12, + name: '微软雅黑', + color: {argb: '000'} + }; + cell.alignment = { + horizontal: 'center', + vertical: 'middle', + wrapText: true // 单元格自动换行 + }; + }); let tbodyList = this.$utils.deepClone(this.tableData.tbodyList); tbodyList.forEach((item) => { // 添加数据 @@ -368,7 +436,17 @@ export default { let _file = new Blob([buffer], { type: 'application/octet-stream' }); - FileSaver.saveAs(_file, `${this.formItem?.label || ''}_${this.$utils.getCurrenttime('yyyyMMddHHmmss')}.xlsx`); + + new Promise((resolve, reject) => { + try { + FileSaver.saveAs(_file, `${this.formItem?.label || ''}_${this.$utils.getCurrenttime('yyyyMMddHHmmss')}.xlsx`); + resolve(this.$t('page.success')); + } catch (error) { + reject(this.$t('page.fail')); + } + }).finally((message) => { + this.isShowExportExcel = true; + }); }); }, handleCellType(uuid) { @@ -416,24 +494,22 @@ export default { }, handleSpecialValue(value) { let valueList = []; - if (typeof value == 'string') { return value?.split('&=&')?.[0] || value; } else if (Array.isArray(value)) { valueList = value.map((item) => item?.split('&=&')?.[0] || item).filter(Boolean); } - return valueList.join(','); }, handleFormatError(file) { this.$Notice.warning({ - title: '格式不正确', - desc: `格式${file.name}不正确,请选择正确的格式` + title: this.$t('message.incorrectformat'), + desc: this.$t('form.validate.fileformat', {target: file.name}) }); }, handleMaxSize(file) { this.$Notice.warning({ - title: '超出文件大小限制', + title: this.$t('page.uploadfilelimit', {target: this.maxSize / 1024}), desc: `${file.name}` }); }, @@ -462,34 +538,35 @@ export default { } }); }); + this.$Message.success(this.$t('message.importsuccess')); }); }, - byComponentTypeSetValue(uuid, item) { + byComponentTypeSetValue(uuid, value) { // 根据组件的类型,设置回显值 let resultValue; let selectedItem = this.extraList.find((extraItem) => extraItem.uuid == uuid); let {config = {}, handler = ''} = selectedItem || {}; - if (item) { + if (value) { let {dataSource = '', isMultiple = false} = config || {}; if (dataSource === 'matrix' && isMultiple) { // 矩阵 resultValue = []; let valueList = []; - if (typeof item == 'string') { - valueList = item.split(','); + if (typeof value == 'string') { + valueList = value.split(','); valueList.forEach((valueItem) => { if (valueItem) { resultValue.push(`${valueItem}&=&${valueItem}`); } }); } else { - resultValue.push(`${item}&=&${item}`); + resultValue.push(`${value}&=&${value}`); } } else if (dataSource == 'static' && (isMultiple || (handler == 'formcheckbox'))) { resultValue = []; - resultValue.push(item); + resultValue.push(value); } else { - resultValue = item; + resultValue = value; } } return resultValue; @@ -575,7 +652,6 @@ export default { 'tableData.tbodyList': { handler: function(val) { this.setValue(val); - //console.log(JSON.stringify(val, null, 2)); }, deep: true, immediate: true -- Gitee