导出库表支持建表语句的导出
This commit is contained in:
@@ -41,6 +41,7 @@ import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* 文档控制器
|
||||
@@ -251,44 +252,67 @@ public class DatabaseDocController {
|
||||
}
|
||||
|
||||
@PostMapping(value = "/exportDatabase")
|
||||
public ResponseJson exportDatabase(HttpServletResponse response, Long sourceId, String dbName, String tableNames, Integer exportType) {
|
||||
public ResponseJson exportDatabase(HttpServletResponse response, Long sourceId, String dbName, String tableNames, Integer exportType, Integer exportFormat) {
|
||||
this.judgeAuth(sourceId, DbAuthType.VIEW.getName(), "没有查看该库表信息的权限");
|
||||
if (StringUtils.isBlank(tableNames)) {
|
||||
return DocDbResponseJson.warn("请选择需要导出的表");
|
||||
}
|
||||
List<String> tableNameList = Stream.of(tableNames.split(",")).filter(StringUtils::isNotBlank).collect(Collectors.toList());
|
||||
if (Objects.equals(exportType, 1)) {
|
||||
return this.exportForTableDoc(response, sourceId, dbName, tableNameList, exportFormat);
|
||||
} else if (Objects.equals(exportType, 2)) {
|
||||
return this.exportForTableDdl(response, sourceId, dbName, tableNameList, exportFormat);
|
||||
}
|
||||
return DocDbResponseJson.ok();
|
||||
}
|
||||
|
||||
private DocDbResponseJson exportForTableDdl(HttpServletResponse response, Long sourceId, String dbName, List<String> tableNameList, Integer exportFormat) {
|
||||
BaseMapper baseMapper = this.getViewAuthBaseMapper(sourceId);
|
||||
DatabaseFactoryBean databaseFactoryBean = databaseRegistrationBean.getOrCreateFactoryById(sourceId);
|
||||
DatabaseProduct databaseProduct = databaseFactoryBean.getDatabaseProduct();
|
||||
Map<String, String> ddlSqlMap = new HashMap<>();
|
||||
for (String tableName : tableNameList) {
|
||||
Map<String, String> dataMap = baseMapper.getTableDdl(dbName, tableName);
|
||||
// 不同数据源类型获取方式不一致
|
||||
if (Objects.equals(DatabaseProduct.MYSQL, databaseProduct)) {
|
||||
ddlSqlMap.put(tableName, dataMap.get("Create Table"));
|
||||
}
|
||||
}
|
||||
try {
|
||||
PoiUtil.exportByDdl(ddlSqlMap, dbName, databaseProduct.name(), response);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return DocDbResponseJson.error("导出失败:" + e.getMessage());
|
||||
}
|
||||
return DocDbResponseJson.ok();
|
||||
}
|
||||
|
||||
private DocDbResponseJson exportForTableDoc(HttpServletResponse response, Long sourceId, String dbName, List<String> tableNameList, Integer exportFormat) {
|
||||
DatabaseFactoryBean databaseFactoryBean = databaseRegistrationBean.getOrCreateFactoryById(sourceId);
|
||||
if (databaseFactoryBean == null) {
|
||||
return DocDbResponseJson.warn("未找到对应的数据库连接");
|
||||
}
|
||||
List<TableInfoVo> tableList = new LinkedList<>();
|
||||
Map<String, List<TableColumnDescDto>> columnList = new HashMap<>();
|
||||
String[] tableNameArr = tableNames.split(",");
|
||||
for (String tableName : tableNameArr) {
|
||||
if (StringUtils.isBlank(tableName)) {
|
||||
continue;
|
||||
}
|
||||
for (String tableName : tableNameList) {
|
||||
TableColumnVo tableColumnVo = this.getTableColumnVo(databaseFactoryBean, dbName, tableName);
|
||||
columnList.put(tableName, tableColumnVo.getColumnList());
|
||||
tableList.add(tableColumnVo.getTableInfo());
|
||||
}
|
||||
DatabaseExportVo exportVo = new DatabaseExportVo();
|
||||
exportVo.setColumnList(columnList);
|
||||
exportVo.setTableList(tableList);
|
||||
try {
|
||||
if (Objects.equals(exportType, 1)) {
|
||||
DatabaseExportVo exportVo = new DatabaseExportVo(columnList, tableList);
|
||||
if (Objects.equals(exportFormat, 1)) {
|
||||
PoiUtil.exportByText(exportVo, response);
|
||||
} else if (Objects.equals(exportType, 2)) {
|
||||
} else if (Objects.equals(exportFormat, 2)) {
|
||||
PoiUtil.exportByXlsx(exportVo, response);
|
||||
} else if (Objects.equals(exportType, 3)) {
|
||||
} else if (Objects.equals(exportFormat, 3)) {
|
||||
PoiUtil.exportByDocx(dbName, exportVo, response);
|
||||
} else {
|
||||
return DocDbResponseJson.error("导出失败:请先选择导出类型");
|
||||
}
|
||||
return DocDbResponseJson.error("导出失败:请先选择导出类型");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return DocDbResponseJson.error("导出失败:" + e.getMessage());
|
||||
}
|
||||
return DocDbResponseJson.ok();
|
||||
}
|
||||
|
||||
private TableColumnVo getTableColumnVo(DatabaseFactoryBean databaseFactoryBean, String dbName, String tableName) {
|
||||
|
||||
@@ -11,7 +11,12 @@ public class DatabaseExportVo {
|
||||
private Map<String, List<TableColumnDescDto>> columnList;
|
||||
|
||||
private List<TableInfoVo> tableList;
|
||||
|
||||
|
||||
public DatabaseExportVo(Map<String, List<TableColumnDescDto>> columnList, List<TableInfoVo> tableList) {
|
||||
this.columnList = columnList;
|
||||
this.tableList = tableList;
|
||||
}
|
||||
|
||||
public Map<String, List<TableColumnDescDto>> getColumnList() {
|
||||
return columnList;
|
||||
}
|
||||
|
||||
@@ -70,7 +70,12 @@ public class DatasourceUtil {
|
||||
return null;
|
||||
}
|
||||
// 数据源配置
|
||||
DruidDataSource dataSource = DruidDataSourceUtil.createDataSource(dbDatasource.getDriverClassName(), dbDatasource.getSourceUrl(), dbDatasource.getSourceName(), dbDatasource.getSourcePassword(), breakAfterAcquireFailure);
|
||||
DruidDataSource dataSource = DruidDataSourceUtil.createDataSource(dbDatasource.getDriverClassName(), dbDatasource.getSourceUrl(), dbDatasource.getSourceName(), dbDatasource.getSourcePassword(), false);
|
||||
if (breakAfterAcquireFailure) {
|
||||
dataSource.close();
|
||||
// 先关闭会自动关闭的数据源,再创建一个会重连的
|
||||
dataSource = DruidDataSourceUtil.createDataSource(dbDatasource.getDriverClassName(), dbDatasource.getSourceUrl(), dbDatasource.getSourceName(), dbDatasource.getSourcePassword(), true);
|
||||
}
|
||||
// 创建sqlSessionTemplate
|
||||
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
|
||||
sqlSessionFactoryBean.setDataSource(dataSource);
|
||||
|
||||
@@ -31,6 +31,36 @@ import java.util.Map;
|
||||
*/
|
||||
public class PoiUtil {
|
||||
|
||||
/**
|
||||
* 导出为ddl
|
||||
*
|
||||
* @param ddlSqlMap
|
||||
* @param response
|
||||
* @throws Exception
|
||||
*/
|
||||
public static void exportByDdl(Map<String, String> ddlSqlMap, String dbName, String dbType, HttpServletResponse response) throws Exception {
|
||||
String fileName = URLEncoder.encode("建表语句导出", "UTF-8");
|
||||
response.setContentType("application/octet-stream");
|
||||
response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".sql");
|
||||
response.setCharacterEncoding("utf-8");
|
||||
// 将文件输入流写入response的输出流中
|
||||
StringBuilder ddlSqlSb = new StringBuilder("/*\n" +
|
||||
" zyplayer-doc-db 数据库建表语句导出\n" +
|
||||
"\n" +
|
||||
" 数据库 : " + dbName + "\n" +
|
||||
" 数据库类型 : " + dbType + "\n" +
|
||||
" 导出时间 : " + DateTime.now().toString() + "\n" +
|
||||
"*/\n\n");
|
||||
for (Map.Entry<String, String> entry : ddlSqlMap.entrySet()) {
|
||||
ddlSqlSb.append("-- ----------------------------\n")
|
||||
.append("-- 表结构:" + entry.getKey() + "\n")
|
||||
.append("-- ----------------------------\n")
|
||||
.append("DROP TABLE IF EXISTS `" + entry.getKey() + "`;\n")
|
||||
.append(entry.getValue()).append(";\n\n");
|
||||
}
|
||||
IoUtil.write(response.getOutputStream(), "utf-8", true, ddlSqlSb.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出为Text
|
||||
*
|
||||
|
||||
1
zyplayer-doc-db/src/main/resources/css/app.1c916a62.css
Normal file
1
zyplayer-doc-db/src/main/resources/css/app.1c916a62.css
Normal file
@@ -0,0 +1 @@
|
||||
#app,.el-container,.el-menu{height:100%}.el-header{background-color:#1d4e89!important}.database-list-tree{background-color:#fafafa}.database-list-tree .el-tree-node>.el-tree-node__children{overflow:unset}.el-tree-node__content .el-icon-more{margin-left:5px;color:#606266;font-size:12px;display:none;padding:2px 5px}.el-tree-node__content:hover .el-icon-more{display:inline-block}.login-container{border-radius:5px;-moz-border-radius:5px;background-clip:padding-box;margin:0 auto;width:350px;padding:35px 35px 15px 35px;background:#fff;border:1px solid #eaeaea;-webkit-box-shadow:0 0 25px #cac6c6;box-shadow:0 0 25px #cac6c6}.title{margin:0 auto 40px auto;text-align:center;color:#505458}.remember{margin:0 0 35px 0}.my-info-vue .box-card{margin:10px}.table-info-vue .el-dialog__body{padding:0 20px 10px}.table-info-vue .el-form-item{margin-bottom:5px}.table-info-vue .edit-table-desc{cursor:pointer;color:#409eff}.table-info-vue .description{cursor:pointer;min-height:23px}.table-info-vue .el-table td,.table-info-vue .el-table th{padding:5px 0}.table-info-vue .status-info-row{padding:8px 0}.table-info-vue .status-info-row .label{width:80px;display:inline-block;text-align:right;color:#606266}.table-database-vue .el-table td,.table-database-vue .el-table th{padding:5px 0}body,html{margin:0;padding:0;height:100%}.header-right-user-name{color:#fff;padding-right:5px}.el-menu-vertical{border-right:0}.el-menu-vertical,.el-menu-vertical .el-menu{background:#fafafa}.el-header{background-color:#409eff;color:#333;line-height:40px;text-align:right;height:40px!important}.data-transfer-vue .el-button+.el-button{margin-left:4px}.data-executor-vue .ace-monokai .ace_print-margin{display:none}.data-executor-vue .el-card__body{padding:10px}.data-executor-vue .el-table td,.el-table th{padding:6px 0}.data-executor-vue .execute-result-table .el-input__inner{height:25px;line-height:25px;padding:0 5px}.data-executor-vue .execute-result-table .el-textarea__inner{height:27px;min-height:27px;line-height:25px;padding:0 5px;resize:none}.data-executor-vue .execute-use-time{font-size:12px;margin-right:10px}.data-executor-vue-out .el-tabs__nav-scroll{padding-left:20px}.data-executor-vue-out .el-button+.el-button{margin-left:0}.data-executor-vue-out .el-table__body-wrapper{height:calc(100vh - 180px);overflow-y:auto}
|
||||
@@ -1 +0,0 @@
|
||||
#app,.el-container,.el-menu{height:100%}.el-header{background-color:#1d4e89!important}.database-list-tree{background-color:#fafafa}.database-list-tree .el-tree-node>.el-tree-node__children{overflow:unset}.login-container{border-radius:5px;-moz-border-radius:5px;background-clip:padding-box;margin:0 auto;width:350px;padding:35px 35px 15px 35px;background:#fff;border:1px solid #eaeaea;-webkit-box-shadow:0 0 25px #cac6c6;box-shadow:0 0 25px #cac6c6}.title{margin:0 auto 40px auto;text-align:center;color:#505458}.remember{margin:0 0 35px 0}.my-info-vue .box-card{margin:10px}.table-info-vue .el-dialog__body{padding:0 20px 10px}.table-info-vue .el-form-item{margin-bottom:5px}.table-info-vue .edit-table-desc{cursor:pointer;color:#409eff}.table-info-vue .description{cursor:pointer;min-height:23px}.table-info-vue .el-table td,.table-info-vue .el-table th{padding:5px 0}.table-info-vue .status-info-row{padding:8px 0}.table-info-vue .status-info-row .label{width:80px;display:inline-block;text-align:right;color:#606266}.table-database-vue .el-table td,.table-database-vue .el-table th{padding:5px 0}body,html{margin:0;padding:0;height:100%}.header-right-user-name{color:#fff;padding-right:5px}.el-menu-vertical{border-right:0}.el-menu-vertical,.el-menu-vertical .el-menu{background:#fafafa}.el-header{background-color:#409eff;color:#333;line-height:40px;text-align:right;height:40px!important}.data-transfer-vue .el-button+.el-button{margin-left:4px}.data-executor-vue .ace-monokai .ace_print-margin{display:none}.data-executor-vue .el-card__body{padding:10px}.data-executor-vue .el-table td,.el-table th{padding:6px 0}.data-executor-vue .execute-result-table .el-input__inner{height:25px;line-height:25px;padding:0 5px}.data-executor-vue .execute-result-table .el-textarea__inner{height:27px;min-height:27px;line-height:25px;padding:0 5px;resize:none}.data-executor-vue .execute-use-time{font-size:12px;margin-right:10px}.data-executor-vue-out .el-tabs__nav-scroll{padding-left:20px}.data-executor-vue-out .el-button+.el-button{margin-left:0}.data-executor-vue-out .el-table__body-wrapper{height:calc(100vh - 180px);overflow-y:auto}
|
||||
@@ -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/app.4dd952a3.css rel=preload as=style><link href=css/chunk-vendors.7be40bfc.css rel=preload as=style><link href=js/app.9526be3d.js rel=preload as=script><link href=js/chunk-vendors.d5f91a49.js rel=preload as=script><link href=css/chunk-vendors.7be40bfc.css rel=stylesheet><link href=css/app.4dd952a3.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.d5f91a49.js></script><script src=js/app.9526be3d.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/app.1c916a62.css rel=preload as=style><link href=css/chunk-vendors.7be40bfc.css rel=preload as=style><link href=js/app.00132097.js rel=preload as=script><link href=js/chunk-vendors.d5f91a49.js rel=preload as=script><link href=css/chunk-vendors.7be40bfc.css rel=stylesheet><link href=css/app.1c916a62.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.d5f91a49.js></script><script src=js/app.00132097.js></script></body></html>
|
||||
File diff suppressed because one or more lines are too long
@@ -11,13 +11,7 @@
|
||||
<el-select v-model="choiceDatabase" @change="databaseChangeEvents" filterable placeholder="请选择数据库" style="margin: 0 10px;">
|
||||
<el-option v-for="item in databaseList" :key="item.dbName" :label="item.dbName" :value="item.dbName"></el-option>
|
||||
</el-select>
|
||||
<el-radio-group v-model="exportType">
|
||||
<el-radio :label="1">HTML格式</el-radio>
|
||||
<el-radio :label="2">Excel格式</el-radio>
|
||||
<el-radio :label="3">Word格式</el-radio>
|
||||
<el-radio :label="4">表结构</el-radio>
|
||||
</el-radio-group>
|
||||
<el-button v-on:click="exportChoiceTable" type="primary" style="margin: 0 10px 0 20px;">导出选中的表</el-button>
|
||||
<el-button v-on:click="showExportTypeChoice" type="primary" style="margin: 0 10px 0 20px;">导出选中的表</el-button>
|
||||
<a target="_blank" title="点击查看如何使用" href="http://doc.zyplayer.com/zyplayer-doc-manage/doc-wiki#/page/share/view?pageId=117&space=23f3f59a60824d21af9f7c3bbc9bc3cb"><i class="el-icon-info" style="color: #999;"></i></a>
|
||||
</div>
|
||||
<el-table :data="tableList" stripe border @selection-change="handleSelectionChange" style="width: 100%; margin-bottom: 5px;">
|
||||
@@ -29,13 +23,40 @@
|
||||
<form method="post" ref="downloadForm" :action="downloadFormParam.url" target="_blank">
|
||||
<input type="hidden" :name="key" :value="val" v-for="(val,key) in downloadFormParam.param">
|
||||
</form>
|
||||
<!--导出选项弹窗-->
|
||||
<el-dialog :visible.sync="exportTypeChoiceVisible" width="500px">
|
||||
<span slot="title">库表导出选项</span>
|
||||
<el-form label-width="120px">
|
||||
<el-form-item label="导出类型:">
|
||||
<el-radio-group v-model="exportType" @change="exportTypeChange">
|
||||
<el-radio :label="1">表结构文档</el-radio>
|
||||
<el-radio :label="2">建表语句SQL</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="导出格式:" v-if="exportType == 1">
|
||||
<el-radio-group v-model="exportFormat">
|
||||
<el-radio :label="1">HTML格式</el-radio>
|
||||
<el-radio :label="2">Excel格式</el-radio>
|
||||
<el-radio :label="3">Word格式</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item label="导出格式:" v-else-if="exportType == 2">
|
||||
<el-radio-group v-model="exportFormat">
|
||||
<el-radio :label="1">SQL格式</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="exportTypeChoiceVisible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="doExport">确 定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import datasourceApi from '../../common/api/datasource'
|
||||
|
||||
var app;
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
@@ -46,6 +67,8 @@
|
||||
choiceDatabase: "",
|
||||
choiceTable: "",
|
||||
exportType: 1,
|
||||
exportFormat: 1,
|
||||
exportTypeChoiceVisible: false,
|
||||
// 页面展示相关
|
||||
nowDatasourceShow: {},
|
||||
databaseList: [],
|
||||
@@ -58,20 +81,26 @@
|
||||
}
|
||||
},
|
||||
mounted: function () {
|
||||
app = this;
|
||||
this.loadDatasourceList();
|
||||
},
|
||||
methods: {
|
||||
datasourceChangeEvents() {
|
||||
app.nowDatasourceShow = this.choiceDatasourceId;
|
||||
app.loadDatabaseList(this.choiceDatasourceId);
|
||||
this.nowDatasourceShow = this.choiceDatasourceId;
|
||||
this.loadDatabaseList(this.choiceDatasourceId);
|
||||
},
|
||||
databaseChangeEvents() {
|
||||
app.loadGetTableList();
|
||||
this.loadGetTableList();
|
||||
},
|
||||
exportChoiceTable() {
|
||||
if (this.selectTables.length <= 0) {
|
||||
app.$message.info("请选择需要导出的表");
|
||||
exportTypeChange() {
|
||||
this.exportFormat = '';
|
||||
},
|
||||
doExport() {
|
||||
if (!this.exportType) {
|
||||
this.$message.info("请选择导出类型");
|
||||
return;
|
||||
}
|
||||
if (!this.exportFormat) {
|
||||
this.$message.info("请选择导出格式");
|
||||
return;
|
||||
}
|
||||
let tableNames = "";
|
||||
@@ -89,11 +118,19 @@
|
||||
this.downloadFormParam.param = {
|
||||
sourceId: this.choiceDatasourceId,
|
||||
exportType: this.exportType,
|
||||
exportFormat: this.exportFormat,
|
||||
dbName: this.choiceDatabase,
|
||||
tableNames: tableNames,
|
||||
};
|
||||
setTimeout(() => this.$refs.downloadForm.submit(), 0);
|
||||
},
|
||||
showExportTypeChoice() {
|
||||
if (this.selectTables.length <= 0) {
|
||||
this.$message.info("请选择需要导出的表");
|
||||
return;
|
||||
}
|
||||
this.exportTypeChoiceVisible = true;
|
||||
},
|
||||
loadGetTableList() {
|
||||
datasourceApi.tableList({sourceId: this.choiceDatasourceId, dbName: this.choiceDatabase}).then(json => {
|
||||
this.tableList = json.data || [];
|
||||
|
||||
Reference in New Issue
Block a user