Commit 2fcb54b57661a935cbe650610e31929e4af9dbfd

Authored by YunaiV
1 parent 84ca9222

增加数据库文档的 html、word、markdown 的导出

ruoyi-ui/src/api/infra/dbDoc.js
@@ -8,3 +8,19 @@ export function exportHtml() { @@ -8,3 +8,19 @@ export function exportHtml() {
8 responseType: 'blob' 8 responseType: 'blob'
9 }) 9 })
10 } 10 }
  11 +
  12 +export function exportWord() {
  13 + return request({
  14 + url: '/infra/db-doc/export-word',
  15 + method: 'get',
  16 + responseType: 'blob'
  17 + })
  18 +}
  19 +
  20 +export function exportMarkdown() {
  21 + return request({
  22 + url: '/infra/db-doc/export-markdown',
  23 + method: 'get',
  24 + responseType: 'blob'
  25 + })
  26 +}
ruoyi-ui/src/main.js
@@ -25,7 +25,10 @@ import { @@ -25,7 +25,10 @@ import {
25 download, 25 download,
26 handleTree, 26 handleTree,
27 downloadExcel, 27 downloadExcel,
28 - downloadZip 28 + downloadWord,
  29 + downloadZip,
  30 + downloadHtml,
  31 + downloadMarkdown,
29 } from "@/utils/ruoyi"; 32 } from "@/utils/ruoyi";
30 import Pagination from "@/components/Pagination"; 33 import Pagination from "@/components/Pagination";
31 // 自定义表格工具扩展 34 // 自定义表格工具扩展
@@ -48,6 +51,9 @@ Vue.prototype.getDictDataLabel = getDictDataLabel @@ -48,6 +51,9 @@ Vue.prototype.getDictDataLabel = getDictDataLabel
48 Vue.prototype.DICT_TYPE = DICT_TYPE 51 Vue.prototype.DICT_TYPE = DICT_TYPE
49 Vue.prototype.download = download 52 Vue.prototype.download = download
50 Vue.prototype.downloadExcel = downloadExcel 53 Vue.prototype.downloadExcel = downloadExcel
  54 +Vue.prototype.downloadWord = downloadWord
  55 +Vue.prototype.downloadHtml = downloadHtml
  56 +Vue.prototype.downloadMarkdown = downloadMarkdown
51 Vue.prototype.downloadZip = downloadZip 57 Vue.prototype.downloadZip = downloadZip
52 Vue.prototype.handleTree = handleTree 58 Vue.prototype.handleTree = handleTree
53 59
ruoyi-ui/src/utils/ruoyi.js
@@ -120,11 +120,26 @@ export function downloadExcel(data, fileName) { @@ -120,11 +120,26 @@ export function downloadExcel(data, fileName) {
120 download0(data, fileName, 'application/vnd.ms-excel'); 120 download0(data, fileName, 'application/vnd.ms-excel');
121 } 121 }
122 122
  123 +// 下载 Word 方法
  124 +export function downloadWord(data, fileName) {
  125 + download0(data, fileName, 'application/msword');
  126 +}
  127 +
123 // 下载 Zip 方法 128 // 下载 Zip 方法
124 export function downloadZip(data, fileName) { 129 export function downloadZip(data, fileName) {
125 download0(data, fileName, 'application/zip'); 130 download0(data, fileName, 'application/zip');
126 } 131 }
127 132
  133 +// 下载 Html 方法
  134 +export function downloadHtml(data, fileName) {
  135 + download0(data, fileName, 'text/html');
  136 +}
  137 +
  138 +// 下载 Markdown 方法
  139 +export function downloadMarkdown(data, fileName) {
  140 + download0(data, fileName, 'text/markdown');
  141 +}
  142 +
