最近项目在走验收流程,之前没有仔细看SOW文档,发现需要补好多份文档,其中就有数据字典,项目组不愿意花时间太多的时间弄这些文档,也不希望以后还要重复劳动力,最终决定做一个工具,方便自己生成数据字典文档。

  这里只是分享一下开发的思路和经历(如果发现有问题,请及时告诉我,我会即时纠正,以免误导他人,欢迎大家多多指点)

  工具的界面大体如下:

  

  需要完成的任务:

  1. 投影未脱机的数据库列表(使用T-SQL)
  2. 投影当前数据库的表列表(使用T-SQL)
  3. 投影某表的字段信息列表(使用T-SQL)
  4. 使用OpenXml新建总文档
  5. 使用OpenXml开始生成单张表的数据字典,替换书签
  6. 使用OpenXml添加表格,完成单张表的数据字典docx文档
  7. 使用OpenXml将当前文档合并成到总文档中

一、投影未脱机的数据库列表(使用T-SQL)

SELECT Name FROM Master..SysDatabases WHERE STATUS = 65536 ORDER BY Name

二、投影当前数据库的表列表(使用T-SQL)

USE TestDB;SELECT Name FROM SysObjects Where XType='U' ORDER BY Name DESC

三、投影某表的字段信息列表(使用T-SQL)

USE TestDB;
SELECT
a.name 字段名 ,
( CASE WHEN COLUMNPROPERTY(a.id, a.name, 'IsIdentity') = 1 THEN '√' ELSE ''
END ) 标识 ,
( CASE WHEN ( SELECT COUNT(*)
FROM sysobjects
WHERE ( name IN (
SELECT name
FROM sysindexes
WHERE ( id = a.id )
AND ( indid IN (
SELECT indid
FROM sysindexkeys
WHERE ( id = a.id )
AND ( colid IN (
SELECT
colid
FROM
syscolumns
WHERE
( id = a.id )
AND ( name = a.name ) ) ) ) ) ) )
AND ( xtype = 'PK' )
) > 0 THEN '√'
ELSE ''
END ) 主键 ,
( CASE b.name
WHEN 'varchar' THEN b.name + '(' + cast(a.length as varchar(8)) + ')'
WHEN 'nvarchar' THEN b.name + '(' + cast(a.length as varchar(8)) + ')'
ELSE b.name
END ) 类型 ,
( CASE WHEN a.isnullable = 1 THEN '√' ELSE ''END ) 允许空 ,
( CASE a.name WHEN 'Id' THEN 'Id'
WHEN 'AddTime' THEN '添加时间'
WHEN 'UpdateTime' THEN '修改时间'
WHEN 'IsValid' THEN '删除标记'
WHEN 'AddIp' THEN '添加IP地址'
WHEN 'UpdateIp' THEN '修改IP地址'
WHEN 'State' THEN '状态'
WHEN 'PicUrl' THEN '图片地址'
WHEN 'Image' THEN '图片地址'
WHEN 'Description' THEN '介绍'
WHEN 'Title' THEN '标题'
WHEN 'Note' THEN '备注'
WHEN 'Type' THEN '类型'
WHEN 'Content' THEN '内容'
END ) 字段中文名,
ISNULL(e.text, '') 默认值,
'' as 备注
FROM syscolumns a
LEFT JOIN systypes b ON a.xtype = b.xusertype
INNER JOIN sysobjects d ON a.id = d.id
AND d.xtype = 'U'
AND d.name <> 'dtproperties'
LEFT JOIN syscomments e ON a.cdefault = e.id
LEFT JOIN sys.extended_properties g ON a.id = g.major_id
AND a.colid = g.minor_id
LEFT JOIN sys.extended_properties f ON d.id = f.class
AND f.minor_id = 0
WHERE b.name IS NOT NULL
and d.name='Account'
ORDER BY a.id ,
a.colorder;

四、使用OpenXml新建总文档

tmplFilePath是临时存放各个表数据字典的文件夹

string path = string.Format(@"{0}{1}.docx", tmplFilePath, DateTime.Now.Ticks.ToString());
using (WordprocessingDocument doc = WordprocessingDocument.Create(path, WordprocessingDocumentType.Document))
{
MainDocumentPart mainPart = doc.AddMainDocumentPart();
mainPart.Document = new Document();
Body body = mainPart.Document.AppendChild(new Body());
Paragraph p = mainPart.Document.Body.AppendChild(new Paragraph());
p.AppendChild(new Run(new Text("数据字典")));
}

