一、概述
平常会遇到编写文档类的工作,尤其是数据库的,要把每张表的详细字段列出来,手写实在费劲,从网上找了很多,都没有那种直接GUI输入参数,一键生成的,所以自己花时间做了一个,功能很简陋,但是基本需求可以实现。
二、代码
Swing
package com.scc.generate.word;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.io.PrintWriter;
import java.io.StringWriter;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
/**
* @ClassName: MainJFrame
* @Description: TODO(这里用一句话描述这个类的作用)
* @author javascc@126.com
* @date 2023年3月30日 下午5:23:40
*
*/
public class MainJFrame implements Runnable {
/*
* (非 Javadoc) <p>Title: run</p> <p>Description: </p>
*
* @see java.lang.Runnable#run()
*/
@Override
public void run() {
JFrame frame = new JFrame("数据库WORD生成器-scc");
frame.setSize(500, 350);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
frame.add(panel);
placeComponents(frame, panel);
frame.setVisible(true);
}
private static void placeComponents(JFrame frame, JPanel panel) {
panel.setLayout(null);
// 驱动类
JLabel driverJLabel = new JLabel("驱动类");
driverJLabel.setBounds(10, 20, 80, 25);
panel.add(driverJLabel);
String[] driverSelectJLabel = { "com.mysql.cj.jdbc.Driver" };
JComboBox comboBox = new JComboBox();
comboBox.setModel(new DefaultComboBoxModel(driverSelectJLabel));
comboBox.setBounds(100, 20, 350, 25);
panel.add(comboBox);
// URL
JLabel urlLabel = new JLabel("URL:");
urlLabel.setBounds(10, 50, 80, 25);
panel.add(urlLabel);
JTextField urlTextLabel = new JTextField(20);
urlTextLabel.setBounds(100, 50, 350, 25);
urlTextLabel
.setText("jdbc:mysql://127.0.0.1:3306/[db_name]?useUnicode=true&characterEncoding=UTF-8&useSSL=false");
panel.add(urlTextLabel);
// 用户名
JLabel uanmeLabel = new JLabel("用户名:");
uanmeLabel.setBounds(10, 80, 80, 25);
panel.add(uanmeLabel);
JTextField uanmeTextLabel = new JTextField(20);
uanmeTextLabel.setBounds(100, 80, 350, 25);
uanmeTextLabel.setText("root");
panel.add(uanmeTextLabel);
// 密码
JLabel passwordLabel = new JLabel("密码:");
passwordLabel.setBounds(10, 110, 80, 25);
panel.add(passwordLabel);
JTextField passwordText = new JTextField(20);
passwordText.setBounds(100, 110, 350, 25);
passwordText.setText("123456");
panel.add(passwordText);
// 文件位置
JLabel filePathLabel = new JLabel("文件位置:");
filePathLabel.setBounds(10, 140, 80, 25);
panel.add(filePathLabel);
JTextField filePathText = new JTextField(20);
filePathText.setBounds(100, 140, 350, 25);
filePathText.setText("/Users/[user]/Desktop/words/");
panel.add(filePathText);
// 按钮
JButton loginButton = new JButton("生成");
loginButton.setBounds(100, 170, 100, 25);
panel.add(loginButton);
// 信息输出
JTextArea infoJTextArea = new JTextArea();
infoJTextArea.setLineWrap(true);
JScrollPane jsp = new JScrollPane(infoJTextArea);
jsp.setBounds(10, 210, 480, 100);
jsp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
panel.add(jsp);
loginButton.addActionListener(e -> {
infoJTextArea.append("------------------开始生成------------------");
infoJTextArea.append("\r\n");
infoJTextArea.append("配置的驱动:");
String driver = driverSelectJLabel[comboBox.getSelectedIndex()];
infoJTextArea.append(driver);
if (null == driver || "".equals(driver)) {
infoJTextArea.append("ERROR:未配置驱动!");
}
infoJTextArea.append("\r\n");
infoJTextArea.append("配置的URL:");
String url = urlTextLabel.getText();
infoJTextArea.append(url);
if (null == url || "".equals(url)) {
infoJTextArea.append("ERROR:未配置URL!");
}
infoJTextArea.append("\r\n");
infoJTextArea.append("配置的用户名:");
String uname = uanmeTextLabel.getText();
infoJTextArea.append(uname);
if (null == uname || "".equals(uname)) {
infoJTextArea.append("ERROR:未配置用户名!");
}
infoJTextArea.append("\r\n");
infoJTextArea.append("配置的密码:");
String pwd = passwordText.getText();
infoJTextArea.append(pwd);
if (null == pwd || "".equals(pwd)) {
infoJTextArea.append("ERROR:未配置密码!");
}
infoJTextArea.append("\r\n");
infoJTextArea.append("配置的文件输出位置:");
String filePath = filePathText.getText();
infoJTextArea.append(filePath);
if (null == filePath || "".equals(filePath)) {
infoJTextArea.append("ERROR:未配置文件输出位置!");
}
infoJTextArea.append("\r\n");
infoJTextArea.setCaretPosition(infoJTextArea.getText().length());
try {
new GenerateMysqlWord().generate(driver, url, uname, pwd, filePath);
} catch (Exception ec) {
infoJTextArea.append(getErrorInfoFromException(ec));
}
infoJTextArea.append("------------------生成完成------------------");
});
frame.addComponentListener(new ComponentAdapter() {// 拖动窗口监听
@Override
public void componentResized(ComponentEvent e) {
int whidth = frame.getWidth();// 获取窗口宽度
int height = frame.getHeight();// 获取窗口宽度
// 将lable放在 窗口左边的1/3处
comboBox.setBounds(100, 20, whidth - 110, 25);// (起始点x,起始点y,宽地w,高h) 标签设置宽高不明显
// 将lable放在 窗口左边的1/2处
urlTextLabel.setBounds(100, 50, whidth - 110, 25);// (起始点x,起始点y,宽地w,高h)
// 宽度始终是窗口的1/2
uanmeTextLabel.setBounds(100, 80, whidth - 110, 25);// (起始点x,起始点y,宽地w,高h)
passwordText.setBounds(100, 110, whidth - 110, 25);// (起始点x,起始点y,宽地w,高h)
filePathText.setBounds(100, 140, whidth - 110, 25);// (起始点x,起始点y,宽地w,高h)
jsp.setBounds(10, 210, whidth - 25, height - 250);// (起始点x,起始点y,宽地w,高h)
}
});
}
public static String getErrorInfoFromException(Exception e) {
StringWriter sw = new StringWriter();
try (PrintWriter pw = new PrintWriter(sw);) {
e.printStackTrace(pw);
}
return sw.toString();
}
}
文档生成
package com.scc.generate.word;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import javax.sql.DataSource;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import cn.smallbun.screw.core.Configuration;
import cn.smallbun.screw.core.engine.EngineConfig;
import cn.smallbun.screw.core.engine.EngineFileType;
import cn.smallbun.screw.core.engine.EngineTemplateType;
import cn.smallbun.screw.core.execute.DocumentationExecute;
import cn.smallbun.screw.core.process.ProcessConfig;
/**
* @ClassName: GenerateMysqlWord
* @Description: TODO(这里用一句话描述这个类的作用)
* @author javascc@126.com
* @date 2023年3月27日 下午3:49:19
*
*/
public class GenerateMysqlWord {
public void generate(String driverClassName, String url, String uname, String pwd, String filePath)
throws Exception {
// 数据源:HikariCP 线程池, SpringBoot 2.0开始内置了HikariCP,2.0之前的版本需要引入依赖
HikariConfig hikariConfig = new HikariConfig();
// com.mysql.jdbc.Driver MySQL5驱动;com.mysql.cj.jdbc.Driver MySQL6之后的驱动
hikariConfig.setDriverClassName(driverClassName);
hikariConfig.setJdbcUrl(url);
hikariConfig.setUsername(uname);
hikariConfig.setPassword(pwd);
// 设置可以获取tables remarks信息
hikariConfig.addDataSourceProperty("useInformationSchema", "true");
hikariConfig.setMinimumIdle(2);
hikariConfig.setMaximumPoolSize(5);
DataSource dataSource = new HikariDataSource(hikariConfig);
// 1、生成文件配置
EngineConfig engineConfig = EngineConfig.builder()
// 生成文件路径(改成自己的生成路径)
.fileOutputDir(filePath)
// 生成后是否立即打开目录
.openOutputDir(false)
// 文件类型 有HTML、WORD、MD三种枚举选择
.fileType(EngineFileType.WORD)
// 生成模板实现
.produceType(EngineTemplateType.freemarker).build();
// 忽略表名(可选)
List<String> ignoreTableName = Arrays.asList("aa", "test_group");
// 忽略表前缀(可选)
List<String> ignorePrefix = Collections.singletonList("czb_");
// 忽略表后缀(可选)
List<String> ignoreSuffix = Arrays.asList("_test", "_test1");
// 2、配置想要忽略的表(可选)
ProcessConfig processConfig = ProcessConfig.builder().ignoreTableName(ignoreTableName)
.ignoreTablePrefix(ignorePrefix).ignoreTableSuffix(ignoreSuffix).build();
// 3、生成文档配置(包含以下自定义版本号、标题、描述(数据库名 + 描述 = 文件名)等配置连接)
Configuration config = Configuration.builder().version("1.0.0").title("数据库文档").description("数据库设计文档生成")
.dataSource(dataSource).engineConfig(engineConfig).produceConfig(processConfig).build();
// 4、执行生成
new DocumentationExecute(config).execute();
}
}
main
package com.scc.generate.word;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.io.PrintWriter;
import java.io.StringWriter;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
/**
* @ClassName: MainJFrame
* @Description: TODO(这里用一句话描述这个类的作用)
* @author javascc@126.com
* @date 2023年3月30日 下午5:23:40
*
*/
public class MainJFrame implements Runnable {
/*
* (非 Javadoc) <p>Title: run</p> <p>Description: </p>
*
* @see java.lang.Runnable#run()
*/
@Override
public void run() {
JFrame frame = new JFrame("数据库WORD生成器-scc");
frame.setSize(500, 350);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
frame.add(panel);
placeComponents(frame, panel);
frame.setVisible(true);
}
private static void placeComponents(JFrame frame, JPanel panel) {
panel.setLayout(null);
// 驱动类
JLabel driverJLabel = new JLabel("驱动类");
driverJLabel.setBounds(10, 20, 80, 25);
panel.add(driverJLabel);
String[] driverSelectJLabel = { "com.mysql.cj.jdbc.Driver" };
JComboBox comboBox = new JComboBox();
comboBox.setModel(new DefaultComboBoxModel(driverSelectJLabel));
comboBox.setBounds(100, 20, 350, 25);
panel.add(comboBox);
// URL
JLabel urlLabel = new JLabel("URL:");
urlLabel.setBounds(10, 50, 80, 25);
panel.add(urlLabel);
JTextField urlTextLabel = new JTextField(20);
urlTextLabel.setBounds(100, 50, 350, 25);
urlTextLabel
.setText("jdbc:mysql://127.0.0.1:3306/[db_name]?useUnicode=true&characterEncoding=UTF-8&useSSL=false");
panel.add(urlTextLabel);
// 用户名
JLabel uanmeLabel = new JLabel("用户名:");
uanmeLabel.setBounds(10, 80, 80, 25);
panel.add(uanmeLabel);
JTextField uanmeTextLabel = new JTextField(20);
uanmeTextLabel.setBounds(100, 80, 350, 25);
uanmeTextLabel.setText("root");
panel.add(uanmeTextLabel);
// 密码
JLabel passwordLabel = new JLabel("密码:");
passwordLabel.setBounds(10, 110, 80, 25);
panel.add(passwordLabel);
JTextField passwordText = new JTextField(20);
passwordText.setBounds(100, 110, 350, 25);
passwordText.setText("123456");
panel.add(passwordText);
// 文件位置
JLabel filePathLabel = new JLabel("文件位置:");
filePathLabel.setBounds(10, 140, 80, 25);
panel.add(filePathLabel);
JTextField filePathText = new JTextField(20);
filePathText.setBounds(100, 140, 350, 25);
filePathText.setText("/Users/[user]/Desktop/words/");
panel.add(filePathText);
// 按钮
JButton loginButton = new JButton("生成");
loginButton.setBounds(100, 170, 100, 25);
panel.add(loginButton);
// 信息输出
JTextArea infoJTextArea = new JTextArea();
infoJTextArea.setLineWrap(true);
JScrollPane jsp = new JScrollPane(infoJTextArea);
jsp.setBounds(10, 210, 480, 100);
jsp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
panel.add(jsp);
loginButton.addActionListener(e -> {
infoJTextArea.append("------------------开始生成------------------");
infoJTextArea.append("\r\n");
infoJTextArea.append("配置的驱动:");
String driver = driverSelectJLabel[comboBox.getSelectedIndex()];
infoJTextArea.append(driver);
if (null == driver || "".equals(driver)) {
infoJTextArea.append("ERROR:未配置驱动!");
}
infoJTextArea.append("\r\n");
infoJTextArea.append("配置的URL:");
String url = urlTextLabel.getText();
infoJTextArea.append(url);
if (null == url || "".equals(url)) {
infoJTextArea.append("ERROR:未配置URL!");
}
infoJTextArea.append("\r\n");
infoJTextArea.append("配置的用户名:");
String uname = uanmeTextLabel.getText();
infoJTextArea.append(uname);
if (null == uname || "".equals(uname)) {
infoJTextArea.append("ERROR:未配置用户名!");
}
infoJTextArea.append("\r\n");
infoJTextArea.append("配置的密码:");
String pwd = passwordText.getText();
infoJTextArea.append(pwd);
if (null == pwd || "".equals(pwd)) {
infoJTextArea.append("ERROR:未配置密码!");
}
infoJTextArea.append("\r\n");
infoJTextArea.append("配置的文件输出位置:");
String filePath = filePathText.getText();
infoJTextArea.append(filePath);
if (null == filePath || "".equals(filePath)) {
infoJTextArea.append("ERROR:未配置文件输出位置!");
}
infoJTextArea.append("\r\n");
infoJTextArea.setCaretPosition(infoJTextArea.getText().length());
try {
new GenerateMysqlWord().generate(driver, url, uname, pwd, filePath);
} catch (Exception ec) {
infoJTextArea.append(getErrorInfoFromException(ec));
}
infoJTextArea.append("------------------生成完成------------------");
});
frame.addComponentListener(new ComponentAdapter() {// 拖动窗口监听
@Override
public void componentResized(ComponentEvent e) {
int whidth = frame.getWidth();// 获取窗口宽度
int height = frame.getHeight();// 获取窗口宽度
// 将lable放在 窗口左边的1/3处
comboBox.setBounds(100, 20, whidth - 110, 25);// (起始点x,起始点y,宽地w,高h) 标签设置宽高不明显
// 将lable放在 窗口左边的1/2处
urlTextLabel.setBounds(100, 50, whidth - 110, 25);// (起始点x,起始点y,宽地w,高h)
// 宽度始终是窗口的1/2
uanmeTextLabel.setBounds(100, 80, whidth - 110, 25);// (起始点x,起始点y,宽地w,高h)
passwordText.setBounds(100, 110, whidth - 110, 25);// (起始点x,起始点y,宽地w,高h)
filePathText.setBounds(100, 140, whidth - 110, 25);// (起始点x,起始点y,宽地w,高h)
jsp.setBounds(10, 210, whidth - 25, height - 250);// (起始点x,起始点y,宽地w,高h)
}
});
}
public static String getErrorInfoFromException(Exception e) {
StringWriter sw = new StringWriter();
try (PrintWriter pw = new PrintWriter(sw);) {
e.printStackTrace(pw);
}
return sw.toString();
}
}
三、使用
打包成generateMysqlWord.jar,双击执行(需要JDK环境),界面如下:
输入相应参数即可。
四、说明
目前实现的功能很简单,其实还可以增加如忽略表的功能,但现在用不到。代码我已经上传到码云,项目地址:https://gitee.com/loveliyiyi/generate-mysql-word
有兴趣的可以关注下微信公共号。