声明
本文章为纯原创,若需转载烦请备注来源。里面涉及到的代码仅供学习使用。
需求
甲方要求我们提供一份数据库设计文档,需要把所有的表结构罗列上去。项目目前涉及到表大概200+个,手工写word肯定是比较耗费时间的。找了下资源也有工具能做到,比如navicat mysql版,但是手头上没有这款工具,简单的找了找POI文档,决定自己手写一个导出Word程序。实现过程还是比较简单的,大家一起来看看。
基本环境
- jdk 1.8
- Apache poi 4.1.2
输出效果
(本人比较懒,直接使用项目库,所以有些打码,忘理解😃。 文档还是比较简陋,以此为基准稿也能减省不少时间🐝)
实现代码
1. 完整代码
(平台不能粘贴完整代码,故分两部分:主要代码和完整结构截图)
public static void main(String[] args) throws IOException {
exportDbSchema();
}
public static void exportDbSchema() throws IOException {
Map<String, String> tables = getTables();
List<ColumnModel> columns = getColumns();
try (XWPFDocument doc = new XWPFDocument()) {
XWPFParagraph p = doc.createParagraph();
p.setAlignment(ParagraphAlignment.CENTER);
XWPFRun r = p.createRun();
r.setText("数据库设计");
r.setBold(true);
r.setFontFamily("黑体");
r.setFontSize(18);
p.createRun().addBreak(BreakType.PAGE);
writeSchema(tables, columns, doc);
try (OutputStream os = Files.newOutputStream(new File("数据库设计.docx").toPath())) {
doc.write(os);
}
}
}
private static void writeSchema(Map<String, String> tables, List<ColumnModel> columns, XWPFDocument doc) {
ArrayList<Map.Entry<String, String>> entries = new ArrayList<>(tables.entrySet());
entries.sort(Map.Entry.comparingByKey());
Map<String, List<ColumnModel>> columnMap = columns.stream().collect(Collectors.groupingBy(ColumnModel::getTable));
XWPFParagraph p;
XWPFRun r;
int index = 1;
for (Map.Entry<String, String> table : entries) {
p = doc.createParagraph();
p.setAlignment(ParagraphAlignment.LEFT);
p.setWordWrapped(true);
p.getCTP().getPPr().addNewOutlineLvl().setVal(new BigInteger("1"));
r = p.createRun();
CTFonts ctFonts = r.getCTR().addNewRPr().addNewRFonts();
ctFonts.setAscii("Times New Roman");
ctFonts.setEastAsia("宋体");
r.setFontSize(10);
r.setText(String.format("%d. %s", index, table.getKey()));
r.setFontFamily("黑体");
r.setStyle("3");
if (StringUtils.isNotBlank(table.getValue())) {
p = doc.createParagraph();
r = p.createRun();
ctFonts = r.getCTR().addNewRPr().addNewRFonts();
ctFonts.setAscii("Times New Roman");
ctFonts.setEastAsia("宋体");
r.setFontSize(10);
r.setText(table.getValue());
}
List<ColumnModel> list = columnMap.get(table.getKey());
writeColumn(list, doc);
index += 1;
}
}
private static void writeColumn(List<ColumnModel> list, XWPFDocument doc) {
String[] headerTitle = new String[]{"名称","数据类型","是否主键","是否为空","注释"};
String[] width = new String[]{"20%","15%","15%","15%","35%"};
XWPFTable table = doc.createTable(list.size() + 1, 5);
table.setWidth("100%");
List<XWPFTableRow> rows = table.getRows();
XWPFTableRow header = rows.get(0);
header.setHeight(50);
for (int i = 0; i < headerTitle.length; i++) {
XWPFTableCell cell = header.getCell(i);
cell.setWidth(width[i]);
cell.setText(headerTitle[i]);
cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.CENTER);
}
for (int i = 0; i < list.size(); i++) {
ColumnModel col = list.get(i);
XWPFTableRow row = rows.get(i + 1);
XWPFTableCell cell = row.getCell(0);
cell.setWidth(width[0]);
cell.setText(col.getName());
XWPFTableCell cell1 = row.getCell(1);
cell1.setWidth(width[1]);
cell1.setText(col.getType());
XWPFTableCell cell2 = row.getCell(2);
cell2.setWidth(width[2]);
cell2.setText(col.getPri());
XWPFTableCell cell3 = row.getCell(3);
cell3.setWidth(width[3]);
cell3.setText(col.getNullable());
XWPFTableCell cell4 = row.getCell(4);
cell4.setWidth(width[4]);
cell4.setText(col.getComment());
}
XWPFParagraph p = doc.createParagraph();
p.createRun().addBreak(BreakType.TEXT_WRAPPING);
p.createRun().addBreak(BreakType.TEXT_WRAPPING);
}
// 表名及表备注结构 可以直接查库
private static Map<String, String> getTables() throws IOException {
List<String> lines = IOUtils.readLines(Files.newInputStream(new File("tables.json").toPath()), StandardCharsets.UTF_8);
return JSON.parseObject(StringUtils.join(lines, ""), new TypeReference<Map<String, String>>(){});
}
// 列信息 可以直接查库
private static List<ColumnModel> getColumns() throws IOException {
List<String> lines = IOUtils.readLines(Files.newInputStream(new File("columns.json").toPath()), StandardCharsets.UTF_8);
return JSON.parseArray(StringUtils.join(lines, ""), ColumnModel.class);
}
2. 简单介绍
循环表集合来依次输出具体表信息,一张表一个段落。为了减省运行调试时间,这里将表结构和列信息用json格式保存到文件中。
XWPFDocument.createParagraph()函数创建段落,XWPFDocument.createTable()在word中绘制表格。代码中简单的设置了字体样式、对齐方式、目录设置,若需要调整字体、样式等就需要翻翻poi文档了。(资源比较少,查找还是比较费劲🤯)
3. 数据结构及表信息查询
- MySQL中查询表及备注信息
select table_name, table_comment from information_schema.tables where table_schema = 'test' order by table_name - MySQL中查询列信息
select table_name, column_name '名称', column_type '数据类型', column_key '是否主键', is_nullable '是否为空', column_comment '注释' from information_schema.columns where table_schema = 'test' order by table_name, ordinal_position - 代码中ColumnModel定义