Java將SQL轉爲數據結構表(辦公用)

/**
 * @author shany
 * @date 2018年9月18日 上午9:00:47 
 * @version V1.0  
 */
package shany;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.HSSFColor;

//將sql文件中內容轉爲excel數據表
public class Sql_Excel {

	// 要讀取的數據類型,可以根據需求自己添加和修改
	String type_list[] = { "numeric", "nvarchar", "datetime", "ntext",
			"int", "bit", "decimal" };

	// #################################################################
	// 解析sql文本內容 --start
	// 讀取指定路徑下文件
	public String read_file(String source) {
		StringBuilder buf = new StringBuilder();
		BufferedReader bufferedReader;
		try {
			bufferedReader = new BufferedReader(new FileReader(source));
			while (bufferedReader.ready()) {
				buf.append(bufferedReader.readLine() + "\r\n");
			}
			bufferedReader.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			System.out.println("文件路徑錯誤");
		} catch (IOException e) {
			e.printStackTrace();
			System.out.println("文件讀取失敗");
		}
		return buf.substring(0, buf.length() - 2);
	}

	// 根據每行內容逐行解析
	public void read_analyze(String source) {
		// 如果出現亂碼則執行下面語句,轉之前編碼是指讀取的文件編碼內容,要轉的編碼是指你當前編譯器的編碼格式
		/*
		 * try { source=new String(source.getBytes("轉之前編碼"), "要轉的編碼"); } catch
		 * (UnsupportedEncodingException e) { e.printStackTrace();
		 * System.out.println("編碼格式轉換失敗"); }
		 */
		// 這個語句有一點問題,有的數據庫區分大小寫,如果區分就去掉toLowerCase
		String ss[] = source.toLowerCase().split("\r\n");
		core(ss, 0);
	}

	// 判斷該行SQL中是否包含type_list數組中的類型
	public String get_type(String str) {
		for (String s : type_list)
			if (str.indexOf(s) != -1)
				return s;
		
		return null;
	}

	// 解析內容-算法部分
	public void core(String ss[], int start) {
		List<String[]> list = new ArrayList<String[]>(); // 表內容
		String tableName = ""; // 表名
		String tableHeader[] = { "序號", "字段名", "字段意義", "字段類型", "是否主鍵", "外鍵關聯",
				"允許爲空" };
		for (int j = start; j < ss.length; j++) {
			// 如果找到了創建該表的sql語句開頭
			int num = 1;
			if (findOne(ss[j], "go")) {
				for (int i = j; i < ss.length; i++) {
					System.out.println(ss[i]);
					// 序號,字段名,字段意義,字段類型,是否主鍵,外鍵關聯,允許爲空
					String obj[] = new String[7];
					// 確定表的中文名
					if (ss[i].indexOf("--") == 0 && i >= 1
							&& findOne(ss[i - 1], "go"))
						tableName = ss[i].substring(2, ss[i].length())
								.replaceAll(" ", "");
					/*
					 * else if (ss[i + 2].indexOf("--") != -1) tableName = ss[i
					 * + 1].substring(2, ss[i].length()) .replaceAll(" ", "");
					 */
					// 判斷表的英文名
					if (ss[i].indexOf("create table ") != -1) {
						tableName += "——"
								+ ss[i].substring("create table ".length(),
										ss[i].indexOf("(")).replaceAll(" ", "");
					} else {
						// 判斷是否是主鍵
						if (ss[i].indexOf("primary key") != -1) {
							obj[4] = "主鍵";
							obj[6] = "不允許";
						}
						// 判斷是否是外鍵
						else if (ss[i].indexOf("references") != -1) {
							// System.out.println("index="+ss[i].lastIndexOf(")"
							// ));
							obj[5] = ss[i].substring(
									ss[i].indexOf("references") + 10,
									ss[i].lastIndexOf(")") + 1).replaceAll(" ",
									"");
						}
						// 添加字段意義信息
						if (ss[i].indexOf("--") != -1) {
							obj[2] = ss[i].substring(ss[i].indexOf("--") + 2,
									ss[i].length()).replaceAll(" ", "");
						}
						if (ss[i].indexOf("not null") != -1) {
							obj[6] = "不允許";
						}
						// 判斷字段類型( numeric , nvarchar , datetime , ntext )
						if (get_type(ss[i]) != null) {
							obj[0] = num++ + "";
							obj[1] = ss[i].substring(0,
									ss[i].indexOf(get_type(ss[i]))).replaceAll(
									" ", "");
							obj[3] = get_type(ss[i]);
						}
					
						// 判斷數據是否符合條件,將符合條件的數據加入list中
						if (obj != null && obj[1] != null
								&& !"".equals(obj[1].replaceAll(" ", "")))
							list.add(obj);
					}
					// 判斷何時結束開始新一輪的查找
					if (findOne(ss[i], ");")) {
						// 將整理好的數據解析
						if (tableName == null
								|| "".equals(tableName.replaceAll(" ", ""))) {
							tableName = "用戶數據表";
						}
						// 寫入到Excel中
						ReadToExcel(list, tableName, tableHeader);
						// 遞歸調用
						core(ss, i);
						// 結束當前function,防止內存溢出
						return;
					}

				}

			}

		}
	}

