基于.NET4平台读写AutoCAD文件

2014-07-18 02:39管文蔚
电脑知识与技术 2014年13期

摘要: 鉴于AutoCAD在各个行业中的广泛应用,目前的技术只是停留在把AutoCAD图档元素信息以文件的形式保存起来,然而随着项目团队对AutoCAD文档的交叉设计,实现如何让不同的设计数据共享起来,是个非常重要的问题。本文针对AutoCAD图档中的各种元素(如文本框、矩形框等)信息进行读取,并将其保存到其它形式的数据存储介质 (如XML或MS SQL Server、Oracle等关系型数据库) 中,方便对AutoCAD图档文件进行更智能化的信息化管理。AutoCAD文件本身也是一种数据库,文件扩展名为DWG,只是该数据生态链没有和日常中经常使用的XML或MS SQL Server、Oracle等关系型数据库存储介质进行交互传递。其实根据XML或MS SQL Server、Oracle保存的数据,我们反过来可以修改AutoCAD文件中文本框、矩形框的相关信息参数,这样我们就可以和AutoCAD文件进行数据交互了,读和写DWG文件中的元素信息。

关键词: .NET;AutoCAD ;XML; 数据存储

中图分类号:TP311 文献标识码:A 文章编号:1009-3044(2014)13-2911-03

1 概述

AutoCAD数据库是按一定组织结构的各相关数据的集合。它可以用来存储组成AutoCAD图的对象和实体。DWG图是一个储存在数据库中的对象集合。基本的数据库对象是实体,符号表和词典。图1列出了组成AutoCAD数据库的主要部件。

图1

在AutoCAD中创建的对象被添加到数据库对应的容器对象中,实体被添加到块表的记录中,符号表记录被添加到相应的符号表中,所有其他的对象被添加到命名对象词典中,或添加到其他对象拥有的对象(拥有其他对象的对象最终属于命名对象词典)中,或添加到扩充词典中。

本文开发使用ObjectARX技术,ObjectARX是针对AutoCAD平台上的二次开发而推出的一个开发软件包,它提供了以C++为基础的面向对象的开发环境及应用程序接口,能真正快速的访问AutoCAD图形数据库。ObjectARX应用程序是一个DLL(动态链接库),共享AutoCAD的地址空间,对AutoCAD进行直接函数调用。

2 功能实现

具体功能可以通过以下两个步骤加以实现,具体步骤及代码附加如下:

2.1加载DWG文件

使用Autodesk.AutoCAD.Windows.OpenFileDialog打开DWG文件,使用acadApp.DocumentManager.Open打开DWG文档,这样我们就可以把文件中的相关元素信息读取并保存到XML文件中了,具体实现代码如下:

private void btnUpload_Click(object sender, EventArgs e)

{ Autodesk.AutoCAD.Windows.OpenFileDialog dialog =

new Autodesk.AutoCAD.Windows.OpenFileDialog(

"选择DWG文件" , null , "dwg;" , "DwgFile" , Autodesk.AutoCAD.Windows.OpenFileDialog.OpenFileDialogFlags.DoNotTransferRemoteFiles );

if (dialog.ShowDialog() == DialogResult.OK)

{acadApp.DocumentManager.Open(dialog.Filename, false);

//加载XML

XmlDocument DocXml = new XmlDocument();

//文件全路径名

string spath = System.IO.Path.GetDirectoryName(dialog.Filename);

//去掉扩展名的文件名,和DWG同名的XML文件

string sGetFileName = System.IO.Path.GetFileNameWithoutExtension(dialog.Filename);

string sPathFileName = spath + "\\" + sGetFileName + ".xml";

if (File.Exists(sPathFileName))

{ XmlDocument document = new XmlDocument();

document.Load(sPathFileName);

XmlElement element = document["CADDoc"];

if (element != null)

{ Document doc = acadApp.DocumentManager.MdiActiveDocument;

Database db = doc.Database;

using (DocumentLock docLock = doc.LockDocument())

{for (int i = 0; i < element.ChildNodes.Count; i++)

{if (element.ChildNodes[i].Name == "Rectangle")

{ string sStatus =element.ChildNodes[i].ChildNodes[11].FirstChild.Value.ToString().Trim(); }}}

doc.SendStringToExecute("_qsave", true, false, false); }}}}}

