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;