基于.NET4平台读写AutoCAD文件
2014-07-18管文蔚
摘要: 鉴于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.