mirror of
https://gitee.com/bookshelfplus/bookshelfplus
synced 2025-09-01 22:53:29 +08:00
导出markdown接口基本功能完成
This commit is contained in:
@@ -13,6 +13,7 @@ public class MarkdownTable {
|
||||
this.format = format;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return format;
|
||||
}
|
||||
@@ -30,11 +31,22 @@ public class MarkdownTable {
|
||||
// 表格的样式
|
||||
private Alignment[] alignments;
|
||||
|
||||
private MarkdownTable(Integer numOfColumns) {
|
||||
// 表格为空时是否输出
|
||||
private Boolean notExportWhenEmpty = true;
|
||||
|
||||
public MarkdownTable doNotExportWhenEmpty(Boolean notExportWhenEmpty) {
|
||||
this.notExportWhenEmpty = notExportWhenEmpty;
|
||||
return this;
|
||||
}
|
||||
|
||||
private MarkdownTable() {
|
||||
}
|
||||
|
||||
private void init(Integer numOfColumns) {
|
||||
this.numOfColumns = numOfColumns;
|
||||
headers = new String[numOfColumns];
|
||||
alignments = new Alignment[numOfColumns];
|
||||
rows = new ArrayList<>();
|
||||
this.headers = new String[numOfColumns];
|
||||
this.alignments = new Alignment[numOfColumns];
|
||||
this.rows = new ArrayList<>();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -48,7 +60,15 @@ public class MarkdownTable {
|
||||
* @return
|
||||
*/
|
||||
public static MarkdownTable create(Integer numOfColumns) {
|
||||
return new MarkdownTable(numOfColumns);
|
||||
MarkdownTable markdownTable = new MarkdownTable();
|
||||
if (numOfColumns > 0) {
|
||||
markdownTable.init(numOfColumns);
|
||||
}
|
||||
return markdownTable;
|
||||
}
|
||||
|
||||
public static MarkdownTable create() {
|
||||
return new MarkdownTable();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -57,14 +77,17 @@ public class MarkdownTable {
|
||||
* @param header
|
||||
* @return
|
||||
*/
|
||||
public MarkdownTable setHeader(Object... header) {
|
||||
public MarkdownTable setHeader(String... header) {
|
||||
if (numOfColumns == 0) {
|
||||
init(header.length);
|
||||
}
|
||||
if (header.length != numOfColumns) {
|
||||
throw new IllegalArgumentException("表格的列数不匹配");
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
for (Object o : header) {
|
||||
headers[i++] = o.toString();
|
||||
for (String o : header) {
|
||||
this.headers[i++] = o;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
@@ -76,6 +99,9 @@ public class MarkdownTable {
|
||||
* @return
|
||||
*/
|
||||
public MarkdownTable setAlignment(Alignment... alignments) {
|
||||
if (numOfColumns == 0) {
|
||||
init(alignments.length);
|
||||
}
|
||||
if (alignments.length != numOfColumns) {
|
||||
throw new IllegalArgumentException("表格的列数不匹配");
|
||||
}
|
||||
@@ -97,6 +123,9 @@ public class MarkdownTable {
|
||||
* @return
|
||||
*/
|
||||
public MarkdownTable addRow(String... row) {
|
||||
if (numOfColumns == 0) {
|
||||
init(row.length);
|
||||
}
|
||||
if (row.length != numOfColumns) {
|
||||
throw new IllegalArgumentException("表格的列数不匹配");
|
||||
}
|
||||
@@ -109,12 +138,11 @@ public class MarkdownTable {
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return toStringBuilder().toString();
|
||||
}
|
||||
public String getMarkdown() {
|
||||
if (notExportWhenEmpty && rows.size() == 0) {
|
||||
return "";
|
||||
}
|
||||
|
||||
public StringBuilder toStringBuilder() {
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
|
||||
// 表头
|
||||
@@ -140,6 +168,7 @@ public class MarkdownTable {
|
||||
// stringBuilder.append(" |\n");
|
||||
|
||||
for (String o : row) {
|
||||
if (o == null) o = "";
|
||||
stringBuilder.append(" ");
|
||||
stringBuilder.append(o.replace("\n", "<br>")
|
||||
.replace("|", "\\|"));
|
||||
@@ -150,6 +179,6 @@ public class MarkdownTable {
|
||||
|
||||
// 删除最后一个换行符
|
||||
stringBuilder.deleteCharAt(stringBuilder.lastIndexOf("\n"));
|
||||
return stringBuilder;
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
}
|
||||
|
@@ -118,6 +118,14 @@ public class MarkdownUtils {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* n级标题
|
||||
*/
|
||||
public MarkdownUtils h(int n, String str) {
|
||||
this.append(StringUtils.repeat("#", n) + " " + str);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 加粗
|
||||
*
|
||||
@@ -285,7 +293,7 @@ public class MarkdownUtils {
|
||||
* @return
|
||||
*/
|
||||
public MarkdownUtils table(MarkdownTable table) {
|
||||
this.append(table.toString());
|
||||
this.append(table.getMarkdown());
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
@@ -9,7 +9,10 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMethod;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import plus.bookshelf.Common.Enum.FileStorageMediumEnum;
|
||||
import plus.bookshelf.Common.Error.BusinessException;
|
||||
import plus.bookshelf.Common.MarkdownUtils.MarkdownTable;
|
||||
import plus.bookshelf.Common.MarkdownUtils.MarkdownUtils;
|
||||
import plus.bookshelf.Common.Response.CommonReturnType;
|
||||
import plus.bookshelf.Dao.DO.BookDO;
|
||||
import plus.bookshelf.Dao.DO.CategoryDO;
|
||||
@@ -24,6 +27,7 @@ import plus.bookshelf.Service.Model.UserModel;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
@Api(tags = "导出数据")
|
||||
@Controller("export")
|
||||
@@ -135,7 +139,11 @@ public class ExportController extends BaseController {
|
||||
@ApiOperation(value = "【管理员】导出系统数据", notes = "将系统中的所有数据导出为markdown")
|
||||
@RequestMapping(value = "markdown", method = {RequestMethod.POST}, consumes = {CONTENT_TYPE_FORMED})
|
||||
@ResponseBody
|
||||
public CommonReturnType deleteBook(@RequestParam(value = "token", required = false) String token) throws BusinessException {
|
||||
public CommonReturnType exportMarkdown(@RequestParam(value = "token", required = false) String token) throws BusinessException {
|
||||
|
||||
// TODO 暂时注释掉
|
||||
// // 已经在 getUserByToken 方法中判断了 token 为空、不合法;用户不存在情况,此处无需再判断
|
||||
// UserModel userModel = userService.getUserByToken(redisTemplate, token);
|
||||
|
||||
// 查询出系统中所有的分类、书籍、文件、文件对象数据
|
||||
CategoryDO[] allCategorys = categoryDOMapper.selectAll();
|
||||
@@ -187,7 +195,7 @@ public class ExportController extends BaseController {
|
||||
|
||||
// 再创建一个虚拟的顶级分类,用于保存所有的一级分类
|
||||
CategoryNode rootCategoryNode = new CategoryNode(new CategoryDO());
|
||||
rootCategoryNode.subCategory = categoryNodeList;
|
||||
rootCategoryNode.subCategory = rootCategoryNodeList;
|
||||
|
||||
// 分类形成树状结构
|
||||
for (CategoryNode categoryNode : categoryNodeList) {
|
||||
@@ -195,34 +203,37 @@ public class ExportController extends BaseController {
|
||||
if (categoryNode.current.getParentId().equals(parentCategoryNode.current.getId())) {
|
||||
parentCategoryNode.subCategory.add(categoryNode);
|
||||
|
||||
// 将子节点从 rootCategoryNodeList 中移除
|
||||
if (rootCategoryNodeList.contains(categoryNode)) {
|
||||
rootCategoryNodeList.remove(categoryNode);
|
||||
}
|
||||
|
||||
// 将父节点添加到 rootCategoryNodeList 中
|
||||
if (!rootCategoryNodeList.contains(parentCategoryNode)) {
|
||||
rootCategoryNodeList.add(parentCategoryNode);
|
||||
}
|
||||
|
||||
// 将子节点从 rootCategoryNodeList 中移除
|
||||
if (rootCategoryNodeList.contains(categoryNode)) {
|
||||
rootCategoryNodeList.remove(categoryNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 打印出这个复杂的树状结构
|
||||
traverseCategory(rootCategoryNode, 1);
|
||||
// 创建 Markdown 对象
|
||||
MarkdownUtils markdownUtils = MarkdownUtils.getInstance();
|
||||
|
||||
StringBuilder markdown = new StringBuilder();
|
||||
// 打印出这个复杂的树状结构
|
||||
traverseCategory(markdownUtils, rootCategoryNode, 1);
|
||||
|
||||
// 形成 markdown 格式的文件
|
||||
String markdown = markdownUtils.getMarkdown();
|
||||
// System.out.println(markdown);
|
||||
|
||||
// 添加 markdown 头部以及尾部
|
||||
|
||||
// 返回 markdown 文件
|
||||
return CommonReturnType.create(null);
|
||||
return CommonReturnType.create(markdown);
|
||||
}
|
||||
|
||||
// 递归打印出分类树状结构
|
||||
private void traverseCategory(CategoryNode parentCategoryNode, Integer level) {
|
||||
private void traverseCategory(MarkdownUtils markdownUtils, CategoryNode parentCategoryNode, Integer level) {
|
||||
|
||||
// 如果这个分类为空,则直接返回
|
||||
if (parentCategoryNode == null) {
|
||||
@@ -230,37 +241,91 @@ public class ExportController extends BaseController {
|
||||
}
|
||||
|
||||
// 如果这个分类下有书籍,则遍历打印书籍信息
|
||||
traverseBook(parentCategoryNode, level);
|
||||
traverseBook(markdownUtils, parentCategoryNode, level);
|
||||
|
||||
// 遍历父级分类的孩子们
|
||||
for (CategoryNode categoryNode : parentCategoryNode.subCategory) {
|
||||
// 打印出当前子分类的名称
|
||||
System.out.println(getSpace(level - 1) + "[" + level + "级分类] \t" + categoryNode.current.getName());
|
||||
// System.out.println(getSpace(level - 1) + "[" + level + "级分类] \t" + categoryNode.current.getName());
|
||||
markdownUtils.h(level, categoryNode.current.getName())
|
||||
.blockquote(categoryNode.current.getDescription());
|
||||
|
||||
// 如果当前子分类还有子分类,则递归他
|
||||
traverseCategory(categoryNode, level + 1);
|
||||
traverseCategory(markdownUtils, categoryNode, level + 1);
|
||||
}
|
||||
}
|
||||
|
||||
// 递归打印出一本书的书籍信息
|
||||
private void traverseBook(CategoryNode categoryNode, Integer level) {
|
||||
private void traverseBook(MarkdownUtils markdownUtils, CategoryNode categoryNode, Integer level) {
|
||||
// 如果这个分类为空,则直接返回
|
||||
if (categoryNode == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
String[] headers = {""/*编号*/, "书名", "格式", "总页数", "语言", "是否有水印/广告", "扫描版/电子版", "文件大小", "来源信息 & 备注", "下载地址"}; // "作者", "出版社", "出版日期", "ISBN"
|
||||
MarkdownTable markdownTable = MarkdownTable.create()
|
||||
.setHeader(headers)
|
||||
.setAlignment(MarkdownTable.Alignment.LEFT)
|
||||
.doNotExportWhenEmpty(true);
|
||||
|
||||
List<BookNode> bookNodeList = categoryNode.children;
|
||||
// 遍历打印出书籍信息
|
||||
int i = 0;
|
||||
for (BookNode bookNode : bookNodeList) {
|
||||
BookDO bookDO = bookNode.current;
|
||||
|
||||
String[] strings = new String[headers.length];
|
||||
// 打印出当前书籍的名称
|
||||
System.out.println(getSpace(level - 1) + "\t[书籍] " + bookNode.current.getId() + "\t" + bookNode.current.getBookName());
|
||||
// System.out.println(getSpace(level - 1) + "\t[书籍] " + bookDO.getId() + "\t" + bookDO.getBookName());
|
||||
strings[0] = ++i + ""; // 编号
|
||||
strings[1] = bookDO.getBookName(); // 书名
|
||||
// strings[2] = ; // 格式
|
||||
// strings[3] = bookDO.getTotalPage() + "";// 总页数
|
||||
strings[4] = bookDO.getLanguage(); // 语言
|
||||
// strings[5] = bookDO.get() + "";// 是否有水印/广告
|
||||
// strings[6] = bookDO.get() + "";// 扫描版/电子版
|
||||
// strings[7] = bookDO.getFileSize() + "";// 文件大小
|
||||
// strings[8] = bookDO.get() + "";// 来源信息 & 备注
|
||||
// strings[9] = bookDO.get() + "";// 下载地址
|
||||
|
||||
for (FileNode fileNode : bookNode.children) {
|
||||
FileDO fileDO = fileNode.current;
|
||||
// 打印出当前书籍的文件信息
|
||||
System.out.println(getSpace(level - 1) + "\t\t[文件] " + fileNode.current.getId() + "\t" + fileNode.current.getFileName());
|
||||
// System.out.println(getSpace(level - 1) + "\t\t[文件] " + fileDO.getId() + "\t" + fileDO.getFileName());
|
||||
strings[2] = fileDO.getFileName();// 格式
|
||||
// strings[3] = fileDO.get() + "";// 总页数
|
||||
|
||||
String[] a = {fileDO.getWatermark() ? "有水印" : "", fileDO.getAdvertising() ? "有广告" : ""};
|
||||
strings[5] = String.join(",", a);// 是否有水印/广告
|
||||
// strings[6] = fileDO.getScan() ? "扫描版" : "电子版";// 扫描版/电子版
|
||||
strings[7] = fileDO.getFileSize() + "";// 文件大小
|
||||
strings[8] = fileDO.getBookOrigin() + "";// 来源信息 & 备注
|
||||
List<String> url = new ArrayList<>();
|
||||
StringBuilder download = new StringBuilder();
|
||||
for (FileObjectNode fileObjectNode : fileNode.children) {
|
||||
FileObjectDO fileObjectDO = fileObjectNode.current;
|
||||
// 打印出当前书籍的文件对象信息
|
||||
System.out.println(getSpace(level - 1) + "\t\t\t[文件对象] " + fileObjectNode.current.getId() + "\t" + fileObjectNode.current.getFileName());
|
||||
// System.out.println(getSpace(level - 1) + "\t\t\t[文件对象] " + fileObjectDO.getId() + "\t" + fileObjectDO.getFileName());
|
||||
if (Objects.equals(fileObjectDO.getStorageMediumType(), FileStorageMediumEnum.QCLOUD_COS.getStorageMediumName()))
|
||||
continue;
|
||||
download.append("[")
|
||||
.append(FileStorageMediumEnum.valueOf(fileObjectDO.getStorageMediumType()).getStorageMediumDisplayName())
|
||||
.append("](")
|
||||
.append(fileObjectDO.getFilePath())
|
||||
.append(")");
|
||||
if (fileObjectDO.getFilePwd() != null && !fileObjectDO.getFilePwd().isEmpty()) {
|
||||
download.append("文件密码:").append(fileObjectDO.getFilePwd());
|
||||
}
|
||||
if (fileObjectDO.getFileShareCode() != null && !fileObjectDO.getFileShareCode().isEmpty()) {
|
||||
download.append("提取码:").append(fileObjectDO.getFileShareCode());
|
||||
}
|
||||
download.append("<br>");
|
||||
}
|
||||
strings[9] = download.toString();// 下载地址
|
||||
}
|
||||
markdownTable.addRow(strings);
|
||||
}
|
||||
markdownUtils.table(markdownTable);
|
||||
}
|
||||
|
||||
public String getSpace(Integer count) {
|
||||
@@ -270,4 +335,5 @@ public class ExportController extends BaseController {
|
||||
}
|
||||
return space.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user