	/**
	 * @Title: ReadToExcel
	 * @Description: 解析的數據轉爲Excel
	 * @author shany
	 * @date 2018年9月20日 下午2:36:05
	 */
	private void ReadToExcel(List<String[]> list, String tableName,
			String[] tableHeader) {
		// 數據導出
		if (list != null && list.size() > 0) {
			// test
			System.out.println("tableName=" + tableName);
			System.out.println("tableHeader=" + Arrays.toString(tableHeader));
			System.out.println("list.size=" + list.size());
			String sss[][] = new String[list.size()][7];
			for (int i = 0; i < list.size(); i++) {
				sss[i] = list.get(i);
			}
			// 文件名
			String path ="F:/"+ tableName  +"數據表.xls";
			try {
				exporteExcel(tableName, tableHeader, sss, new FileOutputStream(
						path));
				System.out.println("導出" + tableName + "成功");
			} catch (FileNotFoundException e) {
				System.out.println("導出" + tableName + "失敗");
				e.printStackTrace();
			}
		}
	}

	// 指定要保存的文件位置

	// 該行是否包含指定內容
	public boolean findOne(String source, String item) {
		if (source == null || "".equals(source) || item == null
				|| "".equals(item))
			return false;
		return source.indexOf(item) != -1;
	}

	// 解析sql文本內容 --end
	// #################################################################
	// list轉爲Excel導出 --start
	/**
	 * 導出excel文件
	 * 
	 * @param title
	 *            表sheet的名字
	 * @param headers
	 *            表頭
	 * @param dataList
	 *            正文單元格
	 * @param out
	 *            輸出流
	 */
	public void exporteExcel(String title, String[] headers,
			String[][] dataList, OutputStream out) {
		HSSFWorkbook workBook = new HSSFWorkbook();
		createSheet(title, headers, dataList, workBook);
//		createSheet(title + "2", headers, dataList, workBook);
		try {
			workBook.write(out);
		} catch (IOException e) {
			System.out.println("寫入文件失敗" + e.getMessage());
		}
	}

	/**
	 * 創建sheet
	 * 
	 * @param title
	 *            sheet的名字
	 * @param headers
	 *            表頭
	 * @param dataList
	 *            正文單元格
	 */
	private void createSheet(String title, String[] headers,
			String[][] dataList, HSSFWorkbook workBook) {
		HSSFSheet sheet = workBook.createSheet(title);
		// sheet.setDefaultColumnWidth(15);
		// 設置表頭和普通單元格的格式
		HSSFCellStyle headStyle = setHeaderStyle(workBook);
		HSSFCellStyle bodyStyle = setBodyStyle(workBook);

		createBody(dataList, sheet, bodyStyle);
		createHeader(headers, sheet, headStyle);
	}

	/**
	 * 創建正文單元格
	 * 
	 * @param dataList
	 *            數據數組
	 * @param sheet
	 *            表
	 * @param bodyStyle
	 *            單元格格式
	 */
	private void createBody(String[][] dataList, HSSFSheet sheet,
			HSSFCellStyle bodyStyle) {
		for (int a = 0; a < dataList.length; a++) {
			HSSFRow row = sheet.createRow(a + 1);
			for (int j = 0; j < dataList[a].length; j++) {
				HSSFCell cell = row.createCell(j);
				cell.setCellStyle(bodyStyle);
				HSSFRichTextString textString = new HSSFRichTextString(
						dataList[a][j]);
				cell.setCellValue(textString);
			}
		}
	}

