导出文件(docx)
导出的核心代码-无需关注这里
@Override
@SneakyThrows
public OutputStream dumpSqlDoc(DbQO dbQO, OutputStream outputStream) {
List<TableInfo> tablesMetas = getTablesMeta(dbQO);
Word07Writer writer = new Word07Writer();
//表索引
Font docTitleFont = new Font(Font.SANS_SERIF, Font.BOLD, 25);
writer.addText(ParagraphAlignment.CENTER,docTitleFont, "数据库设计文档");
writer.addText(ParagraphAlignment.CENTER,docTitleFont, StrUtil.EMPTY);
writer.addText(ParagraphAlignment.CENTER,docTitleFont, StrUtil.EMPTY);
AtomicInteger tableIndexAtomicInteger = new AtomicInteger();
tablesMetas.forEach(tableInfo -> {
String comment = tableInfo.getComment();
comment = StrUtil.isBlank(comment) ? StrUtil.EMPTY : StrUtil.format("({})", comment);
// Font tableNameTitleFont = FontUtil.createSansSerifFont(20);
Font tableNameTitleFont = new Font(Font.SANS_SERIF, Font.BOLD, 20);
writer.addText(tableNameTitleFont, StrUtil.format("{}、{}{}", tableIndexAtomicInteger.incrementAndGet(), tableInfo.getName(),comment));
List<TableField> tableFields = tableInfo.getFields();
//表的字段索引
AtomicInteger tableFieldInexAtomicInteger = new AtomicInteger(0);
List<Map<String, Object>> workTableFields = tableFields.stream()
.map(tableField -> {
Map<String, Object> wrokTableRow = new LinkedHashtable();
wrokTableRow.put("序号", tableFieldInexAtomicInteger.incrementAndGet());
wrokTableRow.put("字段名", tableField.getName());
wrokTableRow.put("数据类型", tableField.getColumnType());
wrokTableRow.put("主键", tableField.isKeyFlag() ? "是" : "否");
wrokTableRow.put("非空", tableField.getMetaInfo().isNullable() ? "是" : "否");
wrokTableRow.put("默认值", tableField.getMetaInfo().getDefaultValue());
wrokTableRow.put("描述", tableField.getComment());
return wrokTableRow;
})
.collect(Collectors.toList());
;
writer.addTable(workTableFields);
writer.addText(FontUtil.createFont(),StrUtil.EMPTY);
writer.addText(FontUtil.createFont(),StrUtil.EMPTY);
});
writer.flush(outputStream, false);
return outputStream;
}
Get请求
后端
@ApiOperation(value = "生成数据库设计文档")
@GetMapping("dump_sql_doc")
public void dumpSqlDoc(@Validated DbQO dbQO) throws IOException {
HttpServletResponse response = EnhanceSpringUtil.getCurrentResponse();
String fileName = StrUtil.format("数据库文档-{}.docx", DatePattern.PURE_DATETIME_FORMAT.format(DateUtil.date()));
response.setHeader(Header.CONTENT_DISPOSITION.getValue(), "attachment;filename="+ URLUtil.encode(fileName, CharsetUtil.CHARSET_UTF_8));
response.setHeader("FileName", URLUtil.encode(fileName, CharsetUtil.CHARSET_UTF_8));
response.setHeader("Access-Control-Expose-Headers", "FileName");
response.setHeader(Header.CONTENT_TYPE.getValue(), "application/vnd.openxmlformats-officedocument.wordprocessingml.document");
dbService.dumpSqlDoc(dbQO, response.getOutputStream());
}
前端
/**
* 构建链接
* @param url
*/
function buildUrl(url, paramBean) {
if(strIsNotEmpty(url) && paramBean) {
let URLObj = new URL(url)
for(let fieldName in paramBean) {
URLObj.searchParams.set(fieldName, paramBean[fieldName]);
}
return URLObj.toString();
}
return null;
}
let downloadUrl = buildUrl(window.location.origin + "/db/dump_sql_doc",dataSource)
jumpUrlByNewWindow(downloadUrl)
Post请求
后端
方式1
@ApiOperation(value = "生成数据库设计文档")
@PostMapping("dump_sql_doc3")
public void dumpSqlDoc3(@RequestBody @Validated DbQO dbQO) throws IOException {
HttpServletResponse currentResponse = EnhanceSpringUtil.getCurrentResponse();
String fileName = StrUtil.format("数据库文档-{}.docx", DatePattern.PURE_DATETIME_FORMAT.format(DateUtil.date()));
currentResponse.setHeader(Header.CONTENT_DISPOSITION.getValue(), "attachment;filename="+ URLUtil.encode(fileName, CharsetUtil.CHARSET_UTF_8));
currentResponse.setHeader("FileName", URLUtil.encode(fileName, CharsetUtil.CHARSET_UTF_8));
currentResponse.setHeader("Access-Control-Expose-Headers", "FileName");
currentResponse.setHeader(Header.CONTENT_TYPE.getValue(), "application/vnd.openxmlformats-officedocument.wordprocessingml.document");
dbService.dumpSqlDoc(dbQO, currentResponse.getOutputStream());
}
方式2
@ApiOperation(value = "生成数据库设计文档")
@PostMapping("dump_sql_doc")
public ResponseEntity<Resource> dumpSqlDoc2(@RequestBody @Validated DbQO dbQO) throws IOException {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
dbService.dumpSqlDoc(dbQO, byteArrayOutputStream);
ByteArrayResource resource = new ByteArrayResource(byteArrayOutputStream.toByteArray());
HttpHeaders headers = new HttpHeaders();
String fileName = StrUtil.format("数据库文档-{}.docx", DatePattern.PURE_DATETIME_FORMAT.format(DateUtil.date()));
headers.add(Header.CONTENT_DISPOSITION.getValue(), "attachment;filename="+ URLUtil.encode(fileName, CharsetUtil.CHARSET_UTF_8));
headers.add("FileName", URLUtil.encode(fileName, CharsetUtil.CHARSET_UTF_8));
headers.add("Access-Control-Expose-Headers", "FileName");
headers.add(Header.CONTENT_TYPE.getValue(), "application/vnd.openxmlformats-officedocument.wordprocessingml.document");
// 返回ResponseEntity对象,包含Resource和响应头
return ResponseEntity.ok()
.headers(headers)
.contentLength(resource.contentLength())
.body(resource);
}
前端
/**
* 生成数据库文档(没用)
* @param dbQO
* @returns {*}
*/
function dumpSqlDoc2(dbQO) {
return request.post('/db/dump_sql_doc', dbQO ? dbQO : {}, {
responseType: 'blob',
})
}
/**
* 生成数据库文档(没用)
* @param dbQO
* @returns {*}
*/
function dumpSqlDoc3(dbQO) {
return request.post('/db/dump_sql_doc3', dbQO ? dbQO : {}, {
responseType: 'blob',
})
}
/**
* 基于响应下载文件
* @param response 响应体
* @param successFunction 下载成功回调
* @param errorFunction 下载失败回调
*/
function downloadFile(response, successFunction, errorFunction) {
log("下载文件:", response);
successFunction = successFunction ? successFunction: () => {};
errorFunction = errorFunction ? errorFunction: () => {};
if(response.status>=200 && response.status < 300) {
data = response.data;
let contentType = strEmptyToDefault(response.headers["content-type"], "application/octet-stream")
let url = window.URL.createObjectURL(new Blob([data],{type: contentType}))
let link = document.createElement('a')
link.style.display = 'none'
link.href = url
let fileName = strEmptyToDefault(response?.headers?.filename, strFormat("{}",getUuid()))
fileName = decodeURIComponent(fileName)
link.download = fileName; //下载后文件名
link.setAttribute('download', fileName)
document.body.appendChild(link)
link.click()
successFunction();
}else {
errorFunction();
}
}
dumpSqlDoc3(dataSource)
.then(response => {
downloadFile(response, () => {
successMessage("生成数据库文档成功")
}, () => {
errorMessage("生成数据库文档成功")
})
})
试验后,可正常下载以及打开文件