2.2把DWG中各元素信息写入XML文件中

首先把打开的DWG文件用DocumentLock docLock = doc.LockDocument()进行锁定,使用XmlTextWriter xtw = new XmlTextWriter(sPathFileName, Encoding.UTF8)创建实例,然后从DWG文档中读取出来的信息写入XML文件中。记录图纸的句柄、所属图层、所属空间、对象类型、对象类别(关联字段)、坐标信息(x1y1z1,x2y2z2、长度或周长、方位角、面积等)、颜色、线型、线宽、线型比例、样式、字体、文字、比例、宽度比例因子、倾斜角度、旋转角度等信息。

Document doc = acadApp.DocumentManager.MdiActiveDocument;

//保存

using (DocumentLock docLock = doc.LockDocument())

{doc.SendStringToExecute("_qsave", true, false, false);}

string fileName = doc.Name.ToString().Trim();

// 取文档信息

if (!File.Exists(fileName))

{throw new FileNotFoundException();}

else

{ //文件全路径名

string spath = System.IO.Path.GetDirectoryName(fileName);

string sGetFileName = System.IO.Path.GetFileNameWithoutExtension(fileName);

string sDWFFileName = spath + sGetFileName + ".dwf";

if (IFCreateSWF.Checked == true)

{SimplePlot(sDWFFileName);}

docInfo = new DocumentInfo(fileName);

rectInfoList.Clear();

textInfoList.Clear();

GetAllEntityInfo(docInfo.Database);

XmlDocument DocXml = new XmlDocument();

string sPathFileName = spath + "\\" + sGetFileName + ".xml";

if (File.Exists(sPathFileName))

{File.Delete(sPathFileName);}

XmlTextWriter xtw = new XmlTextWriter(sPathFileName, Encoding.UTF8);

xtw.WriteStartDocument();

xtw.WriteStartElement("CADDoc");

xtw.WriteEndElement();

xtw.WriteEndDocument();

xtw.Close();

DocXml.Load(sPathFileName);

int icount = 0;

foreach (RectangleInfo item in rectInfoList)

{ icount++;

RectangleGroup group = new RectangleGroup(item);

XmlElement newRectangleInfo = DocXml.CreateElement("Rectangle");

XmlAttribute newID = DocXml.CreateAttribute("id");

newID.InnerText = icount.ToString();

newRectangleInfo.SetAttributeNode(newID);

//句柄

XmlElement newHandle = DocXml.CreateElement("Handle");

newHandle.InnerText = group.Handle.ToString().Trim();

newRectangleInfo.AppendChild(newHandle);

//图层

XmlElement newLayer = DocXml.CreateElement("Layer");

newLayer.InnerText = group.Layer.ToString().Trim();

newRectangleInfo.AppendChild(newLayer);

DocXml.DocumentElement.AppendChild(newRectangleInfo); }

DocXml.Save(sPathFileName);

MessageBox.Show("成功生成图档信息!");}

3 结束语

通过上面的代码可以实现从AutoCAD文件中读取各元素相关信息,并保存到XML文件中,其实也可以把这些信息保存到关系型数据库中,只需要把保存到XML文件的代码修改成保存到数据库中的代码就行了,该文不在赘述。

其实反过来,从XML中读取相关数据,也是可以加载到AutoCAD文件中,使AutoCAD文件中的元素信息依据XML中的数据进行更新。因此只要我们通过信息管理软件对XML或数据库中的相关数据进行更新,我们在加载XML文件时,同样也可以把AutoCAD文件对应的相关元素信息进行更新,从而可以保持AutoCAD文件里的数据共享,方便不同部门或不同区域的人员使用。

参考文献:

[1] Christian Nagel. C#高级编程[M].7版.清华大学出版社,2010.

[2] Andrew Troelsen. C#与.NET 4高级程序设计[M].5版.人民邮电出版社,2011.

[3] 周卫.AUTO CAD地图制图与系统开发[M].科学出版社,2010.

[4] 林昌华,黄霞,杨岩.机械CAD开发技术[M].国防工业出版社,2013.

{ string sStatus =element.ChildNodes[i].ChildNodes[11].FirstChild.Value.ToString().Trim(); }}}

