forked from github/dataease
Merge pull request #4175 from dataease/pr@dev@perf_mark_map_export_excel
perf(地图): 导出excel合并单元格
This commit is contained in:
commit
65559d155e
@ -20,7 +20,7 @@ public class PanelViewDetailsRequest {
|
|||||||
|
|
||||||
private Integer[] excelTypes;
|
private Integer[] excelTypes;
|
||||||
|
|
||||||
private List<String[]> details;
|
private List<Object[]> details;
|
||||||
|
|
||||||
private String snapshot;
|
private String snapshot;
|
||||||
|
|
||||||
@ -28,6 +28,6 @@ public class PanelViewDetailsRequest {
|
|||||||
|
|
||||||
private int snapshotHeight;
|
private int snapshotHeight;
|
||||||
|
|
||||||
|
private ViewDetailField[] detailFields;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,15 @@
|
|||||||
|
package io.dataease.controller.request.panel;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class ViewDetailField implements Serializable {
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
private String dataeaseName;
|
||||||
|
|
||||||
|
private Integer deType;
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
package io.dataease.service.panel;
|
package io.dataease.service.panel;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.ArrayUtil;
|
||||||
import com.alibaba.fastjson.JSONArray;
|
import com.alibaba.fastjson.JSONArray;
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
@ -42,6 +43,7 @@ import org.apache.commons.lang3.StringUtils;
|
|||||||
import org.apache.poi.hssf.usermodel.HSSFClientAnchor;
|
import org.apache.poi.hssf.usermodel.HSSFClientAnchor;
|
||||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||||
import org.apache.poi.ss.usermodel.*;
|
import org.apache.poi.ss.usermodel.*;
|
||||||
|
import org.apache.poi.ss.util.CellRangeAddress;
|
||||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||||
import org.pentaho.di.core.util.UUIDUtil;
|
import org.pentaho.di.core.util.UUIDUtil;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@ -642,13 +644,15 @@ public class PanelGroupService {
|
|||||||
OutputStream outputStream = response.getOutputStream();
|
OutputStream outputStream = response.getOutputStream();
|
||||||
try {
|
try {
|
||||||
String snapshot = request.getSnapshot();
|
String snapshot = request.getSnapshot();
|
||||||
List<String[]> details = request.getDetails();
|
List<Object[]> details = request.getDetails();
|
||||||
Integer[] excelTypes = request.getExcelTypes();
|
Integer[] excelTypes = request.getExcelTypes();
|
||||||
details.add(0, request.getHeader());
|
details.add(0, request.getHeader());
|
||||||
|
|
||||||
Workbook wb = new XSSFWorkbook();
|
Workbook wb = new XSSFWorkbook();
|
||||||
//明细sheet
|
//明细sheet
|
||||||
Sheet detailsSheet = wb.createSheet("数据");
|
Sheet detailsSheet = wb.createSheet("数据");
|
||||||
|
|
||||||
|
|
||||||
//给单元格设置样式
|
//给单元格设置样式
|
||||||
CellStyle cellStyle = wb.createCellStyle();
|
CellStyle cellStyle = wb.createCellStyle();
|
||||||
Font font = wb.createFont();
|
Font font = wb.createFont();
|
||||||
@ -663,30 +667,104 @@ public class PanelGroupService {
|
|||||||
//设置单元格填充样式(使用纯色背景颜色填充)
|
//设置单元格填充样式(使用纯色背景颜色填充)
|
||||||
cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
|
cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
|
||||||
|
|
||||||
if (CollectionUtils.isNotEmpty(details)) {
|
|
||||||
for (int i = 0; i < details.size(); i++) {
|
Boolean mergeHead = false;
|
||||||
Row row = detailsSheet.createRow(i);
|
ViewDetailField[] detailFields = request.getDetailFields();
|
||||||
String[] rowData = details.get(i);
|
if (ArrayUtil.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) {
|
if (rowData != null) {
|
||||||
for (int j = 0; j < rowData.length; j++) {
|
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);
|
Cell cell = row.createCell(j);
|
||||||
if (i == 0) {// 头部
|
if (i == 0) {// 头部
|
||||||
cell.setCellValue(rowData[j]);
|
cell.setCellValue(cellValObj.toString());
|
||||||
cell.setCellStyle(cellStyle);
|
cell.setCellStyle(cellStyle);
|
||||||
//设置列的宽度
|
//设置列的宽度
|
||||||
detailsSheet.setColumnWidth(j, 255 * 20);
|
detailsSheet.setColumnWidth(j, 255 * 20);
|
||||||
} else {
|
} else {
|
||||||
// with DataType
|
// with DataType
|
||||||
if ((excelTypes[j] == DeTypeConstants.DE_INT || excelTypes[j] == DeTypeConstants.DE_FLOAT) && StringUtils.isNotEmpty(rowData[j])) {
|
if ((excelTypes[j] == DeTypeConstants.DE_INT || excelTypes[j] == DeTypeConstants.DE_FLOAT) && StringUtils.isNotEmpty(cellValObj.toString())) {
|
||||||
try {
|
try {
|
||||||
cell.setCellValue(Double.valueOf(rowData[j]));
|
cell.setCellValue(Double.valueOf(cellValObj.toString()));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LogUtil.warn("export excel data transform error");
|
LogUtil.warn("export excel data transform error");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
cell.setCellValue(rowData[j]);
|
cell.setCellValue(cellValObj.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -250,8 +250,32 @@ export default {
|
|||||||
const excelHeader = JSON.parse(JSON.stringify(this.chart.data.fields)).map(item => item.name)
|
const excelHeader = JSON.parse(JSON.stringify(this.chart.data.fields)).map(item => item.name)
|
||||||
const excelTypes = JSON.parse(JSON.stringify(this.chart.data.fields)).map(item => item.deType)
|
const excelTypes = JSON.parse(JSON.stringify(this.chart.data.fields)).map(item => item.deType)
|
||||||
const excelHeaderKeys = JSON.parse(JSON.stringify(this.chart.data.fields)).map(item => item.dataeaseName)
|
const excelHeaderKeys = JSON.parse(JSON.stringify(this.chart.data.fields)).map(item => item.dataeaseName)
|
||||||
const excelData = JSON.parse(JSON.stringify(this.chart.data.tableRow)).map(item => excelHeaderKeys.map(i => item[i]))
|
let excelData = JSON.parse(JSON.stringify(this.chart.data.tableRow)).map(item => excelHeaderKeys.map(i => item[i]))
|
||||||
const excelName = this.chart.name
|
const excelName = this.chart.name
|
||||||
|
let detailFields = []
|
||||||
|
if (this.chart.data.detailFields?.length) {
|
||||||
|
detailFields = this.chart.data.detailFields.map(item => {
|
||||||
|
const temp = {
|
||||||
|
name: item.name,
|
||||||
|
deType: item.deType,
|
||||||
|
dataeaseName: item.dataeaseName
|
||||||
|
}
|
||||||
|
return temp
|
||||||
|
})
|
||||||
|
excelData = JSON.parse(JSON.stringify(this.chart.data.tableRow)).map(item => {
|
||||||
|
const temp = excelHeaderKeys.map(i => {
|
||||||
|
if (i === 'detail' && !item[i] && Array.isArray(item['details'])) {
|
||||||
|
const arr = item['details']
|
||||||
|
if (arr?.length) {
|
||||||
|
return arr.map(ele => detailFields.map(field => ele[field.dataeaseName]))
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
return item[i]
|
||||||
|
})
|
||||||
|
return temp
|
||||||
|
})
|
||||||
|
}
|
||||||
const request = {
|
const request = {
|
||||||
viewId: this.chart.id,
|
viewId: this.chart.id,
|
||||||
viewName: excelName,
|
viewName: excelName,
|
||||||
@ -260,7 +284,8 @@ export default {
|
|||||||
excelTypes: excelTypes,
|
excelTypes: excelTypes,
|
||||||
snapshot: snapshot,
|
snapshot: snapshot,
|
||||||
snapshotWidth: width,
|
snapshotWidth: width,
|
||||||
snapshotHeight: height
|
snapshotHeight: height,
|
||||||
|
detailFields
|
||||||
}
|
}
|
||||||
let method = innerExportDetails
|
let method = innerExportDetails
|
||||||
const token = this.$store.getters.token || getToken()
|
const token = this.$store.getters.token || getToken()
|
||||||
|
Loading…
Reference in New Issue
Block a user