一、概述
平常會遇到編寫文檔類的工作,尤其是數據庫的,要把每張表的詳細字段列出來,手寫實在費勁,從網上找了很多,都沒有那種直接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 [email protected]
* @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 [email protected]
* @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 [email protected]
* @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
有興趣的可以關注下微信公共號。