五、使用OpenXml开始生成单张表的数据字典,替换书签

tmplFileName是单张表的数据字典文档路径

using (WordprocessingDocument tmplDoc = WordprocessingDocument.Open(tmplFileName, true))
{
//修改文档类型 (dotx->docx)
tmplDoc.ChangeDocumentType(WordprocessingDocumentType.Document); var bookMarks = FindBookmarks(tmplDoc.MainDocumentPart.Document);
//替换书签
foreach (var end in bookMarks)
{
if (end.Key == "TableName")
{
var textElement = new Text(tableName);
var runElement = new Run(textElement);
end.Value.InsertAfterSelf(runElement);
}
}
}

下面是FindBookmarks方法

private Dictionary<string, BookmarkEnd> FindBookmarks(OpenXmlElement documentPart, Dictionary<string, BookmarkEnd> results = null, Dictionary<string, string> unmatched = null)
{
results = results ?? new Dictionary<string, BookmarkEnd>();
unmatched = unmatched ?? new Dictionary<string, string>(); foreach (var child in documentPart.Elements())
{
if (child is BookmarkStart)
{
var bStart = child as BookmarkStart;
unmatched.Add(bStart.Id, bStart.Name);
} if (child is BookmarkEnd)
{
var bEnd = child as BookmarkEnd;
foreach (var orphanName in unmatched)
{
if (bEnd.Id == orphanName.Key)
results.Add(orphanName.Value, bEnd);
}
} FindBookmarks(child, results, unmatched);
} return results;
}

六、使用OpenXml添加表格,完成单张表的数据字典docx文档

//设置表格属性
TableProperties tblProp = new TableProperties(
new TableBorders(
new TopBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = },
new BottomBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = },
new LeftBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = },
new RightBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = },
new InsideHorizontalBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = },
new InsideVerticalBorder() { Val = new EnumValue<BorderValues>(BorderValues.Single), Size = }
)
);
Table table = new Table();
table.Append(tblProp);
//添加表头
TableRow headerRow = new TableRow();
foreach (DataColumn column in dataBaseTable.Columns)
{
TableCell cell = new TableCell();
cell.Append(new Paragraph(new Run(new Text(column.ColumnName))));
headerRow.Append(cell);
}
table.Append(headerRow);
//添加数据
foreach (DataRow row in dataBaseTable.Rows)
{
TableRow tableRow = new TableRow();
foreach (object strCell in row.ItemArray)
{
TableCell cell = new TableCell();
cell.Append(new Paragraph(new Run(new Text(strCell.ToString()))));
tableRow.Append(cell);
}
table.Append(tableRow);
}
//添加表格
tmplDoc.MainDocumentPart.Document.Body.Append(new Paragraph(new Run(table)));

七、使用OpenXml将当前文档合并到总文档中

path是总文档的路径

tmplFileName是当前文档的路径

//将当前word和总文档的合并
using (WordprocessingDocument template = WordprocessingDocument.Open(path, true))
{
MainDocumentPart mainPart = template.MainDocumentPart;
string altChunkId = tableName;
AlternativeFormatImportPart chunk =
mainPart.AddAlternativeFormatImportPart(
AlternativeFormatImportPartType.WordprocessingML, altChunkId);
using (FileStream fileStream = File.Open(tmplFileName, FileMode.Open))
chunk.FeedData(fileStream);
AltChunk altChunk = new AltChunk();
altChunk.Id = altChunkId;
mainPart.Document
.Body
.InsertAfter(altChunk, mainPart.Document.Body
.Elements<Paragraph>().Last());
mainPart.Document.Save();
}

截取部分效果:

任务完成,这里是源代码,晚安!