doc.SendStringToExecute("_qsave", true, false, false); }}}}}

2.2把DWG中各元素信息写入XML文件中

首先把打开的DWG文件用DocumentLock docLock = doc.LockDocument()进行锁定,使用XmlTextWriter xtw = new XmlTextWriter(sPathFileName, Encoding.UTF8)创建实例,然后从DWG文档中读取出来的信息写入XML文件中。记录图纸的句柄、所属图层、所属空间、对象类型、对象类别(关联字段)、坐标信息(x1y1z1,x2y2z2、长度或周长、方位角、面积等)、颜色、线型、线宽、线型比例、样式、字体、文字、比例、宽度比例因子、倾斜角度、旋转角度等信息。

Document doc = acadApp.DocumentManager.MdiActiveDocument;

//保存

using (DocumentLock docLock = doc.LockDocument())

{doc.SendStringToExecute("_qsave", true, false, false);}

string fileName = doc.Name.ToString().Trim();

// 取文档信息

if (!File.Exists(fileName))

{throw new FileNotFoundException();}

else

{ //文件全路径名

string spath = System.IO.Path.GetDirectoryName(fileName);

string sGetFileName = System.IO.Path.GetFileNameWithoutExtension(fileName);

string sDWFFileName = spath + sGetFileName + ".dwf";

if (IFCreateSWF.Checked == true)

{SimplePlot(sDWFFileName);}

docInfo = new DocumentInfo(fileName);

rectInfoList.Clear();

textInfoList.Clear();

GetAllEntityInfo(docInfo.Database);

XmlDocument DocXml = new XmlDocument();

string sPathFileName = spath + "\\" + sGetFileName + ".xml";

if (File.Exists(sPathFileName))

{File.Delete(sPathFileName);}

XmlTextWriter xtw = new XmlTextWriter(sPathFileName, Encoding.UTF8);

xtw.WriteStartDocument();

xtw.WriteStartElement("CADDoc");

xtw.WriteEndElement();

xtw.WriteEndDocument();

xtw.Close();

DocXml.Load(sPathFileName);

int icount = 0;

foreach (RectangleInfo item in rectInfoList)

{ icount++;

RectangleGroup group = new RectangleGroup(item);

XmlElement newRectangleInfo = DocXml.CreateElement("Rectangle");

XmlAttribute newID = DocXml.CreateAttribute("id");

newID.InnerText = icount.ToString();

newRectangleInfo.SetAttributeNode(newID);

//句柄

XmlElement newHandle = DocXml.CreateElement("Handle");

newHandle.InnerText = group.Handle.ToString().Trim();

newRectangleInfo.AppendChild(newHandle);

//图层

XmlElement newLayer = DocXml.CreateElement("Layer");

newLayer.InnerText = group.Layer.ToString().Trim();

newRectangleInfo.AppendChild(newLayer);

DocXml.DocumentElement.AppendChild(newRectangleInfo); }

DocXml.Save(sPathFileName);

MessageBox.Show("成功生成图档信息!");}

3 结束语

通过上面的代码可以实现从AutoCAD文件中读取各元素相关信息,并保存到XML文件中,其实也可以把这些信息保存到关系型数据库中,只需要把保存到XML文件的代码修改成保存到数据库中的代码就行了,该文不在赘述。

其实反过来,从XML中读取相关数据,也是可以加载到AutoCAD文件中,使AutoCAD文件中的元素信息依据XML中的数据进行更新。因此只要我们通过信息管理软件对XML或数据库中的相关数据进行更新,我们在加载XML文件时,同样也可以把AutoCAD文件对应的相关元素信息进行更新,从而可以保持AutoCAD文件里的数据共享,方便不同部门或不同区域的人员使用。

参考文献:

[1] Christian Nagel. C#高级编程[M].7版.清华大学出版社,2010.

[2] Andrew Troelsen. C#与.NET 4高级程序设计[M].5版.人民邮电出版社,2011.

[3] 周卫.AUTO CAD地图制图与系统开发[M].科学出版社,2010.

[4] 林昌华,黄霞,杨岩.机械CAD开发技术[M].国防工业出版社,2013.