	/**
	 * 創建表頭
	 * 
	 * @param headers
	 *            表頭
	 * @param sheet
	 *            表
	 * @param headStyle
	 *            表頭格式
	 */
	private void createHeader(String[] headers, HSSFSheet sheet,
			HSSFCellStyle headStyle) {
		HSSFRow row = sheet.createRow(0);
		for (int i = 0; i < headers.length; i++) {
			HSSFCell cell = row.createCell(i);
			cell.setCellStyle(headStyle);
			HSSFRichTextString textString = new HSSFRichTextString(headers[i]);
			cell.setCellValue(textString);
			sheet.autoSizeColumn((short) i);
		}
	}

	/**
	 * 設置正文單元格格式
	 * 
	 * @param workBook
	 * @return
	 */
	private HSSFCellStyle setBodyStyle(HSSFWorkbook workBook) {
		HSSFCellStyle style2 = workBook.createCellStyle();
		style2.setFillForegroundColor(HSSFColor.WHITE.index);
		style2.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
		style2.setBorderBottom(HSSFCellStyle.BORDER_THIN);
		style2.setBorderLeft(HSSFCellStyle.BORDER_THIN);
		style2.setBorderRight(HSSFCellStyle.BORDER_THIN);
		style2.setBorderTop(HSSFCellStyle.BORDER_THIN);
		style2.setAlignment(HSSFCellStyle.ALIGN_LEFT);

		HSSFFont font2 = workBook.createFont();
		font2.setFontName("微軟雅黑");
		font2.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL);
		style2.setFont(font2);
		return style2;
	}

	/**
	 * 設置表頭格式
	 * 
	 * @param workBook
	 * @return
	 */
	private HSSFCellStyle setHeaderStyle(HSSFWorkbook workBook) {
		HSSFCellStyle style = workBook.createCellStyle();
		style.setFillForegroundColor(HSSFColor.LIGHT_YELLOW.index);
		style.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
		style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
		style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
		style.setBorderRight(HSSFCellStyle.BORDER_THIN);
		style.setBorderTop(HSSFCellStyle.BORDER_THIN);
		style.setAlignment(HSSFCellStyle.ALIGN_LEFT);

		HSSFFont font = workBook.createFont();
		font.setFontName("微軟雅黑");
		font.setFontHeightInPoints((short) 12);
		font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
		style.setFont(font);
		return style;
	}

	// list轉爲Excel導出 --end
	// #################################################################

	// 直接調用次方法即可,傳入目標文件路徑
	public void run(String source) {
		String result = read_file(source);
		read_analyze(result);

	}

	// 主函數
	public static void main(String[] args) {
		String source = "E:/aa.txt";
		// Sql_Excel se= new Sql_Excel();
		new Sql_Excel().run(source);
	}

}

備註:因爲前段時間做個SQL轉爲數據庫結構表的,一直複製粘貼太累,所以寫了一個Java腳本。對了,其中數據寫到Excel是使用一位前輩實現好的function(重複造輪子不可取)

他的那篇博客鏈接:利用poi將數據寫入到excel

一下是我推薦的SQL語句書寫規範(sqlserver)

go 
--aaa表
create table a_aas_a( 
	aaa numeric(20,0) IDENTITY PRIMARY KEY NOT NULL,--主鍵
	aaa numeric(20,0) REFERENCES ORG_EMPLOYEE(EMP_ID) NOT NULL,--aaa 
	aaa numeric(10,1),--aaa 
	aaa ntext,--aaa 
	aaa numeric(20,0),--aaa 
	aaa numeric(10,0),--aaa 
	aaa nvarchar(200),--aaa 
	aaa numeric(10,0),--aaa 
	aaa nvarchar(200),--aaa 
	aaa ntext,--aaa 
	aaa ntext,--aaa 
	aaa datetime,--aaa 
	aaa numeric(5,0)--aaa 
);

##############################################################################################

輸出結果

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章