找到一个开源免费的UML建模工具,STARUML,试用后发现还不错,但文档生成功能太差了,幸亏支持插件开发,于是写了一个生成类图和序列图的脚本,方便生成设计文档,接下来慢慢写点STARUML的使用心得。
/* Add attribute get and set accessor to selected classes */
//Global varieties
var docFileName = "c://1.doc";
var modelPath = "::Design Model";
var styleCaption1 = "标题 1";
var styleCaption2 = "标题 2";
var styleCaption3 = "标题 3";
var styleCaption4 = "标题 4";
var styleCaption5 = "标题 5";
var styleCaption6 = "标题 6";
var styleTableName = "表名";
var styleChartName = "图名";
var styleText = "正文";
var styleTable = "彩色型 2";
//StarUML objects
var app = new ActiveXObject("StarUML.StarUMLApplication");
var prj = app.GetProject();
var facto = app.UMLFactory;
var selmgr = app.SelectionManager;
//Just select one model
var m = selmgr.GetSelectedModelAt(0);
//Only operate for UMLSequenceDiagram
if( m.GetClassName() == "UMLClassDiagram" )
{
//File system object
var fso = new ActiveXObject("Scripting.FileSystemObject");
//Word objects
var word = new ActiveXObject("Word.Application");
word.Visible = false;
var doc = word.Document;
doc = word.Documents.Open( docFileName );
//Create diagram and view elements, add class to view
var rootElem = app.FindByPathname( modelPath );
var diagram = facto.CreateClassDiagram( rootElem );
var diagramView = diagram.DiagramView;
app.log(m.name);
//Get model's diagram view
var dv = m.DiagramView;
if(dv != null )
{
app.log(dv.GetOwnedViewCount());
CreateDorForClass(m.name, dv);
}
else
app.log("Get model diagram view failed!");
//Delete view and close diagram
app.DeleteModel(diagram);
//Save and close word
doc.save();
word.quit();
}
else
{
app.log("No class diagram found.");
}
app.log("Finished");
/***********/
/*functions*/
/***********/
function blankArray(n)
{
for (var i = 0; i < n; i++)
this[i] = null;
this.length = n;
}
function CheckClassView(m)
{
//var m = view.Model;
if (m.GetClassName() == "UMLClass")
{
app.log("Process class " + m.name);
WriteClassInfoToWord(m,view.Width,view.Height);
}
}
function CheckEnumView(view)
{
var m = view.Model;
if (m.GetClassName() == "UMLEnumeration")
{
app.log("Process enumeration " + m.name);
WriteEnumInfoToWord(m,view.Width,view.Height);
}
}
function CreateDorForClass(nameStr, dv)
{
var view;
SetTextStyle(nameStr, styleCaption3);
SetTextStyle(nameStr, styleTableName);
var table = doc.Tables.Add(doc.Paragraphs(doc.Paragraphs.Count).Range, 3, 1);
SetTableStyle(table, true);
//Export diagram view picture
var jpgName = "c://" + nameStr + ".jpg";
dv.ExportDiagramAsJPEG(jpgName)
//Write sequence chart information
table.Cell(1,1).Range.InsertAfter( nameStr );
table.Cell(2,1).Range.InlineShapes.AddPicture(jpgName);
table.Cell(3,1).Range.InsertAfter( dv.documentation );
//Delete temporary picture file
var picFile = fso.GetFile(jpgName);
picFile.Delete();
for (var i = 0; i < dv.GetOwnedViewCount(); i++)
{
view = dv.GetOwnedViewAt(i);
if(view == null)
app.log("null");
else
{
var m = view.Model;
app.log(m.name);
//Get UMLStimulus only
if (m.IsKindOf("UMLClass"))
{
WriteClassInfo(m, view.Width,view.Height);
}
}
}
for (var i = 0; i < dv.GetOwnedViewCount(); i++)
{
view = dv.GetOwnedViewAt(i);
if(view == null)
app.log("null");
else
{
var m = view.Model;
app.log(m.name);
//Get UMLStimulus only
if (m.IsKindOf("UMLEnumeration"))
{
WriteEnumInfo(m, view.Width,view.Height);
}
}
}
doc.save();
}
function WriteClassInfo(elem, w, h)
{
SetTextStyle(elem.name + "类", styleCaption3);
SetTextStyle(elem.name + "类概述", styleCaption4);
SetTextStyle(elem.name + "类", styleTableName);
var table1 = doc.Tables.Add(doc.Paragraphs(doc.Paragraphs.Count).Range,3, 2);
SetTableStyle(table1, false);
table1.Cell(1,1).Range.InsertAfter("名称");
table1.Cell(2,1).Range.InsertAfter("图片");
table1.Cell(3,1).Range.InsertAfter("描述");
//Add class view to diagram view
var tmpClassView = facto.CreateClassView(diagramView, elem);
//Save diagram view to file
var jpgName = "c://" + elem.name + ".jpg";
tmpClassView.Width = w;
tmpClassView.Height = h;
diagramView.ExportDiagramAsJPEG(jpgName)
//Write class information
table1.Cell(1,2).Range.InsertAfter( elem.name );
table1.Cell(2,2).Range.InlineShapes.AddPicture(jpgName);
table1.Cell(3,2).Range.InsertAfter( elem.documentation );
//Delete temporary picture file
var picFile = fso.GetFile(jpgName);
picFile.Delete();
//Delete view and close diagram
app.DeleteView(tmpClassView);
//Write attribute information
SetTextStyle( elem.name + "类属性", styleCaption4);
var attrCount = elem.MOF_GetCollectionCount("Attributes");
SetTextStyle("属性个数: " + attrCount + "个", styleText);
if( attrCount > 0)
{
SetTextStyle(elem.name + "类属性", styleTableName);
app.log(elem.name + "类属性");
var table2 = doc.Tables.Add(doc.Paragraphs(doc.Paragraphs.Count).Range,attrCount + 1, 4);
SetTableStyle(table2, true);
table2.Cell(1,1).Range.InsertAfter("名称");
table2.Cell(1,2).Range.InsertAfter("可见性");
table2.Cell(1,3).Range.InsertAfter("类型");
table2.Cell(1,4).Range.InsertAfter("描述");
for(var i = 2; i <= attrCount + 1; i++)
{
var attr = elem.MOF_GetCollectionItem("Attributes", i-2);
table2.Cell(i,1).Range.InsertAfter( attr.name );
table2.Cell(i,2).Range.InsertAfter( GetVisibilityExpression(attr.visibility) );
table2.Cell(i,3).Range.InsertAfter( attr.TypeExpression );
table2.Cell(i,4).Range.InsertAfter( attr.Documentation );
}
}
//Write operation information
var opCount = elem.MOF_GetCollectionCount("Operations");
SetTextStyle(elem.name + "类操作", styleCaption4);
SetTextStyle("操作个数: " + opCount + "个", styleText);
app.log(elem.name + "类操作");
if( opCount > 0)
{
for(var i = 0; i < opCount ; i++)
{
var op = elem.MOF_GetCollectionItem("Operations", i);
SetTextStyle(op.name + "操作", styleCaption5);
SetTextStyle(op.name + "操作概述", styleCaption6);
doc.Paragraphs(doc.Paragraphs.Count).Range.InsertAfter("/r/n");
doc.Paragraphs(doc.Paragraphs.Count).Range.InsertAfter("/t操作名称:/t" + op.name + "/r/n");
doc.Paragraphs(doc.Paragraphs.Count).Range.InsertAfter("/t可见性:/t" + GetVisibilityExpression(op.visibility) + "/r/n");
doc.Paragraphs(doc.Paragraphs.Count).Range.InsertAfter("/t描述:/t" + op.Documentation + "/r/n");
//Write operation parameter information
var paraCount = op.MOF_GetCollectionCount("Parameters");
SetTextStyle(op.name + "参数", styleCaption6);
SetTextStyle("参数个数: " + paraCount + "个", styleText);
if(paraCount > 0)
{
SetTextStyle(op.name + "参数", styleTableName);
app.log(op.name + "参数");
//Add parameter table
var table3 = doc.Tables.Add(doc.Paragraphs(doc.Paragraphs.Count).Range,paraCount + 1, 4);
SetTableStyle(table3, true);
table3.Cell(1,1).Range.InsertAfter("名称");
table3.Cell(1,2).Range.InsertAfter("类型");
table3.Cell(1,3).Range.InsertAfter("输入输出类型");
table3.Cell(1,4).Range.InsertAfter("描述");
for (var j = 2; j <= paraCount + 1; j++)
{
var para = op.MOF_GetCollectionItem("Parameters", j-2);
table3.Cell(j,1).Range.InsertAfter( para.name );
table3.Cell(j,2).Range.InsertAfter( para.TypeExpression );
table3.Cell(j,3).Range.InsertAfter( GetParaDirection(para.directionkind) );
table3.Cell(j,4).Range.InsertAfter( para.Documentation );
}
}
}
}
}
function GetVisibilityExpression(type)
{
switch(type)
{
case 0:
return "公有";
case 1:
return "保护";
case 2:
return "私有";
case 3:
return "包";
default:
return "未知"
}
}
function GetParaDirection(type)
{
switch(type)
{
case 0:
return "输入";
case 1:
return "双向";
case 2:
return "输出";
case 3:
return "返回";
default:
return "未知"
}
}
function SetTableStyle(table, flag)
{
table.Style = styleTable;
table.ApplyStyleLastRow = false;
table.ApplyStyleLastColumn = false;
if( flag == true)
{
table.ApplyStyleHeadingRows = true;
table.ApplyStyleFirstColumn = false;
}
else
{
table.ApplyStyleHeadingRows = false;
table.ApplyStyleFirstColumn = true;
}
}
function SetTextStyle(text, style)
{
//Insert text using specific style
doc.Paragraphs(doc.Paragraphs.Count).Range.InsertAfter("/r/n");
doc.Paragraphs(doc.Paragraphs.Count).Range.ParagraphFormat.Style = doc.Styles(style);
doc.Paragraphs(doc.Paragraphs.Count).Range.InsertAfter(text);
doc.Paragraphs(doc.Paragraphs.Count).Range.InsertAfter("/r/n");
//Set back
doc.Paragraphs(doc.Paragraphs.Count).Range.ParagraphFormat.Style = doc.Styles(styleText);
}
function WriteEnumInfo(elem,w,h)
{
SetTextStyle(elem.name + "枚举类", styleCaption3);
SetTextStyle(elem.name + "枚举类概述", styleCaption4);
SetTextStyle(elem.name + "枚举类", styleTableName);
var table1 = doc.Tables.Add(doc.Paragraphs(doc.Paragraphs.Count).Range,3, 2);
SetTableStyle(table1, false);
table1.Cell(1,1).Range.InsertAfter("名称");
table1.Cell(2,1).Range.InsertAfter("图片");
table1.Cell(3,1).Range.InsertAfter("描述");
//Add view to diagram view
var tmpEnumView = facto.CreateEnumerationView(diagramView, elem);
//Save diagram view to file
var jpgName = "c://" + elem.name + ".jpg";
tmpEnumView.Width = w;
tmpEnumView.Height = h;
diagramView.ExportDiagramAsJPEG(jpgName)
//Write class information
table1.Cell(1,2).Range.InsertAfter( elem.name );
table1.Cell(2,2).Range.InlineShapes.AddPicture(jpgName);
table1.Cell(3,2).Range.InsertAfter( elem.documentation );
//Delete temporary picture file
var picFile = fso.GetFile(jpgName);
picFile.Delete();
//Delete view and close diagram
app.DeleteView(tmpEnumView);
//Write attribute information
SetTextStyle(elem.name + "枚举值", styleCaption4);
var literalCount = elem.MOF_GetCollectionCount("Literals");
SetTextStyle("枚举值个数: " + literalCount + "个", styleText);
if( literalCount > 0)
{
SetTextStyle(elem.name + "枚举值", styleTableName);
var table2 = doc.Tables.Add(doc.Paragraphs(doc.Paragraphs.Count).Range,literalCount + 1, 3);
SetTableStyle(table2, true);
table2.Cell(1,1).Range.InsertAfter("名称");
table2.Cell(1,2).Range.InsertAfter("可见性");
table2.Cell(1,3).Range.InsertAfter("描述");
for(var i = 2; i <= literalCount + 1; i++)
{
var literal = elem.MOF_GetCollectionItem("Literals", i-2);
table2.Cell(i,1).Range.InsertAfter( literal.name );
table2.Cell(i,2).Range.InsertAfter( GetVisibilityExpression(literal.visibility) );
table2.Cell(i,3).Range.InsertAfter( literal.Documentation );
}
}
//Write operation information
var opCount = elem.MOF_GetCollectionCount("Operations");
SetTextStyle(elem.name + "枚举类操作", styleCaption4);
SetTextStyle("操作个数: " + opCount + "个", styleText);
if( opCount > 0)
{
for(var i = 0; i < opCount ; i++)
{
var op = elem.MOF_GetCollectionItem("Operations", i);
SetTextStyle("Operation " + op.name + " of class " + elem.name, styleCaption5);
SetTextStyle(op.name + "操作概述", styleCaption6);
doc.Paragraphs(doc.Paragraphs.Count).Range.InsertAfter("/r/n");
doc.Paragraphs(doc.Paragraphs.Count).Range.InsertAfter("/t操作名称:/t" + op.name + "/r/n");
doc.Paragraphs(doc.Paragraphs.Count).Range.InsertAfter("/t可见性:/t" + GetVisibilityExpression(op.visibility) + "/r/n");
doc.Paragraphs(doc.Paragraphs.Count).Range.InsertAfter("/t描述:/t" + op.Documentation + "/r/n");
//Write operation parameter information
var paraCount = op.MOF_GetCollectionCount("Parameters");
SetTextStyle(op.name + "参数", styleCaption6);
SetTextStyle("参数个数: " + paraCount + "个", styleText);
if(paraCount > 0)
{
SetTextStyle(op.name + "参数", styleTableName);
//Add parameter table
var table3 = doc.Tables.Add(doc.Paragraphs(doc.Paragraphs.Count).Range,paraCount + 1, 4);
SetTableStyle(table3, true);
table3.Cell(1,1).Range.InsertAfter("名称");
table3.Cell(1,2).Range.InsertAfter("类型");
table3.Cell(1,3).Range.InsertAfter("输入输出类型");
table3.Cell(1,4).Range.InsertAfter("描述");
for (var j = 2; j <= paraCount + 1; j++)
{
var para = op.MOF_GetCollectionItem("Parameters", j-2);
table3.Cell(j,1).Range.InsertAfter( para.name );
table3.Cell(j,2).Range.InsertAfter( para.TypeExpression );
table3.Cell(j,3).Range.InsertAfter( GetParaDirection(para.directionkind) );
table3.Cell(j,4).Range.InsertAfter( para.Documentation );
}
}
}
}
doc.save();
}
使用时要准备一个空文档1.doc,放在C:/下,然后添加样式
var styleCaption1 = "标题 1";
var styleCaption2 = "标题 2";
var styleCaption3 = "标题 3";
var styleCaption4 = "标题 4";
var styleCaption5 = "标题 5";
var styleCaption6 = "标题 6";
var styleTableName = "表名";
var styleChartName = "图名";
var styleText = "正文";
var styleTable = "彩色型 2";
你也可以改成自己的模板,
具体的菜单如何添加可以参考STARUML开发文档
效果如下:
名称
|
Status
|
图片
| |
描述
|
状态虚基类,提供共用状态属性和虚函数
|
名称
|
可见性
|
类型
|
描述
|
stationId
|
公有
|
|
|
devId
|
公有
|
|
|
updateTime
|
公有
|
|
|
phyicalId
|
公有
|
|
|
statusWarning
|
公有
|
StatusWarningType
|
|
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=981210