springboot+freemarker實現生成資料庫設計Word文件
阿新 • • 發佈:2018-12-15
以前在專案完成後都會按照要求寫資料庫設計文件,表少的時候還無所謂,當有上百張表的時候就不好寫了。當然也有一些自動化軟體可以幫我們實現這個功能,但是自定義的程度比較低。所以今天自己來實現這個功能,可以按照自己的喜好定義樣式和模板,是不是很酷。
首先新建一個Word文件
然後另存為xml格式,用NotePad開啟。
在xml中使用freemarker的標籤將資料填充。不會freemarker的可以先自己研究一下。
<w:body> <wx:sect> //迴圈遍歷所有table <#list tables as table> <w:p wsp:rsidR="0017374B" wsp:rsidRPr="00481323" wsp:rsidRDefault="00AD2DC7"> <w:pPr> <w:rPr> <w:b/> <w:sz w:val="18"/> <w:sz-cs w:val="18"/> </w:rPr> </w:pPr> <w:r wsp:rsidRPr="00481323"> <w:rPr> <wx:font wx:val="宋體"/> <w:b/> <w:sz w:val="18"/> <w:sz-cs w:val="18"/> </w:rPr> <w:t>表名</w:t> </w:r> <w:r wsp:rsidRPr="00481323"> <w:rPr> <w:rFonts w:hint="fareast"/> <wx:font wx:val="宋體"/> <w:b/> <w:sz w:val="18"/> <w:sz-cs w:val="18"/> </w:rPr> <w:t>:</w:t> </w:r> <w:r wsp:rsidRPr="00481323"> <w:rPr> <w:b/> <w:sz w:val="18"/> <w:sz-cs w:val="18"/> </w:rPr> <w:t>${table.tableName} </w:t> </w:r> <w:r wsp:rsidRPr="00481323"> <w:rPr> <wx:font wx:val="宋體"/> <w:b/> <w:sz w:val="18"/> <w:sz-cs w:val="18"/> </w:rPr> <w:t>註釋</w:t> </w:r> <w:r wsp:rsidRPr="00481323"> <w:rPr> <w:rFonts w:hint="fareast"/> <wx:font wx:val="宋體"/> <w:b/> <w:sz w:val="18"/> <w:sz-cs w:val="18"/> </w:rPr> <w:t>:</w:t> </w:r> <w:r wsp:rsidR="005A39AB"> <w:rPr> <w:b/> <w:sz w:val="18"/> <w:sz-cs w:val="18"/> </w:rPr> <w:t>${table.tableComment} </w:t> </w:r> </w:p> <w:tbl> <w:tblPr> <w:tblW w:w="0" w:type="auto"/> <w:tblBorders> <w:top w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto"/> <w:left w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto"/> <w:bottom w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto"/> <w:right w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto"/> <w:insideH w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto"/> <w:insideV w:val="single" w:sz="4" wx:bdrwidth="10" w:space="0" w:color="auto"/> </w:tblBorders> <w:tblLook w:val="04A0"/> </w:tblPr> <w:tblGrid> <w:gridCol w:w="1659"/> <w:gridCol w:w="1659"/> <w:gridCol w:w="1659"/> <w:gridCol w:w="1659"/> <w:gridCol w:w="1660"/> </w:tblGrid> <w:tr wsp:rsidR="00DE1640" wsp:rsidRPr="00FA35C4" wsp:rsidTr="00FA35C4"> <w:tc> <w:tcPr> <w:tcW w:w="1659" w:type="dxa"/> <w:shd w:val="clear" w:color="auto" w:fill="AEAAAA"/> </w:tcPr> <w:p wsp:rsidR="00DE1640" wsp:rsidRPr="00FA35C4" wsp:rsidRDefault="00DE1640"> <w:pPr> <w:rPr> <w:sz w:val="18"/> <w:sz-cs w:val="18"/> </w:rPr> </w:pPr> <w:r wsp:rsidRPr="00FA35C4"> <w:rPr> <w:rFonts w:hint="fareast"/> <wx:font wx:val="宋體"/> <w:sz w:val="18"/> <w:sz-cs w:val="18"/> </w:rPr> <w:t>列名</w:t> </w:r> </w:p> </w:tc> <w:tc> <w:tcPr> <w:tcW w:w="1659" w:type="dxa"/> <w:shd w:val="clear" w:color="auto" w:fill="AEAAAA"/> </w:tcPr> <w:p wsp:rsidR="00DE1640" wsp:rsidRPr="00FA35C4" wsp:rsidRDefault="00DE1640"> <w:pPr> <w:rPr> <w:sz w:val="18"/> <w:sz-cs w:val="18"/> </w:rPr> </w:pPr> <w:r wsp:rsidRPr="00FA35C4"> <w:rPr> <w:rFonts w:hint="fareast"/> <wx:font wx:val="宋體"/> <w:sz w:val="18"/> <w:sz-cs w:val="18"/> </w:rPr> <w:t>資料型別</w:t> </w:r> </w:p> </w:tc> <w:tc> <w:tcPr> <w:tcW w:w="1659" w:type="dxa"/> <w:shd w:val="clear" w:color="auto" w:fill="AEAAAA"/> </w:tcPr> <w:p wsp:rsidR="00DE1640" wsp:rsidRPr="00FA35C4" wsp:rsidRDefault="00DE1640"> <w:pPr> <w:rPr> <w:sz w:val="18"/> <w:sz-cs w:val="18"/> </w:rPr> </w:pPr> <w:r wsp:rsidRPr="00FA35C4"> <w:rPr> <w:rFonts w:hint="fareast"/> <wx:font wx:val="宋體"/> <w:sz w:val="18"/> <w:sz-cs w:val="18"/> </w:rPr> <w:t>約束</w:t> </w:r> </w:p> </w:tc> <w:tc> <w:tcPr> <w:tcW w:w="1659" w:type="dxa"/> <w:shd w:val="clear" w:color="auto" w:fill="AEAAAA"/> </w:tcPr> <w:p wsp:rsidR="00DE1640" wsp:rsidRPr="00FA35C4" wsp:rsidRDefault="00DE1640"> <w:pPr> <w:rPr> <w:sz w:val="18"/> <w:sz-cs w:val="18"/> </w:rPr> </w:pPr> <w:r wsp:rsidRPr="00FA35C4"> <w:rPr> <w:rFonts w:hint="fareast"/> <wx:font wx:val="宋體"/> <w:sz w:val="18"/> <w:sz-cs w:val="18"/> </w:rPr> <w:t>允許空</w:t> </w:r> </w:p> </w:tc> <w:tc> <w:tcPr> <w:tcW w:w="1660" w:type="dxa"/> <w:shd w:val="clear" w:color="auto" w:fill="AEAAAA"/> </w:tcPr> <w:p wsp:rsidR="00DE1640" wsp:rsidRPr="00FA35C4" wsp:rsidRDefault="00DE1640"> <w:pPr> <w:rPr> <w:sz w:val="18"/> <w:sz-cs w:val="18"/> </w:rPr> </w:pPr> <w:r wsp:rsidRPr="00FA35C4"> <w:rPr> <w:rFonts w:hint="fareast"/> <wx:font wx:val="宋體"/> <w:sz w:val="18"/> <w:sz-cs w:val="18"/> </w:rPr> <w:t>備註</w:t> </w:r> </w:p> </w:tc> </w:tr> <#list table.columns as column> <w:tr wsp:rsidR="00DE1640" wsp:rsidRPr="00FA35C4" wsp:rsidTr="00FA35C4"> <w:tc> <w:tcPr> <w:tcW w:w="1659" w:type="dxa"/> <w:shd w:val="clear" w:color="auto" w:fill="auto"/> </w:tcPr> <w:p wsp:rsidR="00DE1640" wsp:rsidRPr="00FA35C4" wsp:rsidRDefault="00D01744"> <w:pPr> <w:rPr> <w:sz w:val="18"/> <w:sz-cs w:val="18"/> </w:rPr> </w:pPr> <w:r> <w:rPr> <w:rFonts w:hint="fareast"/> <w:sz w:val="18"/> <w:sz-cs w:val="18"/> </w:rPr> <w:t>${column.columnName}</w:t> </w:r> </w:p> </w:tc> <w:tc> <w:tcPr> <w:tcW w:w="1659" w:type="dxa"/> <w:shd w:val="clear" w:color="auto" w:fill="auto"/> </w:tcPr> <w:p wsp:rsidR="00DE1640" wsp:rsidRPr="00FA35C4" wsp:rsidRDefault="00D01744"> <w:pPr> <w:rPr> <w:sz w:val="18"/> <w:sz-cs w:val="18"/> </w:rPr> </w:pPr> <w:r> <w:rPr> <w:sz w:val="18"/> <w:sz-cs w:val="18"/> </w:rPr> <w:t>${column.columnType}</w:t> </w:r> </w:p> </w:tc> <w:tc> <w:tcPr> <w:tcW w:w="1659" w:type="dxa"/> <w:shd w:val="clear" w:color="auto" w:fill="auto"/> </w:tcPr> <w:p wsp:rsidR="00DE1640" wsp:rsidRPr="00FA35C4" wsp:rsidRDefault="00D01744"> <w:pPr> <w:rPr> <w:sz w:val="18"/> <w:sz-cs w:val="18"/> </w:rPr> </w:pPr> <w:r> <w:rPr> <w:sz w:val="18"/> <w:sz-cs w:val="18"/> </w:rPr> <w:t>${column.columnKey}</w:t> </w:r> </w:p> </w:tc> <w:tc> <w:tcPr> <w:tcW w:w="1659" w:type="dxa"/> <w:shd w:val="clear" w:color="auto" w:fill="auto"/> </w:tcPr> <w:p wsp:rsidR="00DE1640" wsp:rsidRPr="00FA35C4" wsp:rsidRDefault="001C4911"> <w:pPr> <w:rPr> <w:sz w:val="18"/> <w:sz-cs w:val="18"/> </w:rPr> </w:pPr> <w:r> <w:rPr> <w:sz w:val="18"/> <w:sz-cs w:val="18"/> </w:rPr> <w:t>${column.isNullable}</w:t> </w:r> </w:p> </w:tc> <w:tc> <w:tcPr> <w:tcW w:w="1660" w:type="dxa"/> <w:shd w:val="clear" w:color="auto" w:fill="auto"/> </w:tcPr> <w:p wsp:rsidR="00DE1640" wsp:rsidRPr="00FA35C4" wsp:rsidRDefault="003F3E19"> <w:pPr> <w:rPr> <w:sz w:val="18"/> <w:sz-cs w:val="18"/> </w:rPr> </w:pPr> <w:r> <w:rPr> <w:sz w:val="18"/> <w:sz-cs w:val="18"/> </w:rPr> <w:t>${column.columnComment}</w:t> </w:r> </w:p> </w:tc> </w:tr> </#list> </w:tbl> <w:p wsp:rsidR="00DE1640" wsp:rsidRDefault="00DE1640"> <w:pPr> <w:rPr> <w:sz w:val="18"/> <w:sz-cs w:val="18"/> </w:rPr> </w:pPr> </w:p> <w:p wsp:rsidR="00913083" wsp:rsidRPr="00481323" wsp:rsidRDefault="00913083"> <w:pPr> <w:rPr> <w:sz w:val="18"/> <w:sz-cs w:val="18"/> </w:rPr> </w:pPr> </w:p> <w:sectPr wsp:rsidR="00913083" wsp:rsidRPr="00481323" wsp:rsidSect="00BB620F"> <w:pgSz w:w="11906" w:h="16838"/> <w:pgMar w:top="1440" w:right="1800" w:bottom="1440" w:left="1800" w:header="851" w:footer="992" w:gutter="0"/> <w:cols w:space="425"/> <w:docGrid w:type="lines" w:line-pitch="312"/> </w:sectPr> </#list> </wx:sect> </w:body>
關鍵部分到了,從資料庫中獲取所有的表資訊並將資料填充到模板中生成doc檔案。
package com.dwl.mindoc.service; import com.dwl.mindoc.dao.BaseDao; import com.dwl.mindoc.database.BaseFactory; import com.dwl.mindoc.database.Database; import com.dwl.mindoc.domain.TableVo; import freemarker.template.Configuration; import freemarker.template.Template; import freemarker.template.TemplateException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.ResourceUtils; import javax.annotation.PostConstruct; import java.io.*; import java.util.HashMap; import java.util.List; import java.util.Map; /** * @program: mindoc * @description: generator * @author: daiwenlong * @create: 2018-10-13 13:00 **/ @Service public class GenerateService { private Logger logger = LoggerFactory.getLogger(getClass()); @Autowired private BaseFactory factory; @Autowired private BaseDao dao; @PostConstruct public void genertator(){ try { Database base = factory.getDataBase(); List<TableVo> tables = dao.getTables(base); tables.forEach(table->{ table.setColumns(dao.getColumns(base,table.getTableName())); logger.info("mindoc - TableName:{} TableComment:{} loading...",table.getTableName(),table.getTableComment()); }); makeDoc(tables); } catch (Exception e) { e.printStackTrace(); } } /** * 生成doc * @param tables * @return * @throws IOException * @throws TemplateException */ public void makeDoc(List<TableVo> tables){ logger.info("mindoc - makeDoc Satrting..."); // 第一步:建立一個Configuration物件。 Configuration configuration = new Configuration(Configuration.getVersion()); // 第二步:設定模板檔案所在的路徑。 try { configuration.setDirectoryForTemplateLoading(ResourceUtils.getFile("classpath:")); // 第三步:設定模板檔案使用的字符集。 configuration.setDefaultEncoding("utf-8"); // 第四步:載入一個模板,建立一個模板物件。 Template template = configuration.getTemplate("doc.xml"); // 第五步:建立一個模板使用的資料集。 Map<String,Object> dataModel = new HashMap<>(); dataModel.put("tables",tables); //生成檔案放在專案根目錄下 File outFile = new File(System.getProperty("user.dir")+"\\DatabaseDesign.doc"); Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile))); // 第六步:呼叫模板物件的process方法輸出檔案。 template.process(dataModel, out); logger.info("mindoc - MakeDoc succeeded."); logger.info("mindoc - Doc directory {}",outFile); } catch (IOException |TemplateException e) { logger.warn("mindoc - MakeDoc failed."); } } }
檢視控制檯資訊,檔案已經生成。
我們去檔案目錄下檢視文件。
是不是很方便,終於可以隨心所欲的寫Word了。除了能生成資料庫設計文件,我們還可以生成其他有固定模式的Word文件,大家可以根據自己業務場景試一試。
上面只貼了一部分程式碼,詳細程式碼可以到github上下載mindoc