{ string sStatus =element.ChildNodes[i].ChildNodes[11].FirstChild.Value.ToString().Trim(); }}}

doc.SendStringToExecute("_qsave", true, false, false); }}}}}

2.2把DWG中各元素信息写入XML文件中

首先把打开的DWG文件用DocumentLock docLock = doc.LockDocument()进行锁定,使用XmlTextWriter xtw = new XmlTextWriter(sPathFileName, Encoding.UTF8)创建实例,然后从DWG文档中读取出来的信息写入XML文件中。记录图纸的句柄、所属图层、所属空间、对象类型、对象类别(关联字段)、坐标信息(x1y1z1,x2y2z2、长度或周长、方位角、面积等)、颜色、线型、线宽、线型比例、样式、字体、文字、比例、宽度比例因子、倾斜角度、旋转角度等信息。

Document doc = acadApp.DocumentManager.MdiActiveDocument;

//保存

using (DocumentLock docLock = doc.LockDocument())

{doc.SendStringToExecute("_qsave", true, false, false);}

string fileName = doc.Name.ToString().Trim();

// 取文档信息

if (!File.Exists(fileName))

{throw new FileNotFoundException();}

else

{ //文件全路径名

string spath = System.IO.Path.GetDirectoryName(fileName);

string sGetFileName = System.IO.Path.GetFileNameWithoutExtension(fileName);

string sDWFFileName = spath + sGetFileName + ".dwf";

if (IFCreateSWF.Checked == true)

{SimplePlot(sDWFFileName);}

docInfo = new DocumentInfo(fileName);

rectInfoList.Clear();

textInfoList.Clear();

GetAllEntityInfo(docInfo.Database);

XmlDocument DocXml = new XmlDocument();

string sPathFileName = spath + "\\" + sGetFileName + ".xml";

if (File.Exists(sPathFileName))

{File.Delete(sPathFileName);}

XmlTextWriter xtw = new XmlTextWriter(sPathFileName, Encoding.UTF8);

xtw.WriteStartDocument();

xtw.WriteStartElement("CADDoc");

xtw.WriteEndElement();

xtw.WriteEndDocument();

xtw.Close();

DocXml.Load(sPathFileName);

int icount = 0;

foreach (RectangleInfo item in rectInfoList)

{ icount++;

RectangleGroup group = new RectangleGroup(item);

XmlElement newRectangleInfo = DocXml.CreateElement("Rectangle");

XmlAttribute newID = DocXml.CreateAttribute("id");

newID.InnerText = icount.ToString();

newRectangleInfo.SetAttributeNode(newID);

//句柄

XmlElement newHandle = DocXml.CreateElement("Handle");

newHandle.InnerText = group.Handle.ToString().Trim();

newRectangleInfo.AppendChild(newHandle);

//图层

XmlElement newLayer = DocXml.CreateElement("Layer");

newLayer.InnerText = group.Layer.ToString().Trim();

newRectangleInfo.AppendChild(newLayer);

DocXml.DocumentElement.AppendChild(newRectangleInfo); }

DocXml.Save(sPathFileName);

MessageBox.Show("成功生成图档信息!");}

3 结束语

通过上面的代码可以实现从AutoCAD文件中读取各元素相关信息,并保存到XML文件中,其实也可以把这些信息保存到关系型数据库中,只需要把保存到XML文件的代码修改成保存到数据库中的代码就行了,该文不在赘述。

其实反过来,从XML中读取相关数据,也是可以加载到AutoCAD文件中,使AutoCAD文件中的元素信息依据XML中的数据进行更新。因此只要我们通过信息管理软件对XML或数据库中的相关数据进行更新,我们在加载XML文件时,同样也可以把AutoCAD文件对应的相关元素信息进行更新,从而可以保持AutoCAD文件里的数据共享,方便不同部门或不同区域的人员使用。

参考文献:

[1] Christian Nagel. C#高级编程[M].7版.清华大学出版社,2010.

[2] Andrew Troelsen. C#与.NET 4高级程序设计[M].5版.人民邮电出版社,2011.

[3] 周卫.AUTO CAD地图制图与系统开发[M].科学出版社,2010.

[4] 林昌华,黄霞,杨岩.机械CAD开发技术[M].国防工业出版社,2013.