feat: 新增数据导出中心功能

This commit is contained in:
taojinlong 2024-04-06 20:15:06 +08:00
parent 04f8279171
commit c7687978e5
12 changed files with 575 additions and 123 deletions

View File

@ -1,17 +1,11 @@
package io.dataease.controller.exportCenter;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import io.dataease.controller.request.dataset.DataSetExportRequest;
import io.dataease.plugins.common.base.domain.ExportTask;
import io.dataease.dto.ExportTaskDTO;
import io.dataease.service.exportCenter.ExportCenterService;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
@ApiSupport(order = 31)
@ -25,14 +19,23 @@ public class ExportCenterController {
@PostMapping("/exportTasks/{status}")
public List<ExportTask> exportTasks(@PathVariable String status) {
public List<ExportTaskDTO> exportTasks(@PathVariable String status) {
return exportCenterService.exportTasks(status);
}
@PostMapping("/exportTasks/{status}")
public void addTask(String exportFrom, String exportFromType, DataSetExportRequest request){
@GetMapping("/delete/{id}")
public void delete(@PathVariable String id){
exportCenterService.delete(id);
}
@PostMapping("/delete")
public void delete(@RequestBody List<String> ids){
exportCenterService.delete(ids);
}
@GetMapping("/download/{id}")
public void download(@PathVariable String id, HttpServletResponse response) throws Exception {
exportCenterService.download(id, response);
}
}

View File

@ -18,6 +18,7 @@ import io.dataease.dto.authModel.VAuthModelDTO;
import io.dataease.dto.panel.PanelExport2App;
import io.dataease.dto.panel.PanelGroupDTO;
import io.dataease.plugins.common.base.domain.PanelGroup;
import io.dataease.service.exportCenter.ExportCenterService;
import io.dataease.service.panel.PanelGroupService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
@ -50,6 +51,8 @@ public class PanelGroupController {
private PanelGroupService panelGroupService;
@Resource
private ExtAuthServiceImpl authService;
@Resource
private ExportCenterService exportCenterService;
@ApiOperation("查询树")
@PostMapping("/tree")
@ -170,7 +173,7 @@ public class PanelGroupController {
@DePermissionProxy(value = "proxy")
@I18n
public void innerExportDetails(@RequestBody PanelViewDetailsRequest request, HttpServletResponse response) throws IOException {
panelGroupService.exportPanelViewDetails(request, response);
exportCenterService.addTask(request.getViewId(), "chart", request);
}
@ApiOperation("更新仪表板状态")

View File

@ -0,0 +1,9 @@
package io.dataease.dto;
import io.dataease.plugins.common.base.domain.ExportTask;
import lombok.Data;
@Data
public class ExportTaskDTO extends ExportTask {
private String exportFromName;
}

View File

@ -18,6 +18,7 @@ import io.dataease.i18n.Translator;
import io.dataease.listener.util.CacheUtils;
import io.dataease.plugins.common.base.domain.DatasetGroup;
import io.dataease.plugins.common.base.domain.DatasetGroupExample;
import io.dataease.plugins.common.base.domain.DatasetTable;
import io.dataease.plugins.common.base.mapper.DatasetGroupMapper;
import io.dataease.service.sys.SysAuthService;
import org.apache.commons.collections4.CollectionUtils;
@ -158,6 +159,24 @@ public class DataSetGroupService {
}
}
public String getAbsPath(String id){
DatasetTable datasetTable = dataSetTableService.get(id);
if(datasetTable == null){
return null;
}
if(datasetTable.getSceneId() == null){
return datasetTable.getName();
}
List<DatasetGroup> parents = getParents(datasetTable.getSceneId());
StringBuilder stringBuilder = new StringBuilder();
parents.forEach(ele -> {
if (ObjectUtils.isNotEmpty(ele)) {
stringBuilder.append(ele.getName()).append("/");
}
});
stringBuilder.append(datasetTable.getName());
return stringBuilder.toString();
}
public List<DatasetGroup> getParents(String id) {
List<DatasetGroup> list = new ArrayList<>();
DatasetGroup datasetGroup = datasetGroupMapper.selectByPrimaryKey(id);

View File

@ -2,17 +2,17 @@ package io.dataease.service.exportCenter;
import com.google.gson.Gson;
import io.dataease.commons.constants.JobStatus;
import io.dataease.commons.utils.AuthUtils;
import io.dataease.commons.utils.CommonBeanFactory;
import io.dataease.commons.utils.LogUtil;
import io.dataease.commons.utils.TableUtils;
import io.dataease.controller.dataset.request.DataSetTaskInstanceGridRequest;
import io.dataease.commons.constants.SysLogConstants;
import io.dataease.commons.utils.*;
import io.dataease.controller.request.chart.ChartExtRequest;
import io.dataease.controller.request.dataset.DataSetExportRequest;
import io.dataease.controller.request.dataset.DataSetTableRequest;
import io.dataease.controller.request.panel.PanelViewDetailsRequest;
import io.dataease.controller.request.panel.ViewDetailField;
import io.dataease.dto.ExportTaskDTO;
import io.dataease.dto.chart.ChartViewDTO;
import io.dataease.dto.dataset.DataSetPreviewPage;
import io.dataease.dto.dataset.DataSetTableUnionDTO;
import io.dataease.dto.dataset.DataSetTaskLogDTO;
import io.dataease.i18n.Translator;
import io.dataease.plugins.common.base.domain.*;
import io.dataease.plugins.common.base.mapper.DatasetTableMapper;
@ -25,30 +25,36 @@ import io.dataease.plugins.common.exception.DataEaseException;
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.common.util.FileUtil;
import io.dataease.plugins.datasource.provider.Provider;
import io.dataease.plugins.datasource.provider.ProviderFactory;
import io.dataease.plugins.datasource.query.QueryProvider;
import io.dataease.plugins.xpack.auth.dto.request.ColumnPermissionItem;
import io.dataease.provider.datasource.JdbcProvider;
import io.dataease.service.chart.ChartViewService;
import io.dataease.service.chart.util.ChartDataBuild;
import io.dataease.service.dataset.*;
import io.dataease.service.datasource.DatasourceService;
import io.dataease.service.engine.EngineService;
import io.dataease.service.panel.PanelGroupService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFClientAnchor;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.Base64Utils;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.*;
import java.text.DecimalFormat;
import java.util.*;
import java.util.concurrent.ScheduledThreadPoolExecutor;
@ -63,7 +69,7 @@ public class ExportCenterService {
private ExportTaskMapper exportTaskMapper;
@Value("${export.dataset.limit:100000}")
private int limit;
private final static String DATA_URL_TITLE = "data:image/jpeg;base64,";
private static final String exportData_path = "/opt/dataease/data/exportData/";
@Value("${extract.page.size:50000}")
@ -89,7 +95,12 @@ public class ExportCenterService {
private DatasourceService datasourceService;
@Resource
private PermissionService permissionService;
@Resource
private ChartViewService chartViewService;
@Resource
private DataSetGroupService dataSetGroupService;
@Resource
private PanelGroupService panelGroupService;
private int corePoolSize = 10;
private int keepAliveSeconds = 600;
@ -99,17 +110,306 @@ public class ExportCenterService {
scheduledThreadPoolExecutor.setKeepAliveTime(keepAliveSeconds, TimeUnit.SECONDS);
}
public List<ExportTask> exportTasks(String status) {
public void download(String id, HttpServletResponse response) throws Exception {
ExportTask exportTask = exportTaskMapper.selectByPrimaryKey(id);
OutputStream outputStream = response.getOutputStream();
response.setContentType("application/vnd.ms-excel");
//文件名称
response.setHeader("Content-disposition", "attachment;filename=" + exportTask.getFileName());
XSSFWorkbook wb = new XSSFWorkbook(exportData_path + id + "/" + exportTask.getFileName());
wb.write(outputStream);
outputStream.flush();
outputStream.close();
}
public void delete(String id) {
FileUtil.deleteDirectoryRecursively(exportData_path + id);
exportTaskMapper.deleteByPrimaryKey(id);
}
public void delete(List<String> ids) {
ids.forEach(id -> {
delete(id);
});
}
public List<ExportTaskDTO> exportTasks(String status) {
if (!STATUS.contains(status)) {
DataEaseException.throwException("Invalid status: " + status);
}
ExportTaskExample exportTaskExample = new ExportTaskExample();
ExportTaskExample.Criteria criteria = exportTaskExample.createCriteria();
if (!status.equalsIgnoreCase("ALL")) {
criteria.andExportStatusEqualTo(status);
}
criteria.andUserIdEqualTo(AuthUtils.getUser().getUserId());
return exportTaskMapper.selectByExample(exportTaskExample);
List<ExportTask> exportTasks = exportTaskMapper.selectByExample(exportTaskExample);
List<ExportTaskDTO> result = new ArrayList<>();
exportTasks.forEach(exportTask -> {
ExportTaskDTO exportTaskDTO = new ExportTaskDTO();
BeanUtils.copyBean(exportTaskDTO, exportTask);
if (status.equalsIgnoreCase("ALL")) {
setExportFromName(exportTaskDTO);
}
if (status.equalsIgnoreCase(exportTaskDTO.getExportStatus())) {
setExportFromName(exportTaskDTO);
}
result.add(exportTaskDTO);
});
return result;
}
private void setExportFromName(ExportTaskDTO exportTaskDTO) {
if (exportTaskDTO.getExportFromType().equalsIgnoreCase("chart")) {
exportTaskDTO.setExportFromName(panelGroupService.getAbsPath(exportTaskDTO.getExportFrom()));
}
if (exportTaskDTO.getExportFromType().equalsIgnoreCase("dataset")) {
exportTaskDTO.setExportFromName(dataSetGroupService.getAbsPath(exportTaskDTO.getExportFrom()));
}
}
public void exportTableDetails(PanelViewDetailsRequest request, Workbook wb, CellStyle cellStyle, Sheet detailsSheet) throws IOException {
List<Object[]> details = request.getDetails();
Integer[] excelTypes = request.getExcelTypes();
if (CollectionUtils.isNotEmpty(details)) {
for (int i = 0; i < details.size(); i++) {
Row row = detailsSheet.createRow(i);
Object[] rowData = details.get(i);
if (rowData != null) {
for (int j = 0; j < rowData.length; j++) {
Cell cell = row.createCell(j);
if (i == 0) {// 头部
cell.setCellValue(String.valueOf(rowData[j]));
cell.setCellStyle(cellStyle);
//设置列的宽度
detailsSheet.setColumnWidth(j, 255 * 20);
} else {
try {
// with DataType
if ((excelTypes[j].equals(DeTypeConstants.DE_INT) || excelTypes[j].equals(DeTypeConstants.DE_FLOAT)) && rowData[j] != null) {
cell.setCellValue(Double.valueOf(rowData[j].toString()));
} else {
cell.setCellValue(String.valueOf(rowData[j]));
}
} catch (Exception e) {
LogUtil.warn("export excel data transform error");
}
}
}
}
}
}
}
public void findExcelData(PanelViewDetailsRequest request) {
ChartViewWithBLOBs viewInfo = chartViewService.get(request.getViewId());
request.setDownloadType(viewInfo.getType());
if ("table-info".equals(viewInfo.getType())) {
try {
ChartExtRequest componentFilterInfo = request.getComponentFilterInfo();
componentFilterInfo.setGoPage(1L);
componentFilterInfo.setPageSize(Long.valueOf(limit));
componentFilterInfo.setExcelExportFlag(true);
componentFilterInfo.setProxy(request.getProxy());
componentFilterInfo.setUser(request.getUserId());
ChartViewDTO chartViewInfo = chartViewService.getData(request.getViewId(), componentFilterInfo);
List<Object[]> tableRow = (List) chartViewInfo.getData().get("sourceData");
request.setDetails(tableRow);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
public void addTask(String exportFrom, String exportFromType, PanelViewDetailsRequest request) {
ExportTask exportTask = new ExportTask();
exportTask.setId(UUID.randomUUID().toString());
exportTask.setUserId(AuthUtils.getUser().getUserId());
exportTask.setExportFrom(exportFrom);
exportTask.setExportFromType(exportFromType);
exportTask.setExportStatus("PENDING");
exportTask.setFileName(request.getViewName() + ".xlsx");
exportTask.setExportPogress("0");
exportTask.setExportTime(System.currentTimeMillis());
exportTaskMapper.insert(exportTask);
String dataPath = exportData_path + exportTask.getId();
File directory = new File(dataPath);
boolean isCreated = directory.mkdir();
scheduledThreadPoolExecutor.execute(() -> {
try {
exportTask.setExportStatus("IN_PROGRESS");
exportTaskMapper.updateByPrimaryKey(exportTask);
findExcelData(request);
String snapshot = request.getSnapshot();
List<Object[]> details = request.getDetails();
Integer[] excelTypes = request.getExcelTypes();
details.add(0, request.getHeader());
Workbook wb = new SXSSFWorkbook();
//明细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 ("table-info".equals(request.getDownloadType())) {
exportTableDetails(request, wb, cellStyle, detailsSheet);
} else {
Boolean mergeHead = false;
ViewDetailField[] detailFields = request.getDetailFields();
if (ArrayUtils.isNotEmpty(detailFields)) {
cellStyle.setBorderTop(BorderStyle.THIN);
cellStyle.setBorderRight(BorderStyle.THIN);
cellStyle.setBorderBottom(BorderStyle.THIN);
cellStyle.setBorderLeft(BorderStyle.THIN);
String[] detailField = Arrays.stream(detailFields).map(field -> field.getName()).collect(Collectors.toList()).toArray(new String[detailFields.length]);
Object[] header = request.getHeader();
Row row = detailsSheet.createRow(0);
int headLen = header.length;
int detailFieldLen = detailField.length;
for (int i = 0; i < headLen; i++) {
Cell cell = row.createCell(i);
cell.setCellValue(header[i].toString());
if (i < headLen - 1) {
CellRangeAddress cellRangeAddress = new CellRangeAddress(0, 1, i, i);
detailsSheet.addMergedRegion(cellRangeAddress);
} else {
for (int j = i + 1; j < detailFieldLen + i; j++) {
row.createCell(j).setCellStyle(cellStyle);
}
CellRangeAddress cellRangeAddress = new CellRangeAddress(0, 0, i, i + detailFieldLen - 1);
detailsSheet.addMergedRegion(cellRangeAddress);
}
cell.setCellStyle(cellStyle);
detailsSheet.setColumnWidth(i, 255 * 20);
}
Row detailRow = detailsSheet.createRow(1);
for (int i = 0; i < headLen - 1; i++) {
Cell cell = detailRow.createCell(i);
cell.setCellStyle(cellStyle);
}
for (int i = 0; i < detailFieldLen; i++) {
int colIndex = headLen - 1 + i;
Cell cell = detailRow.createCell(colIndex);
cell.setCellValue(detailField[i]);
cell.setCellStyle(cellStyle);
detailsSheet.setColumnWidth(colIndex, 255 * 20);
}
details.add(1, detailField);
mergeHead = true;
}
if (CollectionUtils.isNotEmpty(details) && (!mergeHead || details.size() > 2)) {
int realDetailRowIndex = 2;
for (int i = (mergeHead ? 2 : 0); i < details.size(); i++) {
Row row = detailsSheet.createRow(realDetailRowIndex > 2 ? realDetailRowIndex : i);
Object[] rowData = details.get(i);
if (rowData != null) {
for (int j = 0; j < rowData.length; j++) {
Object cellValObj = rowData[j];
if (mergeHead && j == rowData.length - 1 && (cellValObj.getClass().isArray() || cellValObj instanceof ArrayList)) {
Object[] detailRowArray = ((List<Object>) cellValObj).toArray(new Object[((List<?>) cellValObj).size()]);
int detailRowArrayLen = detailRowArray.length;
int temlJ = j;
while (detailRowArrayLen > 1 && temlJ-- > 0) {
CellRangeAddress cellRangeAddress = new CellRangeAddress(realDetailRowIndex, realDetailRowIndex + detailRowArrayLen - 1, temlJ, temlJ);
detailsSheet.addMergedRegion(cellRangeAddress);
}
for (int k = 0; k < detailRowArrayLen; k++) {
List<Object> detailRows = (List<Object>) detailRowArray[k];
Row curRow = row;
if (k > 0) {
curRow = detailsSheet.createRow(realDetailRowIndex + k);
}
for (int l = 0; l < detailRows.size(); l++) {
Object col = detailRows.get(l);
Cell cell = curRow.createCell(j + l);
cell.setCellValue(col.toString());
}
}
realDetailRowIndex += detailRowArrayLen;
break;
}
Cell cell = row.createCell(j);
if (i == 0) {// 头部
cell.setCellValue(cellValObj.toString());
cell.setCellStyle(cellStyle);
//设置列的宽度
detailsSheet.setColumnWidth(j, 255 * 20);
} else if (cellValObj != null) {
try {
// with DataType
if ((excelTypes[j].equals(DeTypeConstants.DE_INT) || excelTypes[j].equals(DeTypeConstants.DE_FLOAT)) && StringUtils.isNotEmpty(cellValObj.toString())) {
cell.setCellValue(Double.valueOf(cellValObj.toString()));
} else {
cell.setCellValue(cellValObj.toString());
}
} catch (Exception e) {
LogUtil.warn("export excel data transform error");
}
}
}
}
}
}
if (StringUtils.isNotEmpty(snapshot)) {
//截图sheet 1px 2.33dx 0.48 dy 8*24 个单元格
Sheet snapshotSheet = wb.createSheet("图表");
short reDefaultRowHeight = (short) Math.round(request.getSnapshotHeight() * 3.5 / 8);
int reDefaultColumnWidth = (int) Math.round(request.getSnapshotWidth() * 0.25 / 24);
snapshotSheet.setDefaultColumnWidth(reDefaultColumnWidth);
snapshotSheet.setDefaultRowHeight(reDefaultRowHeight);
//画图的顶级管理器一个sheet只能获取一个一定要注意这点i
Drawing patriarch = snapshotSheet.createDrawingPatriarch();
HSSFClientAnchor anchor = new HSSFClientAnchor(0, 0, reDefaultColumnWidth, reDefaultColumnWidth, (short) 0, 0, (short) 8, 24);
anchor.setAnchorType(ClientAnchor.AnchorType.DONT_MOVE_DO_RESIZE);
patriarch.createPicture(anchor, wb.addPicture(Base64Utils.decodeFromString(snapshot.replace(DATA_URL_TITLE, "")), HSSFWorkbook.PICTURE_TYPE_JPEG));
}
}
try (FileOutputStream outputStream = new FileOutputStream(dataPath + "/" + request.getViewName() + ".xlsx")) {
wb.write(outputStream);
}
wb.close();
if (ObjectUtils.isNotEmpty(AuthUtils.getUser())) {
String viewId = request.getViewId();
ChartViewWithBLOBs chartViewWithBLOBs = chartViewService.get(viewId);
String pid = chartViewWithBLOBs.getSceneId();
DeLogUtils.save(SysLogConstants.OPERATE_TYPE.EXPORT, SysLogConstants.SOURCE_TYPE.VIEW, viewId, pid, null, null);
}
exportTask.setExportPogress("100");
exportTask.setExportStatus("SUCCESS");
} catch (Exception e) {
e.printStackTrace();
exportTask.setExportStatus("FAILED");
} finally {
exportTaskMapper.updateByPrimaryKey(exportTask);
}
});
}
public void addTask(String exportFrom, String exportFromType, DataSetExportRequest request) {
@ -140,11 +440,8 @@ public class ExportCenterService {
permissionsTreeService.getField(tree);
}
Datasource datasource = datasourceService.get(request.getDataSourceId());
Integer totalCount = getTotal(request, limit, tree);
if (totalCount == null) {
Workbook wb = new SXSSFWorkbook();
// Sheet
Sheet detailsSheet = wb.createSheet("数据");
@ -161,7 +458,6 @@ public class ExportCenterService {
cellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
//设置单元格填充样式(使用纯色背景颜色填充)
cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
int pageSize = (datasource != null && StringUtils.equalsIgnoreCase(datasource.getType(), "es")) ? 10000 : limit;
request.setRow(String.valueOf(pageSize));
Map<String, Object> previewData = dataSetTableService.getPreviewData(request, 1, pageSize, null, tree);
@ -171,10 +467,8 @@ public class ExportCenterService {
for (DatasetTableField field : fields) {
header.add(field.getName());
}
List<List<String>> details = new ArrayList<>();
details.add(header);
for (Map<String, Object> obj : data) {
List<String> row = new ArrayList<>();
for (DatasetTableField field : fields) {
@ -222,14 +516,12 @@ public class ExportCenterService {
for (Integer p = 1; p < totalPage + 1; p++) {
Integer offset = p * extractPageSize;
Integer all = offset + extractPageSize;
Map<String, Object> previewData = getPreviewData(request, p, extractPageSize, all, null, tree);
Workbook wb = null;
Sheet detailsSheet = null;
CellStyle cellStyle = null;
FileInputStream fis = null;
if (p == 0L) {
if (p == 1L) {
wb = new SXSSFWorkbook();
// Sheet
detailsSheet = wb.createSheet("数据");
@ -253,7 +545,7 @@ public class ExportCenterService {
}
details.add(header);
} else {
fis = new FileInputStream("existing_file.xlsx");
fis = new FileInputStream(dataPath + "/" + request.getFilename() + ".xlsx");
wb = new XSSFWorkbook(fis); // 假设这是个.xlsx格式的文件
detailsSheet = wb.getSheetAt(0);
}
@ -305,19 +597,15 @@ public class ExportCenterService {
fis.close();
wb.close();
}
exportTask.setExportStatus("IN_PROGRESS");
double exportRogress = (double) (p / totalCount);
double exportRogress = (double) ((double) p / (double) totalCount);
DecimalFormat df = new DecimalFormat("#.##");
String formattedResult = df.format(exportRogress * 100);
exportTask.setExportPogress(formattedResult);
exportTaskMapper.updateByPrimaryKey(exportTask);
}
}
exportTask.setExportPogress("100");
exportTask.setExportStatus("SUCCESS");
} catch (Exception e) {
exportTask.setExportStatus("FAILED");
@ -377,7 +665,7 @@ public class ExportCenterService {
String table = dataTableInfoDTO.getTable();
QueryProvider qp = ProviderFactory.getQueryProvider(ds.getType());
try {
String totalSql = qp.getTotalCount(false, qp.createQuerySQL(table, fields, false, ds, null, rowPermissionsTree), ds);
String totalSql = qp.getTotalCount(false, qp.createQueryTableWithLimit(table, fields, limit, false, ds, null, rowPermissionsTree), ds);
if (totalSql == null) {
return null;
}
@ -404,7 +692,7 @@ public class ExportCenterService {
QueryProvider qp = ProviderFactory.getQueryProvider(ds.getType());
try {
String totalSql = qp.getTotalCount(false, qp.createQuerySQL(table, fields, false, ds, null, rowPermissionsTree), ds);
String totalSql = qp.getTotalCount(false, qp.createQueryTableWithLimit(table, fields, limit, false, ds, null, rowPermissionsTree), ds);
if (totalSql == null) {
return null;
}
@ -433,7 +721,7 @@ public class ExportCenterService {
sql = dataSetTableService.handleVariableDefaultValue(sql, datasetTable.getSqlVariableDetails(), ds.getType(), false);
QueryProvider qp = ProviderFactory.getQueryProvider(ds.getType());
try {
String totalSql = qp.getTotalCount(false, qp.createQuerySQLAsTmp(sql, fields, false, null, rowPermissionsTree), ds);
String totalSql = qp.getTotalCount(false, qp.createQuerySqlWithLimit(sql, fields, limit, false, null, rowPermissionsTree), ds);
if (totalSql == null) {
return null;
}
@ -454,10 +742,8 @@ public class ExportCenterService {
datasourceRequest.setDatasource(ds);
String table = TableUtils.tableName(dataSetTableRequest.getId());
QueryProvider qp = ProviderFactory.getQueryProvider(ds.getType());
try {
String totalSql = qp.getTotalCount(true, qp.createQuerySQL(table, fields, false, ds, null, rowPermissionsTree), ds);
String totalSql = qp.getTotalCount(false, qp.createQueryTableWithLimit(table, fields, limit, false, ds, null, rowPermissionsTree), ds);
if (totalSql == null) {
return null;
}
@ -480,7 +766,7 @@ public class ExportCenterService {
String table = TableUtils.tableName(dataSetTableRequest.getId());
QueryProvider qp = ProviderFactory.getQueryProvider(ds.getType());
try {
String totalSql = qp.getTotalCount(true, qp.createQuerySQL(table, fields, false, ds, null, rowPermissionsTree), ds);
String totalSql = qp.getTotalCount(false, qp.createQueryTableWithLimit(table, fields, limit, false, ds, null, rowPermissionsTree), ds);
if (totalSql == null) {
return null;
}
@ -563,7 +849,7 @@ public class ExportCenterService {
}
QueryProvider qp = ProviderFactory.getQueryProvider(ds.getType());
try {
String totalSql = qp.getTotalCount(true, qp.createQuerySQLAsTmp(sql, fields, false, null, rowPermissionsTree), ds);
String totalSql = qp.getTotalCount(false, qp.createQuerySqlWithLimit(sql, fields, limit, false, null, rowPermissionsTree), ds);
if (totalSql == null) {
return null;
}
@ -581,7 +867,7 @@ public class ExportCenterService {
String table = TableUtils.tableName(dataSetTableRequest.getId());
QueryProvider qp = ProviderFactory.getQueryProvider(ds.getType());
try {
String totalSql = qp.getTotalCount(true, qp.createQuerySQL(table, fields, false, ds, null, rowPermissionsTree), ds);
String totalSql = qp.getTotalCount(false, qp.createQueryTableWithLimit(table, fields, limit, false, ds, null, rowPermissionsTree), ds);
if (totalSql == null) {
return null;
}
@ -705,7 +991,7 @@ public class ExportCenterService {
datasourceRequest.setQuery(qp.createQuerySQLWithPage(sql, fields, page, pageSize, realSize, false, null, rowPermissionsTree));
map.put("sql", java.util.Base64.getEncoder().encodeToString(datasourceRequest.getQuery().getBytes()));
datasourceRequest.setPage(page);
datasourceRequest.setFetchSize(Integer.parseInt(dataSetTableRequest.getRow()));
datasourceRequest.setFetchSize(limit);
datasourceRequest.setPageSize(pageSize);
datasourceRequest.setRealSize(realSize);
datasourceRequest.setPreviewData(true);

View File

@ -1225,4 +1225,43 @@ public class PanelGroupService {
}
}
public String getAbsPath(String id) {
ChartViewWithBLOBs chartViewWithBLOBs = chartViewMapper.selectByPrimaryKey(id);
if (chartViewWithBLOBs == null) {
return null;
}
if (chartViewWithBLOBs.getSceneId() == null) {
return chartViewWithBLOBs.getName();
}
List<PanelGroupWithBLOBs> parents = getParents(chartViewWithBLOBs.getSceneId());
StringBuilder stringBuilder = new StringBuilder();
parents.forEach(ele -> {
if (ObjectUtils.isNotEmpty(ele)) {
stringBuilder.append(ele.getName()).append("/");
}
});
stringBuilder.append(chartViewWithBLOBs.getName());
return stringBuilder.toString();
}
public List<PanelGroupWithBLOBs> getParents(String id) {
List<PanelGroupWithBLOBs> list = new ArrayList<>();
PanelGroupWithBLOBs panelGroupWithBLOBs = panelGroupMapper.selectByPrimaryKey(id);
list.add(panelGroupWithBLOBs);
getParent(list, panelGroupWithBLOBs);
Collections.reverse(list);
return list;
}
public void getParent(List<PanelGroupWithBLOBs> list, PanelGroupWithBLOBs panelGroupWithBLOBs) {
if (ObjectUtils.isNotEmpty(panelGroupWithBLOBs)) {
if (StringUtils.isNotEmpty(panelGroupWithBLOBs.getPid()) && !panelGroupWithBLOBs.getPid().equalsIgnoreCase("panel_list")) {
PanelGroupWithBLOBs d = panelGroupMapper.selectByPrimaryKey(panelGroupWithBLOBs.getPid());
list.add(d);
getParent(list, d);
}
}
}
}

View File

@ -290,6 +290,15 @@ export function exportDataset(data) {
method: 'post',
data: data,
loading: true,
})
}
export function downloadFile(id) {
// 初始化仪表板视图缓存
return request({
url: 'exportCenter/download/' + id,
method: 'get',
loading: true,
responseType: 'blob'
})
}

View File

@ -15,6 +15,7 @@ import Vue from 'vue'
import { exportDetails, innerExportDetails } from '@/api/panel/panel'
import { getLinkToken, getToken } from '@/utils/auth'
import { toPngUrl } from '@/utils/CanvasUtils'
import {Button} from "element-ui";
export function deepCopy(target) {
if (typeof target === 'object' && target !== null) {
@ -528,14 +529,6 @@ export function exportExcelDownload(chart, snapshot, width, height, loadingWrapp
request.proxy = { userId: panelInfo.proxy }
}
method(request).then((res) => {
const blob = new Blob([res], { type: 'application/vnd.ms-excel' })
const link = document.createElement('a')
link.style.display = 'none'
link.href = URL.createObjectURL(blob)
link.download = excelName + '.xlsx' // 下载的文件名
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
loadingWrapper && (loadingWrapper.val = false)
callBack && callBack()
}).catch(() => {

View File

@ -50,6 +50,7 @@
@click="downloadClick"
icon-class="icon_download_outlined"
/>
</div>
<div
v-if="aiBaseUrl"
style="height: 100%;padding: 0 8px;"
@ -61,7 +62,6 @@
@click="handleAiClick"
/>
</a>
</div>
<notification class="right-menu-item hover-effect" />
<lang-select class="right-menu-item hover-effect" />
@ -128,7 +128,6 @@
<ai-component v-if="aiBaseUrl" :base-url="aiBaseUrl"/>
<!--模板市场全屏显示框-->
<el-dialog
:visible="templateMarketShow"

View File

@ -259,6 +259,7 @@ import { pluginLoaded } from '@/api/user'
import PluginCom from '@/views/system/plugin/PluginCom'
import UpdateRecords from './UpdateRecords'
import rowAuth from './components/rowAuth.vue'
import {Button} from "element-ui";
export default {
name: 'ViewTable',
@ -489,6 +490,35 @@ export default {
closeExport() {
this.showExport = false
},
openMessageSuccess(text, type, cb) {
const h = this.$createElement;
const iconClass = `el-icon-${type || "success"}`;
const customClass = `de-message-${type || "success"} de-message-export`;
this.$message({
message: h("p", null, [
h("span", null, text),
h(
Button,
{
props: {
type: "text",
size: "mini",
},
class: "btn-text",
on: {
click: () => {
cb();
},
},
},
"数据导出中心",
),
]),
iconClass,
showClose: true,
customClass,
});
},
exportDatasetRequest() {
this.$refs['exportForm'].validate((valid) => {
if (valid) {
@ -507,16 +537,10 @@ export default {
this.table.expressionTree = JSON.stringify({ items, logic })
this.exportDatasetLoading = true
exportDataset(this.table).then((res) => {
const blob = new Blob([res], { type: 'application/vnd.ms-excel' })
const link = document.createElement('a')
link.style.display = 'none'
link.href = URL.createObjectURL(blob)
link.download = this.exportForm.name + '.xlsx' //
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
this.openMessageSuccess('后台导出中', 'info')
}).finally(() => {
this.exportDatasetLoading = false
this.showExport = false
})
}
} else {

View File

@ -27,22 +27,36 @@
style="width: 100%"
>
<el-table-column type="selection" width="50"> </el-table-column>
<el-table-column prop="name" label="文件名" width="320">
<el-table-column prop="fileName" label="文件名" width="320">
<template slot-scope="scope">
<div class="name-excel">
<svg-icon style="font-size: 24px;" icon-class="icon_file-excel_colorful"> </svg-icon>
<span style="margin-left: 8px">{{ scope.row.name }}</span>
<span style="margin-left: 8px">{{ scope.row.fileName }}</span>
</div>
</template>
</el-table-column>
<el-table-column prop="object" label="导出对象" width="200">
<el-table-column prop="exportFromName" label="导出对象" width="200">
</el-table-column>
<el-table-column prop="origin" width="120" label="导出来源">
<el-table-column prop="exportFromType" width="120" label="导出来源">
<template slot-scope="scope">
<span v-if="scope.row.exportFromType === 'dataset'">数据集</span>
<span v-if="scope.row.exportFromType === 'chart'">视图</span>
</template>
</el-table-column>
<el-table-column prop="time" width="180" label="导出时间">
<el-table-column prop="exportTime" width="180" label="导出时间">
<template slot-scope="scope">
<span>{{ scope.row.exportTime | timestampFormatDate }}</span>
</template>
</el-table-column>
<el-table-column prop="operate" width="80" label="操作">
<template slot-scope="scope">
<el-button v-if="activeName === 'SUCCESS'" type="text" size="mini" @click="downloadClick(scope.row)">
<div class="download-export">
<svg-icon
icon-class="icon_download_outlined"
/>
</div>
</el-button>
<el-button type="text" size="mini" @click="deleteField(scope.row)"
>{{ $t("dataset.delete") }}
</el-button>
@ -63,11 +77,13 @@
<script>
import msgCfm from "@/components/msgCfm/index";
import { Button } from "element-ui";
import request from "@/utils/request";
import {downloadFile, post} from '@/api/dataset/dataset'
export default {
mixins: [msgCfm],
data() {
return {
activeName: "all",
activeName: "IN_PROGRESS",
multipleSelection: [],
errImg: require("@/assets/none-data.png"),
tableData: [{ name: "附件名称" }],
@ -75,31 +91,83 @@ export default {
description: this.$t("暂无任务"),
tabList: [
{
label: "导出中(3)",
name: "ing",
label: "导出中(0)",
name: "IN_PROGRESS",
},
{
label: "成功(3)",
name: "success",
label: "成功(0)",
name: "SUCCESS",
},
{
label: "失败(3)",
name: "fail",
label: "失败(0)",
name: "FAILED",
},
{
label: "全部(3)",
name: "all",
label: "全部(0)",
name: "ALL",
},
],
};
},
created() {
this.handleClick()
},
methods: {
init() {
this.drawer = true;
},
handleClick() {},
deleteField() {
this.tableData = [];
handleClick() {
request({
url: '/exportCenter/exportTasks/' + this.activeName,
method: 'post'
}).then(
(res) => {
this.tabList.forEach( item => {
if(item.name === 'ALL'){
item.label = '全部' + '(' + res.data.length + ')'
}
if(item.name === 'IN_PROGRESS'){
item.label = '导出中' + '(' + res.data.filter(task => task.exportStatus === 'IN_PROGRESS').length + ')'
}
if(item.name === 'SUCCESS'){
item.label = '成功' + '(' + res.data.filter(task => task.exportStatus === 'SUCCESS').length + ')'
}
if(item.name === 'FAILED'){
item.label = '失败' + '(' + res.data.filter(task => task.exportStatus === 'FAILED').length + ')'
}
})
if(this.activeName === 'ALL'){
this.tableData = res.data
}else {
this.tableData = res.data.filter(task => task.exportStatus === this.activeName)
}
}
)
},
downloadClick(item) {
downloadFile(item.id).then((res) => {
const blob = new Blob([res], { type: 'application/vnd.ms-excel' })
const link = document.createElement('a')
link.style.display = 'none'
link.href = URL.createObjectURL(blob)
link.download = item.fileName //
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
}).finally(() => {
this.exportDatasetLoading = false
})
},
deleteField(item) {
request({
url: '/exportCenter/delete/' + item.id,
method: 'get'
}).then(
(res) => {
this.handleClick()
}
)
this.openMessageSuccess("commons.delete_success");
},
handleSelectionChange(val) {
@ -143,40 +211,19 @@ export default {
customClass,
});
},
openMessageSuccess(text, type, cb) {
const h = this.$createElement;
const iconClass = `el-icon-${type || "success"}`;
const customClass = `de-message-${type || "success"} de-message-export`;
this.$message({
message: h("p", null, [
h("span", null, text),
h(
Button,
{
props: {
type: "text",
size: "mini",
},
class: "btn-text",
on: {
click: () => {
cb();
},
},
},
"数据导出中心",
),
]),
iconClass,
showClose: true,
customClass,
});
},
delAll() {
this.openMessageLoading(this.handleClick);
this.openMessageSuccess( '第二个文件名称 导出失败,前往', 'error',this.handleClick);
this.openMessageSuccess( '第二个文件名称 导出成功,前往', 'success',this.handleClick);
post(
'/exportCenter/delete',
this.multipleSelection.map((ele) => ele.id),
false
).then(
(res) => {
this.handleClick()
}
)
this.openMessageSuccess("commons.delete_success");
},
handleClose() {
this.drawer = false;
},

View File

@ -101,4 +101,25 @@ public class FileUtil {
throw new RuntimeException(e);
}
}
public static boolean deleteDirectoryRecursively(String directoryPath) {
File directory = new File(directoryPath);
if (!directory.exists()) {
return true;
}
File[] files = directory.listFiles();
if (files != null) {
for (File file : files) {
if (file.isDirectory()) {
deleteDirectoryRecursively(file.getAbsolutePath());
} else {
boolean deletionSuccess = file.delete();
}
}
}
return directory.delete();
}
}