diff --git a/core/core-backend/src/main/java/io/dataease/exportCenter/.DS_Store b/core/core-backend/src/main/java/io/dataease/exportCenter/.DS_Store
new file mode 100644
index 0000000000..5c17fe30fe
Binary files /dev/null and b/core/core-backend/src/main/java/io/dataease/exportCenter/.DS_Store differ
diff --git a/core/core-backend/src/main/java/io/dataease/exportCenter/dao/auto/entity/CoreExportTask.java b/core/core-backend/src/main/java/io/dataease/exportCenter/dao/auto/entity/CoreExportTask.java
new file mode 100644
index 0000000000..b3aaf07412
--- /dev/null
+++ b/core/core-backend/src/main/java/io/dataease/exportCenter/dao/auto/entity/CoreExportTask.java
@@ -0,0 +1,159 @@
+package io.dataease.exportCenter.dao.auto.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import java.io.Serializable;
+
+/**
+ *
+ * 导出任务表
+ *
+ *
+ * @author fit2cloud
+ * @since 2024-05-23
+ */
+@TableName("core_export_task")
+public class CoreExportTask implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ private String id;
+
+ private Long userId;
+
+ private String fileName;
+
+ private Double fileSize;
+
+ private String fileSizeUnit;
+
+ private String exportFrom;
+
+ private String exportStatus;
+
+ private String exportFromType;
+
+ private Long exportTime;
+
+ private String exportProgress;
+
+ private String exportMachineName;
+
+ /**
+ * 过滤参数
+ */
+ private String params;
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public Long getUserId() {
+ return userId;
+ }
+
+ public void setUserId(Long userId) {
+ this.userId = userId;
+ }
+
+ public String getFileName() {
+ return fileName;
+ }
+
+ public void setFileName(String fileName) {
+ this.fileName = fileName;
+ }
+
+ public Double getFileSize() {
+ return fileSize;
+ }
+
+ public void setFileSize(Double fileSize) {
+ this.fileSize = fileSize;
+ }
+
+ public String getFileSizeUnit() {
+ return fileSizeUnit;
+ }
+
+ public void setFileSizeUnit(String fileSizeUnit) {
+ this.fileSizeUnit = fileSizeUnit;
+ }
+
+ public String getExportFrom() {
+ return exportFrom;
+ }
+
+ public void setExportFrom(String exportFrom) {
+ this.exportFrom = exportFrom;
+ }
+
+ public String getExportStatus() {
+ return exportStatus;
+ }
+
+ public void setExportStatus(String exportStatus) {
+ this.exportStatus = exportStatus;
+ }
+
+ public String getExportFromType() {
+ return exportFromType;
+ }
+
+ public void setExportFromType(String exportFromType) {
+ this.exportFromType = exportFromType;
+ }
+
+ public Long getExportTime() {
+ return exportTime;
+ }
+
+ public void setExportTime(Long exportTime) {
+ this.exportTime = exportTime;
+ }
+
+ public String getExportProgress() {
+ return exportProgress;
+ }
+
+ public void setExportProgress(String exportProgress) {
+ this.exportProgress = exportProgress;
+ }
+
+ public String getExportMachineName() {
+ return exportMachineName;
+ }
+
+ public void setExportMachineName(String exportMachineName) {
+ this.exportMachineName = exportMachineName;
+ }
+
+ public String getParams() {
+ return params;
+ }
+
+ public void setParams(String params) {
+ this.params = params;
+ }
+
+ @Override
+ public String toString() {
+ return "CoreExportTask{" +
+ "id = " + id +
+ ", userId = " + userId +
+ ", fileName = " + fileName +
+ ", fileSize = " + fileSize +
+ ", fileSizeUnit = " + fileSizeUnit +
+ ", exportFrom = " + exportFrom +
+ ", exportStatus = " + exportStatus +
+ ", exportFromType = " + exportFromType +
+ ", exportTime = " + exportTime +
+ ", exportProgress = " + exportProgress +
+ ", exportMachineName = " + exportMachineName +
+ ", params = " + params +
+ "}";
+ }
+}
diff --git a/core/core-backend/src/main/java/io/dataease/exportCenter/dao/auto/mapper/CoreExportTaskMapper.java b/core/core-backend/src/main/java/io/dataease/exportCenter/dao/auto/mapper/CoreExportTaskMapper.java
new file mode 100644
index 0000000000..a9d7a4ba26
--- /dev/null
+++ b/core/core-backend/src/main/java/io/dataease/exportCenter/dao/auto/mapper/CoreExportTaskMapper.java
@@ -0,0 +1,18 @@
+package io.dataease.exportCenter.dao.auto.mapper;
+
+import io.dataease.exportCenter.dao.auto.entity.CoreExportTask;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ *
+ * 导出任务表 Mapper 接口
+ *
+ *
+ * @author fit2cloud
+ * @since 2024-05-23
+ */
+@Mapper
+public interface CoreExportTaskMapper extends BaseMapper {
+
+}
diff --git a/core/core-backend/src/main/java/io/dataease/exportCenter/manage/ExportCenterManage.java b/core/core-backend/src/main/java/io/dataease/exportCenter/manage/ExportCenterManage.java
new file mode 100644
index 0000000000..42190b0d49
--- /dev/null
+++ b/core/core-backend/src/main/java/io/dataease/exportCenter/manage/ExportCenterManage.java
@@ -0,0 +1,1246 @@
+package io.dataease.exportCenter.manage;
+
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import io.dataease.api.chart.dto.ViewDetailField;
+import io.dataease.api.chart.request.ChartExcelRequest;
+import io.dataease.api.exportCenter.vo.ExportTaskDTO;
+import io.dataease.auth.bo.TokenUserBO;
+import io.dataease.chart.dao.auto.mapper.CoreChartViewMapper;
+import io.dataease.chart.server.ChartDataServer;
+import io.dataease.engine.constant.DeTypeConstants;
+import io.dataease.exception.DEException;
+import io.dataease.exportCenter.dao.auto.entity.CoreExportTask;
+import io.dataease.exportCenter.dao.auto.mapper.CoreExportTaskMapper;
+import io.dataease.utils.*;
+import io.dataease.visualization.server.DataVisualizationServer;
+import io.dataease.websocket.entity.WsMessage;
+import io.dataease.websocket.service.WsService;
+import jakarta.annotation.PostConstruct;
+import jakarta.annotation.Resource;
+import jakarta.servlet.http.HttpServletResponse;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.poi.ss.usermodel.*;
+import org.apache.poi.ss.util.CellRangeAddress;
+import org.apache.poi.xssf.streaming.SXSSFWorkbook;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.io.*;
+import java.net.InetAddress;
+import java.util.*;
+import java.util.concurrent.Future;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
+
+@Component
+@Transactional(rollbackFor = Exception.class)
+public class ExportCenterManage {
+ @Resource
+ private CoreExportTaskMapper exportTaskMapper;
+ @Resource
+ DataVisualizationServer dataVisualizationServer;
+ @Resource
+ private CoreChartViewMapper coreChartViewMapper;
+ @Autowired
+ private WsService wsService;
+
+ @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/dataease2.0/data/exportData/";
+ @Value("${extract.page.size:50000}")
+ private Integer extractPageSize;
+ static private List STATUS = Arrays.asList("SUCCESS", "FAILED", "PENDING", "IN_PROGRESS", "ALL");
+ private ScheduledThreadPoolExecutor scheduledThreadPoolExecutor;
+ private int corePoolSize = 10;
+ private int keepAliveSeconds = 600;
+ private Map Running_Task = new HashMap<>();
+ @Resource
+ private ChartDataServer chartDataServer;
+
+ @PostConstruct
+ public void init() {
+ scheduledThreadPoolExecutor = new ScheduledThreadPoolExecutor(corePoolSize);
+ scheduledThreadPoolExecutor.setKeepAliveTime(keepAliveSeconds, TimeUnit.SECONDS);
+ }
+
+ @Scheduled(fixedRate = 5000)
+ public void checkRunningTask() {
+ Iterator> iterator = Running_Task.entrySet().iterator();
+ while (iterator.hasNext()) {
+ Map.Entry entry = iterator.next();
+ if (entry.getValue().isDone()) {
+ iterator.remove();
+ try {
+ CoreExportTask exportTask = exportTaskMapper.selectById(entry.getKey());
+ ExportTaskDTO exportTaskDTO = new ExportTaskDTO();
+ BeanUtils.copyBean(exportTaskDTO, exportTask);
+ setExportFromName(exportTaskDTO);
+ WsMessage message = new WsMessage(exportTask.getUserId(), "/task-export-topic", exportTaskDTO);
+ wsService.releaseMessage(message);
+ } catch (Exception e) {
+
+ }
+ }
+ }
+ }
+
+ public void download(String id, HttpServletResponse response) throws Exception {
+ CoreExportTask exportTask = exportTaskMapper.selectById(id);
+ OutputStream outputStream = response.getOutputStream();
+ response.setContentType("application/vnd.ms-excel");
+ response.setHeader("Content-disposition", "attachment;filename=" + exportTask.getFileName());
+ InputStream fileInputStream = new FileInputStream(exportData_path + id + "/" + exportTask.getFileName());
+ byte[] buffer = new byte[4096];
+ int bytesRead;
+ while ((bytesRead = fileInputStream.read(buffer)) != -1) {
+ outputStream.write(buffer, 0, bytesRead);
+ }
+ outputStream.flush();
+ outputStream.close();
+ fileInputStream.close();
+ response.flushBuffer();
+ }
+
+ public void delete(String id) {
+ Iterator> iterator = Running_Task.entrySet().iterator();
+ while (iterator.hasNext()) {
+ Map.Entry entry = iterator.next();
+ if (entry.getKey().equalsIgnoreCase(id)) {
+ entry.getValue().cancel(true);
+ iterator.remove();
+ }
+ }
+ FileUtils.deleteDirectoryRecursively(exportData_path + id);
+ exportTaskMapper.deleteById(id);
+ }
+
+ public void deleteAll(String type) {
+ if (!STATUS.contains(type)) {
+ DEException.throwException("无效的状态");
+ }
+ QueryWrapper queryWrapper = new QueryWrapper<>();
+ queryWrapper.eq("user_id", AuthUtils.getUser().getUserId());
+ if (!type.equalsIgnoreCase("ALL")) {
+ queryWrapper.eq("export_status", type);
+ }
+ List exportTasks = exportTaskMapper.selectList(queryWrapper);
+ exportTasks.parallelStream().forEach(exportTask -> {
+ Iterator> iterator = Running_Task.entrySet().iterator();
+ while (iterator.hasNext()) {
+ Map.Entry entry = iterator.next();
+ if (entry.getKey().equalsIgnoreCase(exportTask.getId())) {
+ entry.getValue().cancel(true);
+ iterator.remove();
+ }
+ }
+ FileUtils.deleteDirectoryRecursively(exportData_path + exportTask.getId());
+ exportTaskMapper.deleteById(exportTask.getId());
+ });
+
+ }
+
+ public void delete(List ids) {
+ ids.forEach(this::delete);
+ }
+
+ public void retry(String id) {
+ CoreExportTask exportTask = exportTaskMapper.selectById(id);
+ exportTask.setExportStatus("PENDING");
+ exportTask.setExportProgress("0");
+ exportTask.setExportMachineName(hostName());
+ exportTask.setExportTime(System.currentTimeMillis());
+ exportTaskMapper.updateById(exportTask);
+ FileUtils.deleteDirectoryRecursively(exportData_path + id);
+ if (exportTask.getExportFromType().equalsIgnoreCase("chart")) {
+ ChartExcelRequest request = JsonUtil.parse(exportTask.getParams(), ChartExcelRequest.class);
+ startViewTask(exportTask, request);
+ }
+ }
+
+ public List exportTasks(String status) {
+ if (!STATUS.contains(status)) {
+ DEException.throwException("Invalid status: " + status);
+ }
+ QueryWrapper queryWrapper = new QueryWrapper<>();
+ queryWrapper.eq("user_id", AuthUtils.getUser().getUserId());
+ queryWrapper.orderByDesc("export_time");
+ List exportTasks = exportTaskMapper.selectList(queryWrapper);
+ List result = new ArrayList<>();
+ exportTasks.forEach(exportTask -> {
+ ExportTaskDTO exportTaskDTO = new ExportTaskDTO();
+ BeanUtils.copyBean(exportTaskDTO, exportTask);
+ if (status.equalsIgnoreCase("ALL")) {
+ setExportFromAbsName(exportTaskDTO);
+ }
+ if (status.equalsIgnoreCase(exportTaskDTO.getExportStatus())) {
+ setExportFromAbsName(exportTaskDTO);
+ }
+ result.add(exportTaskDTO);
+ });
+
+ return result;
+ }
+
+ private void setExportFromAbsName(ExportTaskDTO exportTaskDTO) {
+ if (exportTaskDTO.getExportFromType().equalsIgnoreCase("chart")) {
+ exportTaskDTO.setExportFromName(dataVisualizationServer.getAbsPath(exportTaskDTO.getExportFrom()));
+ }
+ }
+
+ private void setExportFromName(ExportTaskDTO exportTaskDTO) {
+ if (exportTaskDTO.getExportFromType().equalsIgnoreCase("chart")) {
+ exportTaskDTO.setExportFromName(coreChartViewMapper.selectById(exportTaskDTO.getExportFrom()).getTitle());
+ }
+ }
+
+
+// public void exportTableDetails(PanelViewDetailsRequest request, Workbook wb, CellStyle cellStyle, Sheet detailsSheet) throws IOException {
+// List