From 432b2f50ec719d64f337d902b81202c30a6bdce1 Mon Sep 17 00:00:00 2001 From: junjun Date: Mon, 7 Nov 2022 16:03:08 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E6=95=B0=E6=8D=AE=E9=9B=86):=20=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E9=9B=86=E5=AF=BC=E5=87=BAExcel?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../chart/ChartViewFieldController.java | 2 +- .../dataset/DataSetTableController.java | 12 +- .../dataset/DataSetTableFieldController.java | 4 +- .../request/dataset/DataSetExportRequest.java | 12 ++ .../service/dataset/DataSetTableService.java | 97 ++++++++++++- frontend/src/api/dataset/dataset.js | 13 +- frontend/src/lang/en.js | 6 +- frontend/src/lang/tw.js | 6 +- frontend/src/lang/zh.js | 6 +- frontend/src/views/dataset/data/ViewTable.vue | 127 +++++++++++++++++- 10 files changed, 269 insertions(+), 16 deletions(-) create mode 100644 backend/src/main/java/io/dataease/controller/request/dataset/DataSetExportRequest.java diff --git a/backend/src/main/java/io/dataease/controller/chart/ChartViewFieldController.java b/backend/src/main/java/io/dataease/controller/chart/ChartViewFieldController.java index ef48599bc5..0f9ae8c9d0 100644 --- a/backend/src/main/java/io/dataease/controller/chart/ChartViewFieldController.java +++ b/backend/src/main/java/io/dataease/controller/chart/ChartViewFieldController.java @@ -46,7 +46,7 @@ public class ChartViewFieldController { BeanUtils.copyProperties(datasetTable, dataSetTableRequest); DatasetTableField datasetTableField = new DatasetTableField(); BeanUtils.copyProperties(chartViewField, datasetTableField); - dataSetTableService.getPreviewData(dataSetTableRequest, 1, 1, Collections.singletonList(datasetTableField)); + dataSetTableService.getPreviewData(dataSetTableRequest, 1, 1, Collections.singletonList(datasetTableField), null); } catch (Exception e) { DEException.throwException(Translator.get("i18n_calc_field_error")); } diff --git a/backend/src/main/java/io/dataease/controller/dataset/DataSetTableController.java b/backend/src/main/java/io/dataease/controller/dataset/DataSetTableController.java index 8e869e7cd4..2f9c58759c 100644 --- a/backend/src/main/java/io/dataease/controller/dataset/DataSetTableController.java +++ b/backend/src/main/java/io/dataease/controller/dataset/DataSetTableController.java @@ -12,6 +12,8 @@ import io.dataease.commons.constants.SysLogConstants; import io.dataease.commons.utils.PageUtils; import io.dataease.commons.utils.Pager; import io.dataease.controller.ResultHolder; +import io.dataease.controller.handler.annotation.I18n; +import io.dataease.controller.request.dataset.DataSetExportRequest; import io.dataease.controller.request.dataset.DataSetTableRequest; import io.dataease.controller.response.DataSetDetail; import io.dataease.dto.dataset.DataSetTableDTO; @@ -29,6 +31,7 @@ import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; import java.util.Collections; import java.util.List; import java.util.Map; @@ -139,7 +142,7 @@ public class DataSetTableController { @ApiOperation("查询预览数据") @PostMapping("getPreviewData/{page}/{pageSize}") public Map getPreviewData(@RequestBody DataSetTableRequest dataSetTableRequest, @PathVariable Integer page, @PathVariable Integer pageSize) throws Exception { - return dataSetTableService.getPreviewData(dataSetTableRequest, page, pageSize, null); + return dataSetTableService.getPreviewData(dataSetTableRequest, page, pageSize, null, null); } @ApiOperation("db数据库表预览数据") @@ -249,4 +252,11 @@ public class DataSetTableController { public List getDatasetNameFromGroup(@PathVariable String sceneId) { return dataSetTableService.getDatasetNameFromGroup(sceneId); } + + @ApiOperation("数据集导出") + @PostMapping("/exportDataset") + @I18n + public void exportDataset(@RequestBody DataSetExportRequest request, HttpServletResponse response) throws Exception { + dataSetTableService.exportDataset(request, response); + } } diff --git a/backend/src/main/java/io/dataease/controller/dataset/DataSetTableFieldController.java b/backend/src/main/java/io/dataease/controller/dataset/DataSetTableFieldController.java index 9dddbd612c..8d71eaf194 100644 --- a/backend/src/main/java/io/dataease/controller/dataset/DataSetTableFieldController.java +++ b/backend/src/main/java/io/dataease/controller/dataset/DataSetTableFieldController.java @@ -125,7 +125,7 @@ public class DataSetTableFieldController { DatasetTable datasetTable = dataSetTableService.get(datasetTableField.getTableId()); DataSetTableRequest dataSetTableRequest = new DataSetTableRequest(); BeanUtils.copyProperties(datasetTable, dataSetTableRequest); - dataSetTableService.getPreviewData(dataSetTableRequest, 1, 1, Collections.singletonList(datasetTableField)); + dataSetTableService.getPreviewData(dataSetTableRequest, 1, 1, Collections.singletonList(datasetTableField), null); } catch (Exception e) { DEException.throwException(Translator.get("i18n_calc_field_error")); } @@ -177,7 +177,7 @@ public class DataSetTableFieldController { DecodedJWT jwt = JWT.decode(linkToken); Long userId = jwt.getClaim("userId").asLong(); multFieldValuesRequest.setUserId(userId); - return dataSetFieldService.fieldValues(multFieldValuesRequest.getFieldIds(), multFieldValuesRequest.getSort(), multFieldValuesRequest.getUserId(), true, true,false); + return dataSetFieldService.fieldValues(multFieldValuesRequest.getFieldIds(), multFieldValuesRequest.getSort(), multFieldValuesRequest.getUserId(), true, true, false); } @ApiIgnore diff --git a/backend/src/main/java/io/dataease/controller/request/dataset/DataSetExportRequest.java b/backend/src/main/java/io/dataease/controller/request/dataset/DataSetExportRequest.java new file mode 100644 index 0000000000..0f5b3834e0 --- /dev/null +++ b/backend/src/main/java/io/dataease/controller/request/dataset/DataSetExportRequest.java @@ -0,0 +1,12 @@ +package io.dataease.controller.request.dataset; + +import lombok.Data; + +/** + * @Author Junjun + */ +@Data +public class DataSetExportRequest extends DataSetTableRequest { + private String filename; + private String expressionTree; +} diff --git a/backend/src/main/java/io/dataease/service/dataset/DataSetTableService.java b/backend/src/main/java/io/dataease/service/dataset/DataSetTableService.java index c5f536df90..7849c86d69 100644 --- a/backend/src/main/java/io/dataease/service/dataset/DataSetTableService.java +++ b/backend/src/main/java/io/dataease/service/dataset/DataSetTableService.java @@ -11,6 +11,7 @@ import io.dataease.commons.constants.*; import io.dataease.commons.exception.DEException; import io.dataease.commons.utils.*; import io.dataease.controller.ResultHolder; +import io.dataease.controller.request.dataset.DataSetExportRequest; import io.dataease.controller.request.dataset.DataSetGroupRequest; import io.dataease.controller.request.dataset.DataSetTableRequest; import io.dataease.controller.request.dataset.DataSetTaskRequest; @@ -32,11 +33,13 @@ import io.dataease.plugins.common.base.domain.*; import io.dataease.plugins.common.base.mapper.*; import io.dataease.plugins.common.constants.DatasetType; import io.dataease.plugins.common.constants.DatasourceTypes; +import io.dataease.plugins.common.constants.DeTypeConstants; import io.dataease.plugins.common.dto.dataset.SqlVariableDetails; import io.dataease.plugins.common.dto.datasource.DataSourceType; import io.dataease.plugins.common.dto.datasource.TableField; import io.dataease.plugins.common.request.datasource.DatasourceRequest; import io.dataease.plugins.common.request.permission.DataSetRowPermissionsTreeDTO; +import io.dataease.plugins.common.request.permission.DatasetRowPermissionsTreeObj; import io.dataease.plugins.datasource.provider.Provider; import io.dataease.plugins.datasource.query.QueryProvider; import io.dataease.plugins.loader.ClassloaderResponsity; @@ -61,8 +64,8 @@ import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; import org.apache.poi.hssf.usermodel.HSSFDateUtil; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.CellType; +import org.apache.poi.ss.usermodel.*; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; @@ -72,6 +75,7 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; import java.io.*; import java.math.BigDecimal; import java.nio.charset.StandardCharsets; @@ -558,7 +562,7 @@ public class DataSetTableService { } public Map getPreviewData(DataSetTableRequest dataSetTableRequest, Integer page, Integer pageSize, - List extFields) throws Exception { + List extFields, DatasetRowPermissionsTreeObj extTree) throws Exception { Map map = new HashMap<>(); String syncStatus = ""; DatasetTableField datasetTableField = DatasetTableField.builder().tableId(dataSetTableRequest.getId()) @@ -576,6 +580,12 @@ public class DataSetTableService { DatasetTable datasetTable = datasetTableMapper.selectByPrimaryKey(dataSetTableRequest.getId()); // 行权限 List rowPermissionsTree = permissionsTreeService.getRowPermissionsTree(fields, datasetTable, null); + // ext filter + if (extTree != null) { + DataSetRowPermissionsTreeDTO dto = new DataSetRowPermissionsTreeDTO(); + dto.setTree(extTree); + rowPermissionsTree.add(dto); + } // 列权限 List desensitizationList = new ArrayList<>(); fields = permissionService.filterColumnPermissions(fields, desensitizationList, datasetTable.getId(), null); @@ -2869,4 +2879,85 @@ public class DataSetTableService { public void updateDatasetInfo(DatasetTable datasetTable) { datasetTableMapper.updateByPrimaryKeySelective(datasetTable); } + + public void exportDataset(DataSetExportRequest request, HttpServletResponse response) throws Exception { + try { + DatasetRowPermissionsTreeObj tree = null; + if (StringUtils.isNotEmpty(request.getExpressionTree())) { + Gson gson = new Gson(); + tree = gson.fromJson(request.getExpressionTree(), DatasetRowPermissionsTreeObj.class); + } + Map previewData = getPreviewData(request, 1, 100000, null, tree); + List fields = (List) previewData.get("fields"); + List> data = (List>) previewData.get("data"); + // 构建Excel数据格式 + List> details = new ArrayList<>(); + List header = new ArrayList<>(); + for (DatasetTableField field : fields) { + header.add(field.getName()); + } + details.add(header); + for (Map obj : data) { + List row = new ArrayList<>(); + for (DatasetTableField field : fields) { + String string = (String) obj.get(field.getDataeaseName()); + row.add(string); + } + details.add(row); + } + // 操作Excel + Workbook wb = new XSSFWorkbook(); + // Sheet + Sheet detailsSheet = wb.createSheet("数据"); + //给单元格设置样式 + CellStyle cellStyle = wb.createCellStyle(); + Font font = wb.createFont(); + //设置字体大小 + font.setFontHeightInPoints((short) 12); + //设置字体加粗 + font.setBold(true); + //给字体设置样式 + cellStyle.setFont(font); + //设置单元格背景颜色 + cellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex()); + //设置单元格填充样式(使用纯色背景颜色填充) + cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); + if (CollectionUtils.isNotEmpty(details)) { + for (int i = 0; i < details.size(); i++) { + Row row = detailsSheet.createRow(i); + List rowData = details.get(i); + if (rowData != null) { + for (int j = 0; j < rowData.size(); j++) { + Cell cell = row.createCell(j); + if (i == 0) {// 头部 + cell.setCellValue(rowData.get(j)); + cell.setCellStyle(cellStyle); + //设置列的宽度 + detailsSheet.setColumnWidth(j, 255 * 20); + } else { + if ((fields.get(j).getDeType() == DeTypeConstants.DE_INT || fields.get(j).getDeType() == DeTypeConstants.DE_FLOAT) && StringUtils.isNotEmpty(rowData.get(j))) { + try { + cell.setCellValue(Double.valueOf(rowData.get(j))); + } catch (Exception e) { + LogUtil.warn("export excel data transform error"); + } + } else { + cell.setCellValue(rowData.get(j)); + } + } + } + } + } + } + OutputStream outputStream = response.getOutputStream(); + response.setContentType("application/vnd.ms-excel"); + //文件名称 + response.setHeader("Content-disposition", "attachment;filename=" + request.getFilename() + ".xlsx"); + wb.write(outputStream); + outputStream.flush(); + outputStream.close(); + } catch (Exception e) { + DataEaseException.throwException(e); + } + } } diff --git a/frontend/src/api/dataset/dataset.js b/frontend/src/api/dataset/dataset.js index 106337e62b..c96d1a7bec 100644 --- a/frontend/src/api/dataset/dataset.js +++ b/frontend/src/api/dataset/dataset.js @@ -249,4 +249,15 @@ export function dsTable(page, size, id) { method: 'post' }) } -export default { loadTable, getScene, addGroup, delGroup, addTable, delTable, groupTree, checkCustomDs } + +export function exportDataset(data) { + // 初始化仪表板视图缓存 + return request({ + url: 'dataset/table/exportDataset', + method: 'post', + data: data, + loading: true, + responseType: 'blob' + }) +} +export default { loadTable, getScene, addGroup, delGroup, addTable, delTable, groupTree, checkCustomDs, exportDataset } diff --git a/frontend/src/lang/en.js b/frontend/src/lang/en.js index 36464b9ecb..0a0fbedd08 100644 --- a/frontend/src/lang/en.js +++ b/frontend/src/lang/en.js @@ -1693,7 +1693,11 @@ export default { input_edit_name: 'Input field name', edit_search: 'Search by name', na: 'None', - date_format: 'Time format, default: year-month-day hour:minute:second' + date_format: 'Time format, default: year-month-day hour:minute:second', + export_dataset: 'Export', + filename: 'Filename', + export_filter: 'Filter', + pls_input_filename: 'Please input filename' }, driver: { driver: 'Driver', diff --git a/frontend/src/lang/tw.js b/frontend/src/lang/tw.js index d29875e9de..06efa7fbd1 100644 --- a/frontend/src/lang/tw.js +++ b/frontend/src/lang/tw.js @@ -1693,7 +1693,11 @@ export default { input_edit_name: '請輸入字段名稱', edit_search: '通過名稱搜索', na: '暫無', - date_format: '時間格式,默認:年-月-日 時:分:秒' + date_format: '時間格式,默認:年-月-日 時:分:秒', + export_dataset: '數據集導出', + filename: '文件名稱', + export_filter: '篩選條件', + pls_input_filename: '請輸入文件名稱' }, driver: { driver: '驅動', diff --git a/frontend/src/lang/zh.js b/frontend/src/lang/zh.js index 4ed1cbc09c..acab15b99e 100644 --- a/frontend/src/lang/zh.js +++ b/frontend/src/lang/zh.js @@ -1692,7 +1692,11 @@ export default { input_edit_name: '请输入字段名称', edit_search: '通过名称搜索', na: '暂无', - date_format: '时间格式,默认: 年-月-日 时:分:秒' + date_format: '时间格式,默认: 年-月-日 时:分:秒', + export_dataset: '数据集导出', + filename: '文件名称', + export_filter: '筛选条件', + pls_input_filename: '请输入文件名称' }, driver: { driver: '驱动', diff --git a/frontend/src/views/dataset/data/ViewTable.vue b/frontend/src/views/dataset/data/ViewTable.vue index a82a49ac07..8ee482c617 100644 --- a/frontend/src/views/dataset/data/ViewTable.vue +++ b/frontend/src/views/dataset/data/ViewTable.vue @@ -55,12 +55,19 @@ + + {{ $t('dataset.export_dataset') }} + @@ -177,11 +184,66 @@ /> + + + + + + + + + + + + + 提示:最多支持导出10万条数据 + +