背景:
在作項目的時候,當時的數據庫文檔是txt格式,後來晉升爲doc格式。在開發過程當中,依舊以爲不方便。後來用動軟生成器,發現它能夠生成html和doc格式的數據庫文檔,html用起來相對輕鬆些。有一天突發奇想,如果弄成CHM文檔就行了。期間用過CHM工具一段時間。人是難以知足的,懶惰是永無止盡的。後來嫌棄操做太繁瑣,在博客園上一位牛人博客中學習了CHM編程。此後一直以代碼的方式生成CHM文檔。javascript
如今我將它作成了一個相對通用的工具,支持SQL2005及以上,Oracle。易拓展,方便有須要的朋友。css
資源下載:
文檔生成器html
示例文檔預覽java
源代碼數據庫
軟件及文檔截圖:
開發流程簡介:
1.讀取數據庫表以及表的描述信息。編程
SELECT Row_Number() over ( order by getdate() ) as 序號, case when a.colorder = 1 then d.name else '' end as 表名, case when a.colorder = 1 then isnull(f.value, '') else '' end as 表說明 FROM syscolumns a inner join sysobjects d on a.id = d.id and d.xtype = 'U' and d.name <> 'sys.extended_properties' left join sys.extended_properties f on a.id = f.major_id and f.minor_id = 0 where a.colorder = 1 and d.name<>'sysdiagrams'
SELECT TOP 100 PERCENT d.name as 表名, a.colorder AS 序號, a.name AS 列名, b.name AS 數據類型, a.length AS 長度, ISNULL(COLUMNPROPERTY(a.id, a.name, 'Scale'), 0) AS 小數位數, CASE WHEN COLUMNPROPERTY(a.id,a.name, 'IsIdentity') = 1 THEN '是' ELSE '' END AS 標識, CASE WHEN EXISTS (SELECT 1 FROM dbo.sysindexes si INNER JOIN dbo.sysindexkeys sik ON si.id = sik.id AND si.indid = sik.indid INNER JOIN dbo.syscolumns sc ON sc.id = sik.id AND sc.colid = sik.colid INNER JOIN dbo.sysobjects so ON so.name = si.name AND so.xtype = 'PK' WHERE sc.id = a.id AND sc.colid = a.colid) THEN '√' ELSE '' END AS 主鍵, CASE WHEN a.isnullable = 1 THEN '√' ELSE '' END AS 容許空, ISNULL(e.text, '') AS 默認值, ISNULL(g.[value], '') AS 列說明 FROM dbo.syscolumns a LEFT OUTER JOIN dbo.systypes b ON a.xtype = b.xusertype INNER JOIN dbo.sysobjects d ON a.id = d.id AND d.xtype = 'U' AND d.status >= 0 LEFT OUTER JOIN dbo.syscomments e ON a.cdefault = e.id LEFT OUTER JOIN sys.extended_properties g ON a.id = g.major_id AND a.colid = g.minor_id AND g.name = 'MS_Description' LEFT OUTER JOIN sys.extended_properties f ON d.id = f.major_id AND f.minor_id = 0 AND f.name = 'MS_Description' ORDER BY d.name, 序號
select ROWNUM 序號 ,ut.table_name 表名,utc.comments 表說明 from user_tables ut left join user_tab_comments utc on ut.table_name = utc.table_name order by ut.table_name
select row_number()over( partition by utc.table_name order by utc.COLUMN_ID, ROWNUM ) as 序號, utc.table_name as 表名, utc.column_name as 列名, utc.data_type as 數據類型, utc.data_length as 長度, utc.data_precision as 精度, utc.data_Scale 小數位數, case when exists ( select col.column_name from user_constraints con,user_cons_columns col where con.constraint_name=col.constraint_name and con.constraint_type='P' and col.table_name=ucc.table_name and col.column_name = utc.column_name ) then '√' else '' end as 主鍵, case when utc.nullable = 'Y' then '√' else '' end as 容許空, utc.data_default as 默認值, ucc.comments as 列說明 from user_tab_columns utc,user_col_comments ucc where utc.table_name = ucc.table_name and utc.column_name = ucc.column_name order by utc.table_name,序號
2.獲取用戶選擇的表,獲取該表的全部字段信息,構建html,存儲在tmp臨時目錄。架構
/* ============================================================================== * 文 件 名:DbCommon * 功能描述: * Copyright (c) 2012 武漢經緯視通科技有限公司 * 創 建 人: chenbo * 建立時間: 2013/3/18 15:21:25 * 修 改 人: * 修改時間: * 修改描述: * 版 本: v1.0.0.0 * ==============================================================================*/ using System; using System.Collections.Generic; using System.Data; using System.IO; using System.Text; using Chen.Ext; namespace Chen.DB { /// <summary> /// 經常使用功能類 /// </summary> public class DbCommon { #region 導出表數據爲html格式 /// <summary> /// 導出表數據爲html格式 居中表格樣式 /// </summary> /// <param name="dt">DataTable,須要給TableName賦值</param> /// <param name="KeepNull">保持Null爲Null值,不然爲空</param> /// <param name="Path">保存路徑</param> /// <param name="hasReturn">攜帶返回目錄連接</param> /// <param name="tableDesc">攜帶返回目錄連接</param> public static void CreateHtml(DataTable dt, bool KeepNull, string Path, bool hasReturn = true, string tableDesc = "") { var code = new StringBuilder(); code.AppendLine("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">"); code.AppendLine("<html xmlns=\"http://www.w3.org/1999/xhtml\">"); code.AppendLine("<head>"); code.AppendLine(" <title>{0}</title>".FormatString(dt.TableName)); code.AppendLine(" <style type=\"text/css\">"); code.AppendLine(" body"); code.AppendLine(" {"); code.AppendLine(" font-size: 9pt;"); code.AppendLine(" }"); code.AppendLine(" .styledb"); code.AppendLine(" {"); code.AppendLine(" font-size: 14px;"); code.AppendLine(" }"); code.AppendLine(" .styletab"); code.AppendLine(" {"); code.AppendLine(" font-size: 14px;"); code.AppendLine(" padding-top: 15px;"); code.AppendLine(" }"); code.AppendLine(" a"); code.AppendLine(" {"); code.AppendLine(" color: #015FB6;"); code.AppendLine(" }"); code.AppendLine(" a:link, a:visited, a:active"); code.AppendLine(" {"); code.AppendLine(" color: #015FB6;"); code.AppendLine(" text-decoration: none;"); code.AppendLine(" }"); code.AppendLine(" a:hover"); code.AppendLine(" {"); code.AppendLine(" color: #E33E06;"); code.AppendLine(" }"); code.AppendLine(" </style>"); code.AppendLine("</head>"); code.AppendLine("<body>"); code.AppendLine(" <div style=\"text-align: center\">"); code.AppendLine(" <div>"); code.AppendLine(" <table border=\"0\" cellpadding=\"5\" cellspacing=\"0\" width=\"90%\">"); code.AppendLine(" <tr>"); code.AppendLine(" <td bgcolor=\"#FBFBFB\">"); code.AppendLine(" <table cellspacing=\"0\" cellpadding=\"5\" border=\"1\" width=\"100%\" bordercolorlight=\"#D7D7E5\" bordercolordark=\"#D3D8E0\">"); code.AppendLine(" <caption>"); code.AppendLine(" <div class=\"styletab\">{0}{1}{2}</div>".FormatString( dt.TableName, tableDesc.Length == 0 ? string.Empty : " (" + tableDesc + ") ", hasReturn ? "<a href='../數據庫表目錄.html' style='float: right; margin-top: 6px;'>返回目錄</a>" : string.Empty)); code.AppendLine(" </caption>"); code.AppendLine(" <tr bgcolor=\"#F0F0F0\">"); //構建表頭 foreach (DataColumn dc in dt.Columns) { code.AppendLine(" <td>{0}</td>".FormatString(dc.ColumnName)); } code.AppendLine(" </tr>"); //構建數據行 foreach (DataRow dr in dt.Rows) { code.AppendLine(" <tr>"); foreach (DataColumn dc in dt.Columns) { if (KeepNull && dr[dc.ColumnName] == DBNull.Value) { code.AppendLine(" <td> </td>"); } else { code.AppendLine(" <td>{0}</td>".FormatString( dr[dc.ColumnName].ToString().Trim().Length > 0 ? dr[dc.ColumnName].ToString() : " ")); } } code.AppendLine(" </tr>"); } code.AppendLine(" </table>"); code.AppendLine(" </td>"); code.AppendLine(" </tr>"); code.AppendLine(" </table>"); code.AppendLine(" </div>"); code.AppendLine(" </div>"); code.AppendLine("</body>"); code.AppendLine("</html>"); File.WriteAllText(Path, code.ToString(), Encoding.GetEncoding("gb2312")); //File.WriteAllText(Path, code.ToString(), Encoding.UTF8); } /// <summary> /// 導出表數據爲html格式 Oracle導出格式 帶搜索框 /// </summary> /// <param name="dt">DataTable,須要給TableName賦值</param> /// <param name="KeepNull">保持Null爲Null值,不然爲空</param> /// <param name="Path">保存路徑</param> public static void CreateHtml2(DataTable dt, bool KeepNull, string Path) { var code = new StringBuilder(); code.AppendLine("<html>"); code.AppendLine("<head>"); code.AppendLine(" <title>J{0}</title>".FormatString(dt.TableName)); code.AppendLine(" <meta http-equiv=\"content-type\" content=\"text/html; charset=GBK\">"); code.AppendLine(" <style type=\"text/css\">"); code.AppendLine(" table"); code.AppendLine(" {"); code.AppendLine(" background-color: #F2F2F5;"); code.AppendLine(" border-width: 1px 1px 0px 1px;"); code.AppendLine(" border-color: #C9CBD3;"); code.AppendLine(" border-style: solid;"); code.AppendLine(" }"); code.AppendLine(); code.AppendLine(" td"); code.AppendLine(" {"); code.AppendLine(" color: #000000;"); code.AppendLine(" font-family: Tahoma,Arial,Helvetica,Geneva,sans-serif;"); code.AppendLine(" font-size: 9pt;"); code.AppendLine(" background-color: #EAEFF5;"); code.AppendLine(" padding: 8px;"); code.AppendLine(" background-color: #F2F2F5;"); code.AppendLine(" border-color: #ffffff #ffffff #cccccc #ffffff;"); code.AppendLine(" border-style: solid solid solid solid;"); code.AppendLine(" border-width: 1px 0px 1px 0px;"); code.AppendLine(" }"); code.AppendLine(); code.AppendLine(" th"); code.AppendLine(" {"); code.AppendLine(" font-family: Tahoma,Arial,Helvetica,Geneva,sans-serif;"); code.AppendLine(" font-size: 9pt;"); code.AppendLine(" padding: 8px;"); code.AppendLine(" background-color: #CFE0F1;"); code.AppendLine(" border-color: #ffffff #ffffff #cccccc #ffffff;"); code.AppendLine(" border-style: solid solid solid none;"); code.AppendLine(" border-width: 1px 0px 1px 0px;"); code.AppendLine(" white-space: nowrap;"); code.AppendLine(" }"); code.AppendLine(" a:link, a:visited, a:active"); code.AppendLine(" {"); code.AppendLine(" color: #015FB6;"); code.AppendLine(" text-decoration: none;"); code.AppendLine(" }"); code.AppendLine(" a:hover"); code.AppendLine(" {"); code.AppendLine(" color: #E33E06;"); code.AppendLine(" }"); code.AppendLine(" </style>"); code.AppendLine(" <script type=\"text/javascript\">"); code.AppendLine(" window.apex_search = {};"); code.AppendLine(" apex_search.init = function () {"); code.AppendLine(" this.rows = document.getElementById('data').getElementsByTagName('TR');"); code.AppendLine(" this.rows_length = apex_search.rows.length;"); code.AppendLine(" this.rows_text = [];"); code.AppendLine(" for (var i = 0; i < apex_search.rows_length; i++) {"); code.AppendLine(" this.rows_text[i] = (apex_search.rows[i].innerText) ? apex_search.rows[i].innerText.toUpperCase() : apex_search.rows[i].textContent.toUpperCase();"); code.AppendLine(" }"); code.AppendLine(" this.time = false;"); code.AppendLine(" }"); code.AppendLine(); code.AppendLine(" apex_search.lsearch = function () {"); code.AppendLine(" this.term = document.getElementById('S').value.toUpperCase();"); code.AppendLine(" for (var i = 0, row; row = this.rows[i], row_text = this.rows_text[i]; i++) {"); code.AppendLine(" row.style.display = ((row_text.indexOf(this.term) != -1) || this.term === '') ? '' : 'none';"); code.AppendLine(" }"); code.AppendLine(" this.time = false;"); code.AppendLine(" }"); code.AppendLine(); code.AppendLine(" apex_search.search = function (e) {"); code.AppendLine(" var keycode;"); code.AppendLine(" if (window.event) { keycode = window.event.keyCode; }"); code.AppendLine(" else if (e) { keycode = e.which; }"); code.AppendLine(" else { return false; }"); code.AppendLine(" if (keycode == 13) {"); code.AppendLine(" apex_search.lsearch();"); code.AppendLine(" }"); code.AppendLine(" else { return false; }"); code.AppendLine(" }</script>"); code.AppendLine("</head>"); code.AppendLine("<body onload=\"apex_search.init();\">"); code.AppendLine(" <table border=\"0\" cellpadding=\"0\" cellspacing=\"0\">"); code.AppendLine(" <tbody>"); code.AppendLine(" <tr> "); code.AppendLine(" <td>"); code.AppendLine(" <input type=\"text\" size=\"30\" maxlength=\"1000\" value=\"\" id=\"S\" onkeyup=\"apex_search.search(event);\" /><input type=\"button\" value=\"Search\" onclick=\"apex_search.lsearch();\" />"); code.AppendLine(" </td>"); code.AppendLine(" <td>"); code.AppendLine(" " + dt.TableName); code.AppendLine(" </td>"); code.AppendLine(" </tr>"); code.AppendLine(" </tbody>"); code.AppendLine(" </table>"); code.AppendLine(" <br />"); code.AppendLine(" <table border=\"0\" cellpadding=\"0\" cellspacing=\"0\">"); code.AppendLine(" <tr>"); foreach (DataColumn dc in dt.Columns) { code.AppendLine(" <th>{0}</th>".FormatString(dc.ColumnName)); } code.AppendLine(" </tr>"); code.AppendLine(" <tbody id=\"data\">"); foreach (DataRow dr in dt.Rows) { code.AppendLine(" <tr>"); foreach (DataColumn dc in dt.Columns) { if (KeepNull && dr[dc.ColumnName] == DBNull.Value) { //code.AppendLine(" <td>{0}</td>".FormatString(dr[dc.ColumnName].ToString())); code.AppendLine(" <td> </td>"); } else// align=\"right\" { code.AppendLine(" <td>{0}</td>".FormatString( dr[dc.ColumnName].ToString().Length > 0 ? dr[dc.ColumnName].ToString() : " ")); } } code.AppendLine(" </tr>"); } code.AppendLine(" </tbody>"); code.AppendLine(" </table>"); code.AppendLine("</body>"); code.AppendLine("</html>"); File.WriteAllText(Path, code.ToString(), Encoding.GetEncoding("gb2312")); } #endregion } }
3.在建立好全部的html以後,下一步編譯成chm文檔。編譯以前,須要準備3個文件,hhc,hhp,hhk。分別是CHM格式文件的內容文件、編譯參數文件、索引文件。文件的格式簡單易懂。對比文件夾的內容以及文件夾層次結構,看一下就能夠有點清楚了。這裏仍是簡單的貼一下吧,方便你們的瞭解。ide
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> <HTML> <HEAD> <meta name="GENERATOR" content="EasyCHM.exe www.zipghost.com"> <!-- Sitemap 1.0 --> </HEAD><BODY> <OBJECT type="text/site properties"> <param name="ExWindow Styles" value="0x200"> <param name="Window Styles" value="0x800025"> <param name="Font" value="MS Sans Serif,9,0"> </OBJECT> <UL> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="數據庫表目錄"> <param name="Local" value="數據庫表目錄.html"> <param name="ImageNumber" value="11"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="表結構"> <param name="ImageNumber" value="1"> </OBJECT> <UL> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="Code "> <param name="Local" value="表結構\Code .html"> <param name="ImageNumber" value="11"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="Files 文件列表"> <param name="Local" value="表結構\Files 文件列表.html"> <param name="ImageNumber" value="11"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="Menus 菜單表"> <param name="Local" value="表結構\Menus 菜單表.html"> <param name="ImageNumber" value="11"> </OBJECT> </UL> </UL> </BODY></HTML>
[OPTIONS]
CITATION=Made by Jinwin
Compatibility=1.1 or later
Compiled file=D:\數據庫幫助文檔.chm
Contents file=chm.HHC
COPYRIGHT=www.jinwin.net
Default topic=數據庫表目錄.html
Default Window=Main
Display compile notes=Yes
Display compile progress=Yes
Full-text search=Yes
Index file=chm.HHK
Title=數據庫幫助文檔
Enhanced decompilation=yes
[WINDOWS]
Main="數據庫幫助文檔","chm.hhc","chm.hhk","數據庫表目錄.html","數據庫表目錄.html",,,,,0x63520,180,0x104E, [0,0,745,509],0x0,0x0,,,,,0
[MERGE FILES]
[FILES]
E:\個人代碼\Winform\DBDcoumentCreater\DBDcoumentCreater\bin\Debug\tmp\數據庫表目錄.html
E:\個人代碼\Winform\DBDcoumentCreater\DBDcoumentCreater\bin\Debug\tmp\表結構\Code .html
E:\個人代碼\Winform\DBDcoumentCreater\DBDcoumentCreater\bin\Debug\tmp\表結構\Files 文件列表.html
E:\個人代碼\Winform\DBDcoumentCreater\DBDcoumentCreater\bin\Debug\tmp\表結構\Menus 菜單表.html
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> <HTML> <HEAD> <meta name="GENERATOR" content="EasyCHM.exe www.zipghost.com"> <!-- Sitemap 1.0 --> </HEAD><BODY> <OBJECT type="text/site properties"> <param name="ExWindow Styles" value="0x200"> <param name="Window Styles" value="0x800025"> <param name="Font" value="MS Sans Serif,9,0"> </OBJECT> <UL> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="數據庫表目錄"> <param name="Local" value="數據庫表目錄.html"> <param name="ImageNumber" value="11"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="Code "> <param name="Local" value="表結構\Code .html"> <param name="ImageNumber" value="11"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="Files 文件列表"> <param name="Local" value="表結構\Files 文件列表.html"> <param name="ImageNumber" value="11"> </OBJECT> <LI> <OBJECT type="text/sitemap"> <param name="Name" value="Menus 菜單表"> <param name="Local" value="表結構\Menus 菜單表.html"> <param name="ImageNumber" value="11"> </OBJECT> </UL> </BODY></HTML>
4.chm編譯前的相關文件生成完畢後,開始調用微軟的hhc文件,通常系統都有,我也只在win7上作過測試。測試不足的話,還請見諒。路徑爲:工具
C:\Program Files (x86)\HTML Help Workshop\hhc.exe 。傳入指定的參數,就能夠獲得chm文件了。
5.最後一步則是清理垃圾了。刪除掉這些臨時文件臨時文件夾就行了。
最後:
感興趣的朋友能夠下載可執行程序看看,有須要源碼的朋友留言吧,幫忙消滅萬惡的零回覆,順手點個推薦吧,您的關注是給我最大的鼓勵,謝謝!
更新:
1.修復了26樓朋友提出的問題:Oracle查詢數據的SQL錯誤。(2013-03-22)
2.增長鏈接字符串配置嚮導。(2013-03-23)
3.攜帶hhc.exe,避免有些系統缺乏該文件。(2013-03-24)
4.棄用hhc.exe。直接使用hha.dll提供的接口。修復表目錄老是導出所有而非選中的表的問題。(2013-03-27)
5.整合SQL選項,生成Html文件時gb2312編碼,避免部分系統IE自動解析編碼錯誤。(2013-04-01)
每一次修改,發佈的可執行程序和源碼均同步更新,連接不變。