128 function download0(data, fileName, mineType) { 143 function download0(data, fileName, mineType) {
129 // 创建 blob 144 // 创建 blob
130 let blob = new Blob([data], {type: mineType}); 145 let blob = new Blob([data], {type: mineType});
ruoyi-ui/src/views/tool/dbDoc/index.vue
1 <template> 1 <template>
2 - <div v-loading="loading" :style="'height:'+ height">  
3 - <iframe :src="src" frameborder="no" style="width: 100%;height: 100%" scrolling="auto" /> 2 + <div class="app-container">
  3 + <el-row :gutter="10" class="mb8">
  4 + <el-col :span="1.5">
  5 + <el-button type="primary" icon="el-icon-plus" size="mini" @click="handleExportHtml">导出 HTML</el-button>
  6 + <el-button type="primary" icon="el-icon-plus" size="mini" @click="handleExportWord">导出 Word</el-button>
  7 + <el-button type="primary" icon="el-icon-plus" size="mini" @click="handleExportMarkdown">导出 Markdown</el-button>
  8 + </el-col>
  9 + </el-row>
  10 +
  11 + <!-- 展示文档 -->
  12 + <div v-loading="loading" :style="'height:'+ height">
  13 + <iframe :src="src" frameborder="no" style="width: 100%;height: 100%" scrolling="auto" />
  14 + </div>
4 </div> 15 </div>
5 </template> 16 </template>
6 <script> 17 <script>
7 -import {exportHtml} from "@/api/infra/dbDoc"; 18 +import { exportHtml, exportWord, exportMarkdown} from "@/api/infra/dbDoc";
8 19
9 export default { 20 export default {
10 name: "DBDoc", 21 name: "DBDoc",
@@ -25,10 +36,31 @@ export default { @@ -25,10 +36,31 @@ export default {
25 }; 36 };
26 }, 37 },
27 created() { 38 created() {
  39 + // 加载 Html,进行预览
28 exportHtml().then(response => { 40 exportHtml().then(response => {
29 - // var blob = new Blob(['<a id="a"><b id="b">hey!</b></a>'], {type : 'text/html'});  
30 - this.src = window.URL.createObjectURL(response); 41 + let blob = new Blob([response], {type : 'text/html'});
  42 + this.src = window.URL.createObjectURL(blob);
31 }) 43 })
32 }, 44 },
  45 + methods: {
  46 + /** 处理导出 HTML */
  47 + handleExportHtml() {
  48 + exportHtml().then(response => {
  49 + this.downloadHtml(response, '数据库文档.html');
  50 + })
  51 + },
  52 + /** 处理导出 Word */
  53 + handleExportWord() {
  54 + exportWord().then(response => {
  55 + this.downloadWord(response, '数据库文档.doc');
  56 + })
  57 + },
  58 + /** 处理导出 Markdown */
  59 + handleExportMarkdown() {
  60 + exportMarkdown().then(response => {
  61 + this.downloadMarkdown(response, '数据库文档.md');
  62 + })
  63 + }
  64 + }
33 }; 65 };
34 </script> 66 </script>
src/main/java/cn/iocoder/dashboard/modules/infra/controller/doc/InfDbDocController.java
1 package cn.iocoder.dashboard.modules.infra.controller.doc; 1 package cn.iocoder.dashboard.modules.infra.controller.doc;
2 2
3 import cn.hutool.core.io.FileUtil; 3 import cn.hutool.core.io.FileUtil;
4 -import cn.hutool.core.io.IoUtil;  
5 -import cn.hutool.core.lang.UUID;  
6 import cn.hutool.core.util.IdUtil; 4 import cn.hutool.core.util.IdUtil;
7 -import cn.hutool.extra.servlet.ServletUtil;  
8 import cn.iocoder.dashboard.util.servlet.ServletUtils; 5 import cn.iocoder.dashboard.util.servlet.ServletUtils;
9 import cn.smallbun.screw.core.Configuration; 6 import cn.smallbun.screw.core.Configuration;
10 import cn.smallbun.screw.core.engine.EngineConfig; 7 import cn.smallbun.screw.core.engine.EngineConfig;
@@ -16,11 +13,8 @@ import com.zaxxer.hikari.HikariConfig; @@ -16,11 +13,8 @@ import com.zaxxer.hikari.HikariConfig;
16 import com.zaxxer.hikari.HikariDataSource; 13 import com.zaxxer.hikari.HikariDataSource;
17 import io.swagger.annotations.Api; 14 import io.swagger.annotations.Api;
18 import io.swagger.annotations.ApiImplicitParam; 15 import io.swagger.annotations.ApiImplicitParam;
19 -import io.swagger.annotations.ApiImplicitParams;  
20 import io.swagger.annotations.ApiOperation; 16 import io.swagger.annotations.ApiOperation;
21 import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties; 17 import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
22 -import org.springframework.http.MediaType;  
23 -import org.springframework.util.StreamUtils;  
24 import org.springframework.web.bind.annotation.GetMapping; 18 import org.springframework.web.bind.annotation.GetMapping;
25 import org.springframework.web.bind.annotation.RequestMapping; 19 import org.springframework.web.bind.annotation.RequestMapping;
26 import org.springframework.web.bind.annotation.RequestParam; 20 import org.springframework.web.bind.annotation.RequestParam;
@@ -28,7 +22,8 @@ import org.springframework.web.bind.annotation.RestController; @@ -28,7 +22,8 @@ import org.springframework.web.bind.annotation.RestController;
28 22
29 import javax.annotation.Resource; 23 import javax.annotation.Resource;
30 import javax.servlet.http.HttpServletResponse; 24 import javax.servlet.http.HttpServletResponse;
31 -import java.io.*; 25 +import java.io.File;
  26 +import java.io.IOException;
