AutoCAD C# 二次开发: 输出CAD文本到Txt和Excel
创建类库应用
添加AutoCAD引用
添加一个WinForm面板
WinForm面板中添加两个Button按钮
并修改它们的【Text】分别为:输出到Txt,输出到Excel
安装NPOI
用于读取Excel,C#读取Excel的方式有多种
直接在Nuget下载NPOI,如下图所示
搜索NPOI,点击下载安装该依赖包即可。
命令行类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Autodesk.AutoCAD.Runtime;
namespace CADDemoIO
public class CADDemoIOMain
[CommandMethod("CADIOMain")] //启动CAD界面命令
public void CADIOMain()
CAEDemoExportForm myfrom = new CAEDemoExportForm();
// Autodesk.AutoCAD.ApplicationServices.Application.ShowModalDialog(myfrom); //在CAD的 模态显示
Autodesk.AutoCAD.ApplicationServices.Application.ShowModelessDialog(myfrom); //在CAD的非模态显示
窗口初始化,设置焦点
/// <summary>
/// 初始化 窗口焦点切换功能
/// </summary>
/// <param name="hWnd"></param>
/// <returns></returns>
[DllImport("user32.dll", EntryPoint = "SetFocus")]
public static extern int SetFocus(IntPtr hWnd);
public CAEDemoExportForm()
InitializeComponent();
}
导出到Txt按钮的事件
/// <summary>
/// 输出到Txt
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button1_Click(object sender, EventArgs e)
List<string> textList = new List<string>(); //读取的结果存在这里
Database database = HostApplicationServices.WorkingDatabase;
Document document = Application.DocumentManager.MdiActiveDocument;
SetFocus(document.Window.Handle); //选择完文件在切换焦点
using (DocumentLock acLckDoc = document.LockDocument()) //锁定文档
//框选获取文字 选择集知识点
//设置选择集过滤器为只选择单行文字
TypedValue[] acTypValAr = new TypedValue[1];
acTypValAr.SetValue(new TypedValue(0, "MTEXT"), 0); // 之选择多行文本
SelectionSet acSSet = GetSelectionSet("GetSelection", null, acTypValAr);
if (acSSet != null)
foreach (SelectedObject selObj in acSSet)
if (selObj != null)
//开始启动事物调整文字位置点和对齐点
using (Transaction trans = database.TransactionManager.StartTransaction())
MText myent = trans.GetObject(selObj.ObjectId, OpenMode.ForWrite) as MText;
textList.Add(myent.Contents); //文字对象复制
SaveFileDialog saveFileDialog = new SaveFileDialog();
saveFileDialog.Title = "输出文本内容";
saveFileDialog.Filter = "文本文件(*.txt)|*.txt";
saveFileDialog.InitialDirectory = Path.GetDirectoryName(database.Filename);
string fileName = Path.GetFileName(database.Filename);
saveFileDialog.FileName = fileName.Substring(0, fileName.IndexOf('.'));
DialogResult saveDlgRes = saveFileDialog.ShowDialog();
if (saveDlgRes == DialogResult.OK)
string[] contents = new string[textList.Count];
for (int i = 0; i < textList.Count; i++)
contents[i] = textList[i].ToString();
File.WriteAllLines(saveFileDialog.FileName, contents);
/// <summary>
/// 获取选择集
/// </summary>
/// <param name="selectStr">选择方式</param>
/// <param name="point3dCollection">选择点集合</param>
/// <param name="typedValue">过滤参数</param>
/// <returns></returns>
public SelectionSet GetSelectionSet(string selectStr, Point3dCollection point3dCollection, TypedValue[] typedValue)
Editor editor = Application.DocumentManager.MdiActiveDocument.Editor;
// 将过滤条件赋值给SelectionFilter对象
SelectionFilter selfilter = null;
if (typedValue != null)
selfilter = new SelectionFilter(typedValue);
// 请求在图形区域选择对象
PromptSelectionResult psr;
if (selectStr == "GetSelection") // 提示用户从图形文件中选取对象
psr = editor.GetSelection(selfilter);
else if (selectStr == "SelectAll") //选择当前空间内所有未锁定及未冻结的对象
psr = editor.SelectAll(selfilter);
else if (selectStr == "SelectCrossingPolygon") //选择由给定点定义的多边形内的所有对象以及与多边形相交的对象。多边形可以是任意形状,但不能与自己交叉或接触。
psr = editor.SelectCrossingPolygon(point3dCollection, selfilter);
// 选择与选择围栏相交的所有对象。围栏选择与多边形选择类似,所不同的是围栏不是封闭的, 围栏同样不能与自己相交
else if (selectStr == "SelectFence")
psr = editor.SelectFence(point3dCollection, selfilter);
// 选择完全框入由点定义的多边形内的对象。多边形可以是任意形状,但不能与自己交叉或接触
else if (selectStr == "SelectWindowPolygon")
psr = editor.SelectWindowPolygon(point3dCollection, selfilter);
else if (selectStr == "SelectCrossingWindow") //选择由两个点定义的窗口内的对象以及与窗口相交的对象
Point3d point1 = point3dCollection[0];
Point3d point2 = point3dCollection[1];
psr = editor.SelectCrossingWindow(point1, point2, selfilter);
else if (selectStr == "SelectWindow") // 选择完全框入由两个点定义的矩形内的所有对象。
Point3d point1 = point3dCollection[0];
Point3d point2 = point3dCollection[1];
psr = editor.SelectCrossingWindow(point1, point2, selfilter);
return null;
// 如果提示状态OK,表示对象已选
if (psr.Status == PromptStatus.OK)
SelectionSet sSet = psr.Value;
editor.WriteMessage("选中的对象数量是: " + sSet.Count.ToString() + "\n");
return sSet;
editor.WriteMessage("没有符合条件的对象 \n");
return null;
测试效果
netload,输入命令行之后可以看到下面的界面
点击【导出到Txt】之后,框选
输出到txt的内容
{\fSimSun|b0|i0|c134|p2;非封闭多段线}
{\fSimSun|b0|i0|c134|p2;我的多行文件,\fNSimSun|b0|i0|c134|p49;\H0.79167x;\C7;需要替换的文本}
导出到Excel按钮的事件
/// <summary>
/// 输出到Excel
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button2_Click(object sender, EventArgs e)
List<string> lstAddStr = new List<string>(); //读取的结果存在这里
Database database = HostApplicationServices.WorkingDatabase;
Document document = Application.DocumentManager.MdiActiveDocument;
SetFocus(document.Window.Handle); //选择完文件在切换焦点
using (DocumentLock acLckDoc = document.LockDocument())
//框选获取文字
//设置选择集过滤器为只选择多行文本
TypedValue[] typeValue = new TypedValue[1];
typeValue.SetValue(new TypedValue(0, "MTEXT"), 0);
SelectionSet selectionSet = GetSelectionSet("GetSelection", null, typeValue);
if (selectionSet == null)
return;
foreach (SelectedObject selObj in selectionSet)
if (selObj != null)
//开始启动事物调整文字位置点和对齐点
using (Transaction trans = database.TransactionManager.StartTransaction())
MText myent = trans.GetObject(selObj.ObjectId, OpenMode.ForWrite) as MText;
lstAddStr.Add(myent.Contents); //文字对象复制
//数据输出到EXCEL表格
IWorkbook workbook = null; //新建IWorkbook对象
string localFilePath = "D:\\TEST.xlsx";
// 调用一个系统自带的保存文件对话框 写一个EXCEL
SaveFileDialog saveFileDialog = new SaveFileDialog(); //新建winform自带保存文件对话框对象
saveFileDialog.Filter = "Excel Office97-2003(*.xls)|*.xls|Excel Office2007及以上(*.xlsx)|*.xlsx"; //过滤只能存储的对象
DialogResult result = saveFileDialog.ShowDialog(); //显示对话框
localFilePath = saveFileDialog.FileName.ToString();
if (localFilePath.IndexOf(".xlsx") > 0) // 2007版
workbook = new XSSFWorkbook(); //创建表格对象07版之后
else if (localFilePath.IndexOf(".xls") > 0) // 创建表格对象 2003版本
workbook = new HSSFWorkbook(); //03版
//创建工作簿
ISheet sheet = workbook.CreateSheet("输出的文本");
for (int i = 0; i < lstAddStr.Count; i++)
ICell cell = sheet.CreateRow(i).CreateCell(0); //单元格对象 第i行第0列 cell 单元格对象
cell.SetCellValue(lstAddStr[i]);//循环往单元格赋值
//创建文件
using (FileStream fs = File.OpenWrite(localFilePath)) //打开一个xls文件,如果没有则自行创建,如果存在myxls.xls文件则在创建是不要打开该文件!
workbook.Write(fs);
MessageBox.Show("提示:创建成功.");
fs.Close();
}
输出到Excel中的内容
完整代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using Autodesk.AutoCAD.DatabaseServices;// (Database, DBPoint, Line, Spline)
using Autodesk.AutoCAD.Geometry;//(Point3d, Line3d, Curve3d)
using Autodesk.AutoCAD.ApplicationServices;// (Application, Document)
using Autodesk.AutoCAD.Runtime;// (CommandMethodAttribute, RXObject, CommandFlag)
using Autodesk.AutoCAD.EditorInput;//(Editor, PromptXOptions, PromptXResult)
using AcadApp = Autodesk.AutoCAD.ApplicationServices.Application;
using Application = Autodesk.AutoCAD.ApplicationServices.Application;
using NPOI.SS.UserModel;
using NPOI.HSSF.UserModel;
using NPOI.XSSF.UserModel;
using System.Runtime.InteropServices; //应用[DllImport("user32.dll")]需要
namespace CADDemoIO
public partial class CAEDemoExportForm : Form
/// <summary>
/// 初始化 窗口焦点切换功能
/// </summary>
/// <param name="hWnd"></param>
/// <returns></returns>
[DllImport("user32.dll", EntryPoint = "SetFocus")]
public static extern int SetFocus(IntPtr hWnd);
public CAEDemoExportForm()
InitializeComponent();
/// <summary>
/// 输出到Txt
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button1_Click(object sender, EventArgs e)
List<string> textList = new List<string>(); //读取的结果存在这里
Database database = HostApplicationServices.WorkingDatabase;
Document document = Application.DocumentManager.MdiActiveDocument;
SetFocus(document.Window.Handle); //选择完文件在切换焦点
using (DocumentLock acLckDoc = document.LockDocument()) //锁定文档
//框选获取文字 选择集知识点
//设置选择集过滤器为只选择单行文字
TypedValue[] acTypValAr = new TypedValue[1];
acTypValAr.SetValue(new TypedValue(0, "MTEXT"), 0); // 之选择多行文本
SelectionSet acSSet = GetSelectionSet("GetSelection", null, acTypValAr);
if (acSSet != null)
foreach (SelectedObject selObj in acSSet)
if (selObj != null)
//开始启动事物调整文字位置点和对齐点
using (Transaction trans = database.TransactionManager.StartTransaction())
MText myent = trans.GetObject(selObj.ObjectId, OpenMode.ForWrite) as MText;
textList.Add(myent.Contents); //文字对象复制
SaveFileDialog saveFileDialog = new SaveFileDialog();
saveFileDialog.Title = "输出文本内容";
saveFileDialog.Filter = "文本文件(*.txt)|*.txt";
saveFileDialog.InitialDirectory = Path.GetDirectoryName(database.Filename);
string fileName = Path.GetFileName(database.Filename);
saveFileDialog.FileName = fileName.Substring(0, fileName.IndexOf('.'));
DialogResult saveDlgRes = saveFileDialog.ShowDialog();
if (saveDlgRes == DialogResult.OK)
string[] contents = new string[textList.Count];
for (int i = 0; i < textList.Count; i++)
contents[i] = textList[i].ToString();
File.WriteAllLines(saveFileDialog.FileName, contents);
/// <summary>
/// 输出到Excel
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button2_Click(object sender, EventArgs e)
List<string> lstAddStr = new List<string>(); //读取的结果存在这里
Database database = HostApplicationServices.WorkingDatabase;
Document document = Application.DocumentManager.MdiActiveDocument;
SetFocus(document.Window.Handle); //选择完文件在切换焦点
using (DocumentLock acLckDoc = document.LockDocument())
//框选获取文字
//设置选择集过滤器为只选择多行文本
TypedValue[] typeValue = new TypedValue[1];
typeValue.SetValue(new TypedValue(0, "MTEXT"), 0);
SelectionSet selectionSet = GetSelectionSet("GetSelection", null, typeValue);
if (selectionSet == null)
return;
foreach (SelectedObject selObj in selectionSet)
if (selObj != null)
//开始启动事物调整文字位置点和对齐点
using (Transaction trans = database.TransactionManager.StartTransaction())
MText myent = trans.GetObject(selObj.ObjectId, OpenMode.ForWrite) as MText;
lstAddStr.Add(myent.Contents); //文字对象复制
//数据输出到EXCEL表格
IWorkbook workbook = null; //新建IWorkbook对象
string localFilePath = "D:\\TEST.xlsx";
// 调用一个系统自带的保存文件对话框 写一个EXCEL
SaveFileDialog saveFileDialog = new SaveFileDialog(); //新建winform自带保存文件对话框对象
saveFileDialog.Filter = "Excel Office97-2003(*.xls)|*.xls|Excel Office2007及以上(*.xlsx)|*.xlsx"; //过滤只能存储的对象
DialogResult result = saveFileDialog.ShowDialog(); //显示对话框
localFilePath = saveFileDialog.FileName.ToString();
if (localFilePath.IndexOf(".xlsx") > 0) // 2007版
workbook = new XSSFWorkbook(); //创建表格对象07版之后
else if (localFilePath.IndexOf(".xls") > 0) // 创建表格对象 2003版本
workbook = new HSSFWorkbook(); //03版
//创建工作簿
ISheet sheet = workbook.CreateSheet("输出的文本");
for (int i = 0; i < lstAddStr.Count; i++)
ICell cell = sheet.CreateRow(i).CreateCell(0); //单元格对象 第i行第0列 cell 单元格对象
cell.SetCellValue(lstAddStr[i]);//循环往单元格赋值
//创建文件
using (FileStream fs = File.OpenWrite(localFilePath)) //打开一个xls文件,如果没有则自行创建,如果存在myxls.xls文件则在创建是不要打开该文件!
workbook.Write(fs);
MessageBox.Show("提示:创建成功.");
fs.Close();
/// <summary>
/// 获取选择集
/// </summary>
/// <param name="selectStr">选择方式</param>
/// <param name="point3dCollection">选择点集合</param>
/// <param name="typedValue">过滤参数</param>
/// <returns></returns>
public SelectionSet GetSelectionSet(string selectStr, Point3dCollection point3dCollection, TypedValue[] typedValue)
Editor editor = Application.DocumentManager.MdiActiveDocument.Editor;
// 将过滤条件赋值给SelectionFilter对象
SelectionFilter selfilter = null;
if (typedValue != null)
selfilter = new SelectionFilter(typedValue);
// 请求在图形区域选择对象
PromptSelectionResult psr;
if (selectStr == "GetSelection") // 提示用户从图形文件中选取对象
psr = editor.GetSelection(selfilter);
else if (selectStr == "SelectAll") //选择当前空间内所有未锁定及未冻结的对象
psr = editor.SelectAll(selfilter);
else if (selectStr == "SelectCrossingPolygon") //选择由给定点定义的多边形内的所有对象以及与多边形相交的对象。多边形可以是任意形状,但不能与自己交叉或接触。
psr = editor.SelectCrossingPolygon(point3dCollection, selfilter);
// 选择与选择围栏相交的所有对象。围栏选择与多边形选择类似,所不同的是围栏不是封闭的, 围栏同样不能与自己相交
else if (selectStr == "SelectFence")
psr = editor.SelectFence(point3dCollection, selfilter);
// 选择完全框入由点定义的多边形内的对象。多边形可以是任意形状,但不能与自己交叉或接触
else if (selectStr == "SelectWindowPolygon")
psr = editor.SelectWindowPolygon(point3dCollection, selfilter);
else if (selectStr == "SelectCrossingWindow") //选择由两个点定义的窗口内的对象以及与窗口相交的对象
Point3d point1 = point3dCollection[0];
Point3d point2 = point3dCollection[1];
psr = editor.SelectCrossingWindow(point1, point2, selfilter);
else if (selectStr == "SelectWindow") // 选择完全框入由两个点定义的矩形内的所有对象。
Point3d point1 = point3dCollection[0];
Point3d point2 = point3dCollection[1];
psr = editor.SelectCrossingWindow(point1, point2, selfilter);
return null;
// 如果提示状态OK,表示对象已选
if (psr.Status == PromptStatus.OK)
SelectionSet sSet = psr.Value;
editor.WriteMessage("选中的对象数量是: " + sSet.Count.ToString() + "\n");
return sSet;
editor.WriteMessage("没有符合条件的对象 \n");
return null;