表数据支持Excel格式导出
This commit is contained in:
@@ -1,24 +1,16 @@
|
|||||||
package com.zyplayer.doc.db.controller;
|
package com.zyplayer.doc.db.controller;
|
||||||
|
|
||||||
import cn.hutool.core.io.FileUtil;
|
|
||||||
import cn.hutool.core.util.IdUtil;
|
import cn.hutool.core.util.IdUtil;
|
||||||
import cn.hutool.core.util.RandomUtil;
|
|
||||||
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSON;
|
||||||
import com.alibaba.fastjson.JSONArray;
|
import com.alibaba.fastjson.JSONArray;
|
||||||
import com.alibaba.fastjson.serializer.SerializerFeature;
|
import com.alibaba.fastjson.serializer.SerializerFeature;
|
||||||
import com.alibaba.fastjson.util.TypeUtils;
|
import com.alibaba.fastjson.util.TypeUtils;
|
||||||
import com.zyplayer.doc.core.annotation.AuthMan;
|
import com.zyplayer.doc.core.annotation.AuthMan;
|
||||||
import com.zyplayer.doc.core.exception.ConfirmException;
|
|
||||||
import com.zyplayer.doc.core.json.ResponseJson;
|
import com.zyplayer.doc.core.json.ResponseJson;
|
||||||
import com.zyplayer.doc.core.util.StringUtil;
|
import com.zyplayer.doc.core.util.StringUtil;
|
||||||
import com.zyplayer.doc.data.config.security.DocUserUtil;
|
|
||||||
import com.zyplayer.doc.data.repository.support.consts.DocAuthConst;
|
|
||||||
import com.zyplayer.doc.db.controller.download.FormatDownloadConst;
|
import com.zyplayer.doc.db.controller.download.FormatDownloadConst;
|
||||||
import com.zyplayer.doc.db.controller.download.FormatDownloadService;
|
import com.zyplayer.doc.db.controller.download.FormatDownloadService;
|
||||||
import com.zyplayer.doc.db.controller.param.DataViewParam;
|
import com.zyplayer.doc.db.controller.param.DataViewParam;
|
||||||
import com.zyplayer.doc.db.controller.vo.TableColumnVo;
|
|
||||||
import com.zyplayer.doc.db.framework.consts.DbAuthType;
|
|
||||||
import com.zyplayer.doc.db.framework.db.dto.TableColumnDescDto;
|
|
||||||
import com.zyplayer.doc.db.framework.db.mapper.base.ExecuteParam;
|
import com.zyplayer.doc.db.framework.db.mapper.base.ExecuteParam;
|
||||||
import com.zyplayer.doc.db.framework.db.mapper.base.ExecuteResult;
|
import com.zyplayer.doc.db.framework.db.mapper.base.ExecuteResult;
|
||||||
import com.zyplayer.doc.db.framework.db.mapper.base.ExecuteType;
|
import com.zyplayer.doc.db.framework.db.mapper.base.ExecuteType;
|
||||||
@@ -41,8 +33,6 @@ import org.springframework.web.bind.annotation.RestController;
|
|||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 表数据查看控制器
|
* 表数据查看控制器
|
||||||
|
|||||||
@@ -0,0 +1,160 @@
|
|||||||
|
package com.zyplayer.doc.db.controller.download;
|
||||||
|
|
||||||
|
import cn.hutool.core.date.DateTime;
|
||||||
|
import cn.hutool.core.io.FileUtil;
|
||||||
|
import cn.hutool.core.util.IdUtil;
|
||||||
|
import com.alibaba.excel.EasyExcel;
|
||||||
|
import com.alibaba.excel.ExcelWriter;
|
||||||
|
import com.alibaba.excel.write.metadata.WriteSheet;
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import com.alibaba.fastjson.JSONObject;
|
||||||
|
import com.zyplayer.doc.db.controller.param.DataViewParam;
|
||||||
|
import com.zyplayer.doc.db.controller.vo.TableColumnVo;
|
||||||
|
import com.zyplayer.doc.db.framework.db.dto.TableColumnDescDto;
|
||||||
|
import com.zyplayer.doc.db.framework.db.mapper.base.ExecuteParam;
|
||||||
|
import com.zyplayer.doc.db.framework.db.mapper.base.ExecuteResult;
|
||||||
|
import com.zyplayer.doc.db.framework.db.mapper.base.ExecuteType;
|
||||||
|
import com.zyplayer.doc.db.framework.db.mapper.base.SqlExecutor;
|
||||||
|
import com.zyplayer.doc.db.service.common.ExecuteAuthService;
|
||||||
|
import com.zyplayer.doc.db.service.database.DatabaseServiceFactory;
|
||||||
|
import com.zyplayer.doc.db.service.database.DbBaseService;
|
||||||
|
import com.zyplayer.doc.db.service.download.BaseDownloadService;
|
||||||
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.io.File;
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* excel格式化数据下载服务
|
||||||
|
*
|
||||||
|
* @author 暮光:城中城
|
||||||
|
* @since 2021-08-14
|
||||||
|
*/
|
||||||
|
@Service(FormatDownloadConst.EXCEL)
|
||||||
|
public class ExcelFormatDownloadService implements FormatDownloadService {
|
||||||
|
private static Logger logger = LoggerFactory.getLogger(ExcelFormatDownloadService.class);
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
ExecuteAuthService executeAuthService;
|
||||||
|
@Resource
|
||||||
|
DatabaseServiceFactory databaseServiceFactory;
|
||||||
|
@Resource
|
||||||
|
BaseDownloadService baseDownloadService;
|
||||||
|
@Resource
|
||||||
|
SqlExecutor sqlExecutor;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void download(HttpServletResponse response, DataViewParam param, String[] tableNameArr) throws Exception {
|
||||||
|
DbBaseService dbBaseService = databaseServiceFactory.getDbBaseService(param.getSourceId());
|
||||||
|
boolean multipleFile = Objects.equals(param.getDownloadFileType(), 2);
|
||||||
|
JSONObject conditionMap = StringUtils.isBlank(param.getConditionJson()) ? new JSONObject() : JSON.parseObject(param.getConditionJson());
|
||||||
|
JSONObject conditionColumnMap = StringUtils.isBlank(param.getConditionColumnJson()) ? new JSONObject() : JSON.parseObject(param.getConditionColumnJson());
|
||||||
|
JSONObject getRetainColumnMap = StringUtils.isBlank(param.getRetainColumnJson()) ? new JSONObject() : JSON.parseObject(param.getRetainColumnJson());
|
||||||
|
// 结果
|
||||||
|
String tempDir = System.getProperty("java.io.tmpdir");
|
||||||
|
String tempDirName = tempDir + "zyplayer-doc-" + IdUtil.fastSimpleUUID();
|
||||||
|
ExcelWriter excelWriter = null;
|
||||||
|
boolean excelWriterIsFinish = false;
|
||||||
|
try {
|
||||||
|
String suffix = ".xlsx";
|
||||||
|
if (!multipleFile) {
|
||||||
|
response.setContentType("application/vnd.ms-excel");
|
||||||
|
response.setCharacterEncoding("utf-8");
|
||||||
|
String fileNameOrigin = "数据库表数据导出." + DateTime.now().toString("yyyyMMddHHmmss");
|
||||||
|
String fileName = URLEncoder.encode(fileNameOrigin, "UTF-8");
|
||||||
|
response.setHeader("Content-disposition", "attachment;filename=" + fileName + suffix);
|
||||||
|
excelWriter = EasyExcel.write(response.getOutputStream()).build();
|
||||||
|
}
|
||||||
|
// 创建临时文件夹
|
||||||
|
FileUtil.mkdir(tempDirName);
|
||||||
|
// 再分表查数据
|
||||||
|
int tableIndex = 0;
|
||||||
|
for (String tableName : tableNameArr) {
|
||||||
|
param.setTableName(tableName);
|
||||||
|
param.setCondition(conditionMap.getString(tableName));
|
||||||
|
param.setConditionColumn(conditionColumnMap.getString(tableName));
|
||||||
|
param.setRetainColumn(getRetainColumnMap.getString(tableName));
|
||||||
|
ExecuteType executeType = executeAuthService.getExecuteType(param.getSourceId());
|
||||||
|
// 获取列信息等
|
||||||
|
TableColumnVo tableColumnVo = dbBaseService.getTableColumnList(param.getSourceId(), param.getDbName(), tableName);
|
||||||
|
List<TableColumnDescDto> columnList = tableColumnVo.getColumnList();
|
||||||
|
// 保留的列
|
||||||
|
Set<String> retainColumnSet = StringUtils.isBlank(param.getRetainColumn()) ? Collections.emptySet() : Stream.of(param.getRetainColumn().split(",")).collect(Collectors.toSet());
|
||||||
|
List<TableColumnDescDto> columnListRetain = columnList.stream().filter(item -> retainColumnSet.isEmpty() || retainColumnSet.contains(item.getName())).collect(Collectors.toList());
|
||||||
|
// 数据查询
|
||||||
|
String queryAllSql = dbBaseService.getQueryAllSql(param);
|
||||||
|
ExecuteParam executeParam = new ExecuteParam();
|
||||||
|
executeParam.setDatasourceId(param.getSourceId());
|
||||||
|
executeParam.setExecuteId(param.getExecuteId());
|
||||||
|
executeParam.setExecuteType(executeType);
|
||||||
|
executeParam.setSql(queryAllSql);
|
||||||
|
ExecuteResult executeResult = sqlExecutor.execute(executeParam);
|
||||||
|
List<Map<String, Object>> executeResultData = executeResult.getResult();
|
||||||
|
if (CollectionUtils.isEmpty(executeResultData)) {
|
||||||
|
executeResultData = Collections.emptyList();
|
||||||
|
if (StringUtils.isNotBlank(executeResult.getErrMsg())) {
|
||||||
|
logger.error("执行sql失败:{}, {}", executeResult.getSql(), executeResult.getErrMsg());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 处理成表格下载所需格式
|
||||||
|
List<List<Object>> downloadDataList = new LinkedList<>();
|
||||||
|
for (Map<String, Object> dataMap : executeResultData) {
|
||||||
|
downloadDataList.add(new LinkedList<Object>() {{
|
||||||
|
for (TableColumnDescDto columnDto : columnListRetain) {
|
||||||
|
Object data = dataMap.get(columnDto.getName());
|
||||||
|
// 数据格式处理,不处理有些格式会造成乱码,打不开文件
|
||||||
|
if (!(data == null || data instanceof Number || data instanceof CharSequence)) {
|
||||||
|
if (data instanceof Timestamp) {
|
||||||
|
data = DateTime.of(((Timestamp) data).getTime()).toJdkDate();
|
||||||
|
} else {
|
||||||
|
data = String.valueOf(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
add(data);
|
||||||
|
}
|
||||||
|
}});
|
||||||
|
}
|
||||||
|
List<List<String>> sheetHeadList = this.getSheetHeadList(columnListRetain);
|
||||||
|
if (multipleFile) {
|
||||||
|
// 写入临时文件
|
||||||
|
File tempFile = FileUtil.file(tempDirName + "/" + tableName + suffix);
|
||||||
|
EasyExcel.write(tempFile).head(sheetHeadList).sheet(tableName).doWrite(downloadDataList);
|
||||||
|
} else {
|
||||||
|
WriteSheet writeSheet = EasyExcel.writerSheet(tableIndex++, tableName).head(sheetHeadList).build();
|
||||||
|
excelWriter.write(downloadDataList, writeSheet);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (multipleFile) {
|
||||||
|
baseDownloadService.sendResponse(response, param.getDbName(), tempDirName);
|
||||||
|
} else {
|
||||||
|
excelWriter.finish();
|
||||||
|
excelWriterIsFinish = true;
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
FileUtil.del(tempDirName);
|
||||||
|
if (excelWriterIsFinish && excelWriter != null) {
|
||||||
|
excelWriter.finish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<List<String>> getSheetHeadList(List<TableColumnDescDto> columnListRetain) {
|
||||||
|
List<List<String>> sheetHeadList = new ArrayList<>();
|
||||||
|
for (TableColumnDescDto dataCol : columnListRetain) {
|
||||||
|
sheetHeadList.add(new ArrayList<String>() {{
|
||||||
|
add(dataCol.getName());
|
||||||
|
}});
|
||||||
|
}
|
||||||
|
return sheetHeadList;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,6 +5,7 @@ import com.alibaba.fastjson.JSONObject;
|
|||||||
import com.zyplayer.doc.core.exception.ConfirmException;
|
import com.zyplayer.doc.core.exception.ConfirmException;
|
||||||
import com.zyplayer.doc.data.config.security.DocUserUtil;
|
import com.zyplayer.doc.data.config.security.DocUserUtil;
|
||||||
import com.zyplayer.doc.data.repository.support.consts.DocAuthConst;
|
import com.zyplayer.doc.data.repository.support.consts.DocAuthConst;
|
||||||
|
import com.zyplayer.doc.db.controller.download.FormatDownloadConst;
|
||||||
import com.zyplayer.doc.db.controller.param.DataViewParam;
|
import com.zyplayer.doc.db.controller.param.DataViewParam;
|
||||||
import com.zyplayer.doc.db.controller.param.ProcedureListParam;
|
import com.zyplayer.doc.db.controller.param.ProcedureListParam;
|
||||||
import com.zyplayer.doc.db.controller.vo.TableColumnVo;
|
import com.zyplayer.doc.db.controller.vo.TableColumnVo;
|
||||||
@@ -354,27 +355,6 @@ public abstract class DbBaseService {
|
|||||||
return sqlSb.toString();
|
return sqlSb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 导出单表数据
|
|
||||||
*
|
|
||||||
* @author 暮光:城中城
|
|
||||||
* @since 2020年6月5日
|
|
||||||
*/
|
|
||||||
public void downloadSingleTableData(HttpServletResponse response, DataViewParam param, ExecuteParam executeParam, List<TableColumnDescDto> dataCols, Set<String> conditionSet) throws Exception {
|
|
||||||
DatabaseProductEnum databaseProduct = databaseServiceFactory.getDbBaseService(param.getSourceId()).getDatabaseProduct();
|
|
||||||
DownloadService downloadService = databaseServiceFactory.getDownloadService(databaseProduct);
|
|
||||||
if (Objects.equals(param.getDownloadType(), "insert")) {
|
|
||||||
String resultStr = downloadService.downloadDataByInsert(param, executeParam, dataCols, conditionSet);
|
|
||||||
baseDownloadService.sendResponse(response, param.getTableName(), ".sql", resultStr);
|
|
||||||
} else if (Objects.equals(param.getDownloadType(), "update")) {
|
|
||||||
String resultStr = downloadService.downloadDataByUpdate(param, executeParam, dataCols, conditionSet);
|
|
||||||
baseDownloadService.sendResponse(response, param.getTableName(), ".sql", resultStr);
|
|
||||||
} else if (Objects.equals(param.getDownloadType(), "json")) {
|
|
||||||
String resultStr = downloadService.downloadDataByJson(param, executeParam, dataCols, conditionSet);
|
|
||||||
baseDownloadService.sendResponse(response, param.getTableName(), ".json", resultStr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取表数据
|
* 获取表数据
|
||||||
*
|
*
|
||||||
@@ -384,11 +364,11 @@ public abstract class DbBaseService {
|
|||||||
public String getDownloadTableData(DataViewParam param, ExecuteParam executeParam, List<TableColumnDescDto> dataCols, Set<String> conditionSet) throws Exception {
|
public String getDownloadTableData(DataViewParam param, ExecuteParam executeParam, List<TableColumnDescDto> dataCols, Set<String> conditionSet) throws Exception {
|
||||||
DatabaseProductEnum databaseProduct = databaseServiceFactory.getDbBaseService(param.getSourceId()).getDatabaseProduct();
|
DatabaseProductEnum databaseProduct = databaseServiceFactory.getDbBaseService(param.getSourceId()).getDatabaseProduct();
|
||||||
DownloadService downloadService = databaseServiceFactory.getDownloadService(databaseProduct);
|
DownloadService downloadService = databaseServiceFactory.getDownloadService(databaseProduct);
|
||||||
if (Objects.equals(param.getDownloadType(), "insert")) {
|
if (Objects.equals(param.getDownloadType(), FormatDownloadConst.INSERT)) {
|
||||||
return downloadService.downloadDataByInsert(param, executeParam, dataCols, conditionSet);
|
return downloadService.downloadDataByInsert(param, executeParam, dataCols, conditionSet);
|
||||||
} else if (Objects.equals(param.getDownloadType(), "update")) {
|
} else if (Objects.equals(param.getDownloadType(), FormatDownloadConst.UPDATE)) {
|
||||||
return downloadService.downloadDataByUpdate(param, executeParam, dataCols, conditionSet);
|
return downloadService.downloadDataByUpdate(param, executeParam, dataCols, conditionSet);
|
||||||
} else if (Objects.equals(param.getDownloadType(), "json")) {
|
} else if (Objects.equals(param.getDownloadType(), FormatDownloadConst.JSON)) {
|
||||||
return downloadService.downloadDataByJson(param, executeParam, dataCols, conditionSet);
|
return downloadService.downloadDataByJson(param, executeParam, dataCols, conditionSet);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -159,11 +159,7 @@ public class BaseDownloadService implements DownloadService {
|
|||||||
for (TableColumnDescDto dataCol : dataCols) {
|
for (TableColumnDescDto dataCol : dataCols) {
|
||||||
result.put(dataCol.getName(), item.get(dataCol.getName()));
|
result.put(dataCol.getName(), item.get(dataCol.getName()));
|
||||||
}
|
}
|
||||||
String resultData = result.toJSONString();
|
resultSb.append((resultSb.length() > 1) ? "," : "").append(result.toJSONString());
|
||||||
if (resultSb.length() > 1) {
|
|
||||||
resultSb.append(",");
|
|
||||||
}
|
|
||||||
resultSb.append(resultData);
|
|
||||||
});
|
});
|
||||||
resultSb.append("]\n");
|
resultSb.append("]\n");
|
||||||
return resultSb.toString();
|
return resultSb.toString();
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
<!DOCTYPE html><html lang=en><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1"><link rel=icon href=favicon-db.png><title>数据库文档管理</title><link href=css/chunk-vendors.8924efc6.css rel=preload as=style><link href=css/index.2a7107f3.css rel=preload as=style><link href=js/chunk-vendors.333ced1f.js rel=preload as=script><link href=js/index.ea0404ed.js rel=preload as=script><link href=css/chunk-vendors.8924efc6.css rel=stylesheet><link href=css/index.2a7107f3.css rel=stylesheet></head><body><noscript><strong>We're sorry but zyplayer-db-ui doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id=app></div><script src=js/chunk-vendors.333ced1f.js></script><script src=js/index.ea0404ed.js></script></body></html>
|
<!DOCTYPE html><html lang=en><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1"><link rel=icon href=favicon-db.png><title>数据库文档管理</title><link href=css/chunk-vendors.8924efc6.css rel=preload as=style><link href=css/index.2a7107f3.css rel=preload as=style><link href=js/chunk-vendors.333ced1f.js rel=preload as=script><link href=js/index.d7e1d74e.js rel=preload as=script><link href=css/chunk-vendors.8924efc6.css rel=stylesheet><link href=css/index.2a7107f3.css rel=stylesheet></head><body><noscript><strong>We're sorry but zyplayer-db-ui doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id=app></div><script src=js/chunk-vendors.333ced1f.js></script><script src=js/index.d7e1d74e.js></script></body></html>
|
||||||
1
zyplayer-doc-db/src/main/resources/dist/js/index.d7e1d74e.js
vendored
Normal file
1
zyplayer-doc-db/src/main/resources/dist/js/index.d7e1d74e.js
vendored
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -93,8 +93,7 @@
|
|||||||
<el-option label="SQL Inserts" value="insert"></el-option>
|
<el-option label="SQL Inserts" value="insert"></el-option>
|
||||||
<el-option label="SQL Updates" value="update"></el-option>
|
<el-option label="SQL Updates" value="update"></el-option>
|
||||||
<el-option label="JSON" value="json"></el-option>
|
<el-option label="JSON" value="json"></el-option>
|
||||||
<!-- <el-option label="Excel" value="excel"></el-option>-->
|
<el-option label="Excel" value="excel"></el-option>
|
||||||
<!-- <el-option label="CVS" value="cvs"></el-option>-->
|
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="数据表:" v-if="downloadDataParam.downloadType === 'insert'">
|
<el-form-item label="数据表:" v-if="downloadDataParam.downloadType === 'insert'">
|
||||||
|
|||||||
@@ -47,6 +47,7 @@
|
|||||||
<el-option label="SQL Inserts" value="insert"></el-option>
|
<el-option label="SQL Inserts" value="insert"></el-option>
|
||||||
<el-option label="SQL Updates" value="update"></el-option>
|
<el-option label="SQL Updates" value="update"></el-option>
|
||||||
<el-option label="JSON" value="json"></el-option>
|
<el-option label="JSON" value="json"></el-option>
|
||||||
|
<el-option label="Excel" value="excel"></el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="数据表:" v-if="downloadType === 'insert'">
|
<el-form-item label="数据表:" v-if="downloadType === 'insert'">
|
||||||
|
|||||||
Reference in New Issue
Block a user