32 import java.util.Collections; 27 import java.util.Collections;
33 28
34 @Api(tags = "数据库文档") 29 @Api(tags = "数据库文档")
@@ -45,9 +40,8 @@ public class InfDbDocController { @@ -45,9 +40,8 @@ public class InfDbDocController {
45 private static final String DOC_VERSION = "1.0.0"; 40 private static final String DOC_VERSION = "1.0.0";
46 private static final String DOC_DESCRIPTION = "文档描述"; 41 private static final String DOC_DESCRIPTION = "文档描述";
47 42
48 -  
49 @GetMapping("/export-html") 43 @GetMapping("/export-html")
50 - @ApiOperation("导出html格式的数据文档") 44 + @ApiOperation("导出 html 格式的数据文档")
51 @ApiImplicitParam(name = "deleteFile", value = "是否删除在服务器本地生成的数据库文档", example = "true", dataTypeClass = Boolean.class) 45 @ApiImplicitParam(name = "deleteFile", value = "是否删除在服务器本地生成的数据库文档", example = "true", dataTypeClass = Boolean.class)
52 public void exportHtml(@RequestParam(defaultValue = "true") Boolean deleteFile, 46 public void exportHtml(@RequestParam(defaultValue = "true") Boolean deleteFile,
53 HttpServletResponse response) throws IOException { 47 HttpServletResponse response) throws IOException {
@@ -55,7 +49,7 @@ public class InfDbDocController { @@ -55,7 +49,7 @@ public class InfDbDocController {
55 } 49 }
56 50
57 @GetMapping("/export-word") 51 @GetMapping("/export-word")
58 - @ApiOperation("导出word格式的数据文档") 52 + @ApiOperation("导出 word 格式的数据文档")
59 @ApiImplicitParam(name = "deleteFile", value = "是否删除在服务器本地生成的数据库文档", example = "true", dataTypeClass = Boolean.class) 53 @ApiImplicitParam(name = "deleteFile", value = "是否删除在服务器本地生成的数据库文档", example = "true", dataTypeClass = Boolean.class)
60 public void exportWord(@RequestParam(defaultValue = "true") Boolean deleteFile, 54 public void exportWord(@RequestParam(defaultValue = "true") Boolean deleteFile,
61 HttpServletResponse response) throws IOException { 55 HttpServletResponse response) throws IOException {
@@ -63,7 +57,7 @@ public class InfDbDocController { @@ -63,7 +57,7 @@ public class InfDbDocController {
63 } 57 }
64 58
65 @GetMapping("/export-markdown") 59 @GetMapping("/export-markdown")
66 - @ApiOperation("导出markdown格式的数据文档") 60 + @ApiOperation("导出 markdown 格式的数据文档")
67 @ApiImplicitParam(name = "deleteFile", value = "是否删除在服务器本地生成的数据库文档", example = "true", dataTypeClass = Boolean.class) 61 @ApiImplicitParam(name = "deleteFile", value = "是否删除在服务器本地生成的数据库文档", example = "true", dataTypeClass = Boolean.class)
68 public void exportMarkdown(@RequestParam(defaultValue = "true") Boolean deleteFile, 62 public void exportMarkdown(@RequestParam(defaultValue = "true") Boolean deleteFile,
69 HttpServletResponse response) throws IOException { 63 HttpServletResponse response) throws IOException {
@@ -77,9 +71,8 @@ public class InfDbDocController { @@ -77,9 +71,8 @@ public class InfDbDocController {
77 String downloadFileName = DOC_FILE_NAME + fileOutputType.getFileSuffix(); //下载后的文件名 71 String downloadFileName = DOC_FILE_NAME + fileOutputType.getFileSuffix(); //下载后的文件名
78 try { 72 try {
79 // 读取,返回 73 // 读取,返回
80 - //这里不用hutool工具类,它的中文文件名编码有问题,导致在浏览器下载时有问题  
81 ServletUtils.writeAttachment(response, downloadFileName, FileUtil.readBytes(filePath)); 74 ServletUtils.writeAttachment(response, downloadFileName, FileUtil.readBytes(filePath));
82 - }finally { 75 + } finally {
83 handleDeleteFile(deleteFile, filePath); 76 handleDeleteFile(deleteFile, filePath);
84 } 77 }
85 } 78 }
@@ -123,7 +116,6 @@ public class InfDbDocController { @@ -123,7 +116,6 @@ public class InfDbDocController {
123 private HikariDataSource buildDataSource() { 116 private HikariDataSource buildDataSource() {
124 // 创建 HikariConfig 配置类 117 // 创建 HikariConfig 配置类
125 HikariConfig hikariConfig = new HikariConfig(); 118 HikariConfig hikariConfig = new HikariConfig();
126 -// hikariConfig.setDriverClassName("com.mysql.cj.jdbc.Driver");  
127 hikariConfig.setJdbcUrl(dataSourceProperties.getUrl()); 119 hikariConfig.setJdbcUrl(dataSourceProperties.getUrl());
128 hikariConfig.setUsername(dataSourceProperties.getUsername()); 120 hikariConfig.setUsername(dataSourceProperties.getUsername());
129 hikariConfig.setPassword(dataSourceProperties.getPassword()); 121 hikariConfig.setPassword(dataSourceProperties.getPassword());