forked from github/dataease
Merge pull request #9703 from dataease/pr@dev-v2@feat_report_excel
fix(X-Pack): 定时报告-导出excel
This commit is contained in:
commit
6dcbb71bd2
@ -0,0 +1,21 @@
|
||||
package io.dataease.visualization.bo;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class ExcelSheetModel implements Serializable {
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1122095875367371623L;
|
||||
|
||||
private String sheetName;
|
||||
|
||||
private List<String> heads;
|
||||
|
||||
private List<List<String>> data;
|
||||
|
||||
private List<Integer> filedTypes;
|
||||
}
|
@ -0,0 +1,146 @@
|
||||
package io.dataease.visualization.manage;
|
||||
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import io.dataease.api.chart.dto.ChartExtFilterDTO;
|
||||
import io.dataease.api.chart.dto.ChartViewDTO;
|
||||
import io.dataease.api.chart.dto.ChartViewFieldDTO;
|
||||
import io.dataease.api.chart.request.ChartExtRequest;
|
||||
import io.dataease.api.visualization.vo.DataVisualizationVO;
|
||||
import io.dataease.chart.manage.ChartDataManage;
|
||||
import io.dataease.chart.manage.ChartViewManege;
|
||||
import io.dataease.constant.CommonConstants;
|
||||
import io.dataease.exception.DEException;
|
||||
import io.dataease.utils.AuthUtils;
|
||||
import io.dataease.utils.JsonUtil;
|
||||
import io.dataease.visualization.bo.ExcelSheetModel;
|
||||
import io.dataease.visualization.dao.ext.mapper.ExtDataVisualizationMapper;
|
||||
import io.dataease.visualization.template.FilterBuildTemplate;
|
||||
import io.dataease.visualization.utils.VisualizationExcelUtils;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
@Component
|
||||
public class CoreVisualizationExportManage {
|
||||
@Resource
|
||||
private ExtDataVisualizationMapper extDataVisualizationMapper;
|
||||
|
||||
@Resource
|
||||
private ChartViewManege chartViewManege;
|
||||
|
||||
@Resource
|
||||
private ChartDataManage chartDataManage;
|
||||
|
||||
@Resource
|
||||
private VisualizationTemplateExtendDataManage extendDataManage;
|
||||
|
||||
public File exportExcel(Long dvId, String busiFlag, List<Long> viewIdList, boolean onlyDisplay) throws Exception {
|
||||
DataVisualizationVO visualization = extDataVisualizationMapper.findDvInfo(dvId, busiFlag);
|
||||
if (ObjectUtils.isEmpty(visualization)) DEException.throwException("资源不存在或已经被删除...");
|
||||
List<ChartViewDTO> chartViewDTOS = chartViewManege.listBySceneId(dvId);
|
||||
|
||||
if (CollectionUtils.isNotEmpty(viewIdList)) {
|
||||
chartViewDTOS = chartViewDTOS.stream().filter(item -> viewIdList.contains(item.getId())).collect(Collectors.toList());
|
||||
}
|
||||
if (CollectionUtils.isEmpty(chartViewDTOS)) return null;
|
||||
Map<String, ChartExtRequest> chartExtRequestMap = buildViewRequest(visualization, onlyDisplay);
|
||||
List<ExcelSheetModel> sheets = chartViewDTOS.stream().map(view -> {
|
||||
ChartExtRequest extRequest = chartExtRequestMap.get(view.getId().toString());
|
||||
if (ObjectUtils.isNotEmpty(extRequest)) {
|
||||
view.setChartExtRequest(extRequest);
|
||||
}
|
||||
view.getChartExtRequest().setUser(AuthUtils.getUser().getUserId());
|
||||
return exportViewData(view);
|
||||
}).toList();
|
||||
return VisualizationExcelUtils.exportExcel(sheets, visualization.getName(), visualization.getId().toString());
|
||||
}
|
||||
|
||||
private ExcelSheetModel exportViewData(ChartViewDTO request) {
|
||||
ExcelSheetModel result = new ExcelSheetModel();
|
||||
ChartViewDTO chartViewDTO = null;
|
||||
if (CommonConstants.VIEW_DATA_FROM.TEMPLATE.equalsIgnoreCase(request.getDataFrom())) {
|
||||
chartViewDTO = extendDataManage.getChartDataInfo(request.getId(), request);
|
||||
} else {
|
||||
try {
|
||||
chartViewDTO = chartDataManage.calcData(request);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
String title = chartViewDTO.getTitle();
|
||||
Map<String, Object> chart = chartViewDTO.getData();
|
||||
|
||||
Object objectFields = chart.get("fields");
|
||||
List<ChartViewFieldDTO> fields = (List<ChartViewFieldDTO>) objectFields;
|
||||
List<String> heads = new ArrayList<>();
|
||||
List<String> headKeys = new ArrayList<>();
|
||||
List<Integer> fieldTypes = new ArrayList<>();
|
||||
if (CollectionUtils.isNotEmpty(fields)) {
|
||||
fields.forEach(field -> {
|
||||
Object name = field.getName();
|
||||
Object dataeaseName = field.getDataeaseName();
|
||||
Object deType = field.getDeType();
|
||||
if (ObjectUtils.isNotEmpty(name) && ObjectUtils.isNotEmpty(dataeaseName)) {
|
||||
heads.add(name.toString());
|
||||
headKeys.add(dataeaseName.toString());
|
||||
fieldTypes.add((int) deType);
|
||||
}
|
||||
});
|
||||
}
|
||||
Object objectTableRow = chart.get("tableRow");
|
||||
List<Map<String, Object>> tableRow = (List<Map<String, Object>>) objectTableRow;
|
||||
|
||||
List<List<String>> details = tableRow.stream().map(row -> headKeys.stream().map(key -> {
|
||||
Object val = row.get(key);
|
||||
if (ObjectUtils.isEmpty(val))
|
||||
return StringUtils.EMPTY;
|
||||
return filterInvalidDecimal(val.toString());
|
||||
}).collect(Collectors.toList())).collect(Collectors.toList());
|
||||
result.setHeads(heads);
|
||||
result.setData(details);
|
||||
result.setFiledTypes(fieldTypes);
|
||||
result.setSheetName(title);
|
||||
return result;
|
||||
}
|
||||
|
||||
private String filterInvalidDecimal(String sourceNumberStr) {
|
||||
if (StringUtils.isNotBlank(sourceNumberStr) && StringUtils.contains(sourceNumberStr, ".")) {
|
||||
sourceNumberStr = sourceNumberStr.replaceAll("0+?$", "");
|
||||
sourceNumberStr = sourceNumberStr.replaceAll("[.]$", "");
|
||||
}
|
||||
return sourceNumberStr;
|
||||
}
|
||||
|
||||
private final TypeReference<List<Map<String, Object>>> tokenType = new TypeReference<List<Map<String, Object>>>() {
|
||||
};
|
||||
|
||||
|
||||
private Map<String, ChartExtRequest> buildViewRequest(DataVisualizationVO panelDto, Boolean justView) {
|
||||
String componentsJson = panelDto.getComponentData();
|
||||
List<Map<String, Object>> components = JsonUtil.parseList(componentsJson, tokenType);
|
||||
Map<String, ChartExtRequest> result = new HashMap<>();
|
||||
Map<String, List<ChartExtFilterDTO>> panelFilters = FilterBuildTemplate.buildEmpty(components);
|
||||
// List<String> tableInfoViewIds = findTableInfoViewIds(components);
|
||||
for (Map.Entry<String, List<ChartExtFilterDTO>> entry : panelFilters.entrySet()) {
|
||||
List<ChartExtFilterDTO> chartExtFilterRequests = entry.getValue();
|
||||
ChartExtRequest chartExtRequest = new ChartExtRequest();
|
||||
chartExtRequest.setQueryFrom("panel");
|
||||
chartExtRequest.setFilter(chartExtFilterRequests);
|
||||
chartExtRequest.setResultCount((int) 1000);
|
||||
chartExtRequest.setResultMode("all");
|
||||
result.put(entry.getKey(), chartExtRequest);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package io.dataease.visualization.template;
|
||||
|
||||
import io.dataease.api.chart.dto.ChartExtFilterDTO;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class FilterBuildTemplate {
|
||||
|
||||
public static Map<String, List<ChartExtFilterDTO>> buildEmpty(List<Map<String, Object>> components) {
|
||||
Map<String, List<ChartExtFilterDTO>> result = new HashMap<>();
|
||||
components.forEach(element -> {
|
||||
if (StringUtils.equals(element.get("component").toString(), "UserView")) {
|
||||
String viewId = element.get("id").toString();
|
||||
result.put(viewId, new ArrayList<>());
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
}
|
@ -0,0 +1,100 @@
|
||||
package io.dataease.visualization.utils;
|
||||
|
||||
import io.dataease.engine.constant.DeTypeConstants;
|
||||
import io.dataease.utils.FileUtils;
|
||||
import io.dataease.utils.LogUtil;
|
||||
import io.dataease.visualization.bo.ExcelSheetModel;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.poi.ss.usermodel.*;
|
||||
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
|
||||
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class VisualizationExcelUtils {
|
||||
|
||||
private static final String suffix = ".xlsx";
|
||||
private static final String BASE_ROOT = "/opt/dataease2.0/data/report/";
|
||||
|
||||
public static File exportExcel(List<ExcelSheetModel> sheets, String fileName, String folderId) throws Exception {
|
||||
AtomicReference<String> realFileName = new AtomicReference<>(fileName);
|
||||
Workbook wb = new SXSSFWorkbook();
|
||||
|
||||
sheets.forEach(sheet -> {
|
||||
|
||||
List<List<String>> details = sheet.getData();
|
||||
List<Integer> fieldTypes = sheet.getFiledTypes();
|
||||
details.add(0, sheet.getHeads());
|
||||
String sheetName = sheet.getSheetName();
|
||||
Pattern pattern = Pattern.compile("[\\s\\\\/:\\*\\?\\\"<>\\|]");
|
||||
Matcher matcher = pattern.matcher(sheetName);
|
||||
sheetName = matcher.replaceAll("-");
|
||||
Sheet curSheet = wb.createSheet(sheetName);
|
||||
if (StringUtils.isBlank(fileName)) {
|
||||
String cName = sheetName + suffix;
|
||||
realFileName.set(cName);
|
||||
}
|
||||
|
||||
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 = curSheet.createRow(i);
|
||||
List<String> rowData = details.get(i);
|
||||
if (rowData != null) {
|
||||
for (int j = 0; j < rowData.size(); j++) {
|
||||
Cell cell = row.createCell(j);
|
||||
// with DataType
|
||||
if (i > 0 && (fieldTypes.get(j).equals(DeTypeConstants.DE_INT) || fieldTypes.get(j).equals(DeTypeConstants.DE_FLOAT)) && StringUtils.isNotEmpty(rowData.get(j))) {
|
||||
cell.setCellValue(Double.valueOf(rowData.get(j)));
|
||||
} else {
|
||||
cell.setCellValue(rowData.get(j));
|
||||
}
|
||||
if (i == 0) {// 头部
|
||||
cell.setCellStyle(cellStyle);
|
||||
// 设置列的宽度
|
||||
curSheet.setColumnWidth(j, 255 * 20);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
if (!StringUtils.endsWith(fileName, suffix)) {
|
||||
realFileName.set(realFileName.get() + suffix);
|
||||
}
|
||||
String folderPath = BASE_ROOT;
|
||||
if (StringUtils.isNotBlank(folderId)) {
|
||||
folderPath = BASE_ROOT + folderId + "/";
|
||||
}
|
||||
|
||||
folderPath += Thread.currentThread().getId() + "/";
|
||||
FileUtils.validateExist(folderPath);
|
||||
File result = new File(folderPath + realFileName.get());
|
||||
FileOutputStream fos = new FileOutputStream(result);
|
||||
BufferedOutputStream outputStream = new BufferedOutputStream(fos);
|
||||
try {
|
||||
wb.write(outputStream);
|
||||
} catch (Exception e) {
|
||||
LogUtil.error(e.getMessage(), new Throwable(e));
|
||||
throw e;
|
||||
} finally {
|
||||
wb.close();
|
||||
outputStream.flush();
|
||||
outputStream.close();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user