使用OpenXml实现生成数据字典文档(beta)的更多相关文章

  1. 干掉 Postman?测试接口直接生成API文档,这个工具贼好用

    大家好,我是小富~ 前几天粉丝群有小伙伴问,有啥好用的API文档工具推荐,无意间发现了一款工具,这里马不停蹄的来给大家分享一下. ShowDoc一个非常适合团队的在线API文档工具,也支持用docke ...

  2. 黄聪:利用OpenXml生成Word2007文档(转)

    原文:http://blog.csdn.net/francislaw/article/details/7568317 版权声明:本文为博主原创文章,未经博主允许不得转载.   目录(?)[-] 一Op ...

  3. 利用OpenXml生成Word2007文档

    一.OpenXml简介 利用C#生成Word文档并非一定要利用OpenXml技术,至少可以使用微软提供的Office相关组件来编程,不过对于Office2007(确切的说是Word.Excel和Pow ...

  4. postgresql 导出数据字典文档

    项目上需要整理目前数据库的数据字典文档.项目不规范,这种文档只要后期来补.这么多张表,每个字段都写到word文档里真心头大.就算前面写了个查询表结构的sql,但是最后整理到word里还是感觉有点麻烦. ...

  5. php用PHPExcel库生成Excel文档的例子

    <?php require_once '../libs/PHPWord/PHPWord.php'; require_once '../libs/PHPWord/PHPWord/IOFactory ...

  6. C# Swagger 生成接口文档

    一直听说Swagger是做Web API文档的好工具,这次手里暂时没什么事,类体验下它的强大之处.下面是使用Swashbuckle.net 给asp.net web API添加文档的简要步骤. 参考地 ...

  7. java基础---->使用Itext生成数据库文档

    这里简单的介绍一下使用Itext生成数据库表的文档.于是我们领教了世界是何等凶顽,同时又得知世界也可以变得温存和美好. 生成数据库的文档 一.maven项目需要引入的jar依赖 <depende ...

  8. python 3.7 生成数据库文档

    开发阶段数据库总是有变动,开发人员需要维护文档给相关人员使用,故编写一个脚本自动生成数据库文档 生成的excel如下 import cx_Oracle import os from openpyxl ...

  9. PHP生成word文档的三种实现方式

    PHP生成word原理 利用windows下面的 com组件 利用PHP将内容写入doc文件之中 具体实现: 利用windows下面的 com组件 原理:com作为PHP的一个扩展类,安装过offic ...

随机推荐

  1. 高放的c++学习笔记之模板与泛型编程

    函数模板 作用 有很多时候参数的类型以及返回值的类型是可变的,我们通过定义模板来让函数能更灵活的运用. 我们设计一个比较函数,如果能比较的两个参数是int型的,两个参数也可能都是string型的,单独 ...

  2. Javascript 中神奇的 this

    Javascript 当中的 this 与其他语言是完全不同的机制,很有可能会让一些编写其他语言的工程师迷惑. 1. 误以为 this 指向函数自身 根据 this 的英语语法,很容易将函数中出现的  ...

  3. acdream暴力专场中的优美暴力

    F - 小晴天老师系列——苹果大丰收 Time Limit: 2000/1000MS (Java/Others)    Memory Limit: 128000/64000KB (Java/Other ...

  4. Centos7 打开80端口防火墙命令

    iptables -I INPUT -p TCP --dport 80 -j ACCEPT

  5. Altium Designer 里面怎么画等长线

    (1)一般是将走线布完后,新建一个class. Design -> Classes 如上图添加完后可以点击close. (2)快捷键 T + R: 或者 点击Tools 下拉中的Interact ...

  6. Altium Designer 6 快速进行差分对走线

    1: 在原理图中让一对网络前缀相同,后缀分别为_N 和_P,并且加上差分队对指示.在原理图中,让一对网络名称的前缀名相同,后缀分别为_N 和_P,左键点击Place DirectivesDiffere ...

  7. MySQL更新死锁问题

    作为一个社交类的 App ,我们有很多操作都会同时发生,为了确保数据的一致性,会采用数据库的事物. 比如现在我们有一个点赞操作,点赞成功后,需要更改文章的热度.以下是 SQL 语句: INSERT I ...

  8. 黑马程序员_Java集合框架

    集合类 1,为什么出现集合类? 面向对象语言对食物的体现都是以对象的形式,所以为了方便对多个对象的操作,就对对象进行存储,集合就是存储对象最常用的一种方式. 2,数组和集合类同是容器,有何不同? 数组 ...

  9. HDOJ 1420 Prepared for New Acmer(DP)

    Problem Description 集训进行了将近2个礼拜,这段时间以恢复性训练为主,我一直在密切关注大家的训练情况,目前为止,对大家的表现相当满意,首先是绝大部分队员的训练积极性很高,其次,都很 ...

  10. HDU5107---K-short Problem (线段树区间 合并、第k大)

    题意:二维平面上 N 个高度为 Hi 建筑物,M次询问,每次询问输出 位于坐标(x ,y)左下角(也就是xi <= x && yi <= y)的建筑物中的第k高的建筑物的高 ...