效果如下:

具体代码如下

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.GraphicsInterface;
using Autodesk.Civil;
using Autodesk.Civil.ApplicationServices;
using Autodesk.Civil.DatabaseServices;
using AcAp = Autodesk.AutoCAD.ApplicationServices.Application;
using Application = Autodesk.AutoCAD.ApplicationServices.Core.Application;
using Entity = Autodesk.AutoCAD.DatabaseServices.Entity;
using Exception = Autodesk.AutoCAD.Runtime.Exception;
using Table = Autodesk.AutoCAD.DatabaseServices.Table;

namespace Civil3DTools
{
    internal class CreateStationTable
    {
        private const string TableStyleName = "逐桩坐标表";
        private const double TextHeight = 2.5;
        private const double MajInterval = 1000;
        private const double MinInterval = 25;
        private const int NumRows = 5;
        private const int NumCols = 11;
        private const double TableBreakHeight = 240;
        private const double TableBreakSpace = 100;
        private const double DataRowHeight = 7.85;
        private const double HeaderRowHeight = 7.20;
        private const double TitleRowHeight = 11.45;
        private readonly Database db;
        private readonly Document doc;
        private readonly Editor ed;
        private readonly Table table;
        private readonly double[] widths = {37.5, 37.5, 37.5, 11.25, 37.5, 37.5, 37.5, 11.25, 37.5, 37.5, 37.5};
        private ObjectId alignmentId;
        private CivilDocument civilDoc;
        private ObjectId tableStyleId;

        /// <summary>
        ///     构造函数
        /// </summary>
        public CreateStationTable()
        {
            doc = Application.DocumentManager.MdiActiveDocument;
            db = doc.Database;
            ed = doc.Editor;
            civilDoc = CivilApplication.ActiveDocument;
            alignmentId = ObjectId.Null;
            tableStyleId = ObjectId.Null;
            table = new Table();
        }

        public void CreateTable()
        {
            try
            {
                SelectEntity();
                if (alignmentId == ObjectId.Null) return;

                GetTableStyleId();
                CreatTableHeader();
                SetTableHeaderStyle();
                SetTableHeaderText();
                PopulateData();
                SetGirdLineVisiablity();
                SetGirdLineWeight();
                InsertTable();
            }
            catch (Exception e)
            {
                ed.WriteMessage(e.Message);
            }
        }

        private void InsertTable()
        {
            table.GenerateLayout();
            var tj = new TableJig(table);
            var pr = ed.Drag(tj);
            if (pr.Status != PromptStatus.OK) return;

            using (var tr = db.TransactionManager.StartTransaction())
            {
                var btr = db.CurrentSpaceId.GetObject(OpenMode.ForWrite) as BlockTableRecord;
                btr.AppendEntity(table);
                tr.AddNewlyCreatedDBObject(table, true);
                tr.Commit();
            }
        }

        private void SetGirdLineWeight()
        {
            var lw = LineWeight.LineWeight060;
            var numRows = table.Rows.Count;
            table.Cells[2, -1].Borders.Top.LineWeight = lw;
            table.Cells[numRows - 1, -1].Borders.Top.LineWeight = lw;
            for (var i = 2; i < numRows; i++)
            {
                table.Cells[i, 0].Borders.Left.LineWeight = lw;
                table.Cells[i, NumCols - 1].Borders.Right.LineWeight = lw;
            }
        }

        private void SetGirdLineVisiablity()
        {
            var numRows = table.Rows.Count;
            table.Cells[0, -1].Borders.Top.IsVisible = false;
            table.Cells[0, -1].Borders.Bottom.IsVisible = false;
            table.Cells[0, -1].Borders.Left.IsVisible = false;
            table.Cells[0, -1].Borders.Right.IsVisible = false;
            table.Cells[1, -1].Borders.Top.IsVisible = false;
            table.Cells[1, -1].Borders.Bottom.IsVisible = false;
            table.Cells[1, -1].Borders.Right.IsVisible = false;
            table.Cells[1, -1].Borders.Vertical.IsVisible = false;
            table.Cells[numRows - 1, -1].Borders.Top.IsVisible = false;
            table.Cells[numRows - 1, -1].Borders.Bottom.IsVisible = false;
            table.Cells[numRows - 1, -1].Borders.Right.IsVisible = false;
            table.Cells[numRows - 1, -1].Borders.Vertical.IsVisible = false;
            for (var i = 3; i < table.Rows.Count; i++)
            {
                table.Cells[i, 3].Borders.Top.IsVisible = false;
                table.Cells[i, 3].Borders.Bottom.IsVisible = false;
                table.Cells[i, 7].Borders.Top.IsVisible = false;
                table.Cells[i, 7].Borders.Bottom.IsVisible = false;
            }
        }

        private void PopulateData()
        {
            using (var tr = db.TransactionManager.StartTransaction())
            {
                var al = alignmentId.GetObject(OpenMode.ForRead) as Alignment;
                var stations = al.GetStationSet(StationTypes.Major | StationTypes.Minor, MajInterval, MinInterval);
                var tableTopHeaderRowsNum = table.Rows.Count - 1;
                var tableDataRowsHeight = TableBreakHeight - table.Height;
                table.InsertRows(tableTopHeaderRowsNum, DataRowHeight, (int) Math.Ceiling(stations.Length / 3.0));
                var tableDataRowHeight = table.Rows[tableTopHeaderRowsNum].Height;
                var rowsNumPerPage = (int) (tableDataRowsHeight / tableDataRowHeight);
                var rowsNumTotal = table.Rows.Count;
                var mod = (rowsNumTotal - tableTopHeaderRowsNum - 1) % rowsNumPerPage;
                if (mod > 0) table.InsertRows(rowsNumTotal - 1, tableDataRowHeight, rowsNumPerPage - mod);

                for (var i = 0; i < stations.Length; i++)
                {
                    var station = stations[i];
                    var rowIndex = i % rowsNumPerPage + rowsNumPerPage * (i / rowsNumPerPage / 3);
                    var columIndex = 0;
                    if (i / rowsNumPerPage % 3 == 1)
                        columIndex = 4;
                    else if (i / rowsNumPerPage % 3 == 2) columIndex = 8;

                    string staWithEqu;
                    try
                    {
                        staWithEqu = al.GetStationStringWithEquations(station.RawStation);
                    }
                    catch (Exception e)
                    {
                        staWithEqu = station.RawStation.ToStationString();
                        ed.WriteMessage(e.Message);
                    }

                    var r = tableTopHeaderRowsNum + rowIndex;
                    table.Cells[r, columIndex].TextString = "K" + staWithEqu;
                    table.Cells[r, columIndex + 1].DataType = new DataTypeParameter(DataType.Double, UnitType.Unitless);
                    table.Cells[r, columIndex + 1].Value = station.Location.X;
                    table.Cells[r, columIndex + 1].DataFormat = "%lu2%pr3";
                    table.Cells[r, columIndex + 2].DataType = new DataTypeParameter(DataType.Double, UnitType.Unitless);
                    table.Cells[r, columIndex + 2].Value = station.Location.Y;
                    table.Cells[r, columIndex + 2].DataFormat = "%lu2%pr3";
                }

                tr.Commit();
            }
        }

        private void SetTableHeaderText()
        {
            table.Cells[0, 0].TextString = "路线逐桩坐标表";
            CellRange range;
            range = CellRange.Create(table, 1, 0, 1, NumCols - 5);
            table.MergeCells(range);
            table.Cells[0, 0].Alignment = CellAlignment.MiddleLeft;
            table.Cells[1, 0].TextString = "%<\\AcVar CustomDP.项目名称>%";
            range = CellRange.Create(table, 1, NumCols - 4, 1, NumCols - 1);
            table.MergeCells(range);
            table.Cells[1, NumCols - 4].Alignment = CellAlignment.MiddleRight;
            table.Cells[1, NumCols - 4].Borders.Horizontal.Margin = 10;
            table.Cells[1, NumCols - 4].TextString = "第  页  共  页";
            for (var i = 0; i < 3; i++)
            {
                range = CellRange.Create(table, 2, i * 4 + 0, 3, i * 4 + 0);
                table.MergeCells(range);
                table.Cells[2, i * 4 + 0].TextString = "桩号";
                range = CellRange.Create(table, 2, i * 4 + 0, 3, i * 4 + 2);
                table.MergeCells(range);
                table.Cells[2, i * 4 + 1].TextString = "坐标";
                table.Cells[3, i * 4 + 1].TextString = "N";
                table.Cells[3, i * 4 + 2].TextString = "E";
            }

            var num2 = NumCols / 2;
            range = CellRange.Create(table, NumCols - 1, 0, NumRows - 1, num2 - 1);
            table.MergeCells(range);
            table.Cells[NumRows - 1, 0].Alignment = CellAlignment.MiddleLeft;
            table.Cells[NumRows - 1, 0].Borders.Horizontal.Margin = 60;
            table.Cells[NumRows - 1, 0].TextString = "编制:%<\\AcVar CustomDP.编制>%";
            range = CellRange.Create(table, NumCols - 1, num2, NumRows - 1, NumCols - 1);
            table.MergeCells(range);
            table.Cells[NumRows - 1, num2].Alignment = CellAlignment.MiddleLeft;
            table.Cells[NumRows - 1, num2].Borders.Horizontal.Margin = 60;
            table.Cells[NumRows - 1, num2].TextString = "复核:%<\\AcVar CustomDP.复核>%";
        }

        private void SetTableHeaderStyle()
        {
            table.Cells[0, -1].Style = "_TITLE";
            for (var i = 0; i < NumRows; i++) table.Cells[i, -1].Style = "_HEADER";

            table.Rows[0].Height = TitleRowHeight;
            table.Rows[1].Height = HeaderRowHeight;
            for (var i = 2; i < NumRows; i++) table.Rows[i].Height = DataRowHeight;

            table.BreakFlowDirection = TableBreakFlowDirection.Right;
            table.BreakOptions = TableBreakOptions.EnableBreaking | TableBreakOptions.RepeatTopLabels |
                                 TableBreakOptions.RepeatBottomLabels;
            table.SetBreakHeight(0, TableBreakHeight);
            table.SetBreakSpacing(TableBreakSpace);
        }

        private void CreatTableHeader()
        {
            if (table == null) return;
            table.SetSize(NumRows, NumCols);
            if (tableStyleId == ObjectId.Null) return;

            table.TableStyle = tableStyleId;
            for (var i = 0; i < NumCols; i++) table.Columns[i].Width = widths[i];
        }

        /// <summary>
        ///     获取表格样式
        /// </summary>
        private void GetTableStyleId()
        {
            var tsdId = db.TableStyleDictionaryId;
            using (var tr = db.TransactionManager.StartTransaction())
            {
                var tsd = tsdId.GetObject(OpenMode.ForRead) as DBDictionary;
                if (tsd.Contains(TableStyleName))
                {
                    tableStyleId = tsd.GetAt(TableStyleName);
                }
                else
                {
                    var ts = new TableStyle();
                    var txtStyleId = ObjectId.Null;
                    GetTxtStyleId("表格标题", "黑体", true, ref txtStyleId);
                    ts.SetTextStyle(txtStyleId, (int) RowType.TitleRow);
                    GetTxtStyleId("表格表头", "宋体", true, ref txtStyleId);
                    ts.SetTextStyle(txtStyleId, (int) RowType.HeaderRow);
                    GetTxtStyleId("表格数据", "宋体", true, ref txtStyleId);
                    ts.SetTextStyle(txtStyleId, (int) RowType.DataRow);
                    ts.SetTextHeight(TextHeight * 2, (int) RowType.TitleRow);
                    ts.SetTextHeight(TextHeight * 1.2, (int) RowType.HeaderRow);
                    ts.SetTextHeight(TextHeight, (int) RowType.DataRow);
                    ts.HorizontalCellMargin = TextHeight * 0.2;
                    ts.VerticalCellMargin = TextHeight * 0.5;
                    ts.SetAlignment(CellAlignment.MiddleCenter, (int) RowType.DataRow);
                    tsd.UpgradeOpen();
                    tableStyleId = tsd.SetAt(TableStyleName, ts);
                    tr.AddNewlyCreatedDBObject(ts, true);
                    tsd.DowngradeOpen();
                }

                tr.Commit();
            }
        }

        private void GetTxtStyleId(string txtStyleName, string fontName, bool bold, ref ObjectId txtStyleId)
        {
            var tstId = db.TextStyleTableId;
            using (var tr = db.TransactionManager.StartTransaction())
            {
                var tst = tstId.GetObject(OpenMode.ForRead) as TextStyleTable;
                if (tst.Has(txtStyleName))
                {
                    txtStyleId = tst[txtStyleName];
                }
                else
                {
                    var tstr = new TextStyleTableRecord();
                    tstr.Name = txtStyleName;
                    var fd = new FontDescriptor(fontName, bold, false, 1, 1);
                    tstr.Font = fd;
                    tst.UpgradeOpen();
                    txtStyleId = tst.Add(tstr);
                    tr.AddNewlyCreatedDBObject(tstr, true);
                    tst.DowngradeOpen();
                }

                tr.Commit();
            }
        }

        /// <summary>
        ///     选择路线
        /// </summary>
        private void SelectEntity()
        {
            var peo = new PromptEntityOptions("");
            peo.Message = "\n拾取路线";
            peo.SetRejectMessage("\n选择的不是路线,请重新选择");
            peo.AddAllowedClass(typeof(Alignment), true);
            peo.AllowObjectOnLockedLayer = false;
            var per = ed.GetEntity(peo);
            if (per.Status != PromptStatus.OK) return;

            alignmentId = per.ObjectId;
        }
    }

    internal class TableJig : EntityJig
    {
        private readonly Table m_table;
        private Point3d m_insertPt;

        public TableJig(Entity entity) : base(entity)
        {
            m_table = entity as Table;
            m_insertPt = Point3d.Origin;
        }

        protected override SamplerStatus Sampler(JigPrompts jp)
        {
            var jo = new JigPromptPointOptions("");
            jo.Message = "\n拾取表格插入点";
            var pr = jp.AcquirePoint(jo);
            if (pr.Status == PromptStatus.OK)
            {
                if (m_insertPt == pr.Value) return SamplerStatus.NoChange;

                m_insertPt = pr.Value;
                return SamplerStatus.OK;

            }
            return SamplerStatus.Cancel;
        }

        protected override bool Update()
        {
            m_table.Position = m_insertPt;
            return true;
        }
    }

    public static class MyExtensionMethods
    {
        public static string ToStationString(this double Value)
        {
            var civilDoc = CivilApplication.ActiveDocument;
            var staSetting = civilDoc.Settings.DrawingSettings.AmbientSettings.Station;
            var stationString = Value.ToString("F" + staSetting.Precision.Value);
            var symbolPosition = staSetting.StationDelimiterPosition.Value;
            switch (symbolPosition)
            {
                case StationDelimiterPositionType.Delimiter10:
                    stationString = stationString.Insert(stationString.IndexOf('.') - 1, "+");
                    break;
                case StationDelimiterPositionType.Delimiter100:
                    stationString = stationString.Insert(stationString.IndexOf('.') - 2, "+");
                    break;
                case StationDelimiterPositionType.Delimiter1000:
                    stationString = stationString.Insert(stationString.IndexOf('.') - 3, "+");
                    break;
                case StationDelimiterPositionType.Delimiter10000:
                    stationString = stationString.Insert(stationString.IndexOf('.') - 4, "+");
                    break;
                case StationDelimiterPositionType.Delimiter100000:
                    stationString = stationString.Insert(stationString.IndexOf('.') - 5, "+");
                    break;
            }

            return stationString;
        }
    }

    public class CivilTableToCsv
    {
        private readonly Document doc;
        private string fileName;
        private readonly Database db;
        private readonly Editor ed;
        private readonly List<MText> mts;
        private ObjectId tableId;

        public CivilTableToCsv()
        {
            doc = Application.DocumentManager.MdiActiveDocument;
            ed = doc.Editor;
            db = doc.Database;
            mts = new List<MText>();
            fileName = null;
        }

        public void Export()
        {
            SelectTable();
            if (tableId == ObjectId.Null) return;
            GetFileName();
            if (fileName == null) return;
            GetMtext();
            if (mts.Count < 1) return;
            var fs = new FileStream(fileName, FileMode.Create, FileAccess.ReadWrite);
            var sw = new StreamWriter(fs, Encoding.UTF8);
            var sortedMts = from mt in mts
                orderby mt.Location.Y descending, mt.Location.X
                group mt by mt.Location.Y;
            Array.ForEach(sortedMts.ToArray(), a =>
            {
                Array.ForEach(a.ToArray(), b => { sw.Write("{0},", b.Text); });
                sw.Write(Environment.NewLine);
            });
            sw.Flush();
            sw.Close();
            fs.Close();
        }

        /// <summary>
        ///     提取要输出的文本
        /// </summary>
        private void GetMtext()
        {
            var Objs = new DBObjectCollection();
            using (var tr = db.TransactionManager.StartTransaction())
            {
                var ent = tableId.GetObject(OpenMode.ForRead) as Entity;
                var tmpObjs = new DBObjectCollection();
                ent.Explode(tmpObjs);
                if (tmpObjs.Count == 1)
                {
                    ent = tmpObjs[0] as Entity;
                    ent.Explode(Objs);
                }

                tr.Commit();
            }

            if (Objs.Count > 0)
                using (var tr = db.TransactionManager.StartTransaction())
                {
                    foreach (var obj in Objs)
                    {
                        var mt = obj as MText;
                        if (mt != null) mts.Add(mt);
                    }

                    tr.Commit();
                }
        }

        private void GetFileName()
        {
            var sf = new SaveFileDialog
            {
                Filter = "scv文件|*.csv|所有文件|*.*",
                AddExtension = true,
                Title = "保存文件"
            };
            if (sf.ShowDialog() == DialogResult.OK) fileName = sf.FileName;
        }

        private void SelectTable()
        {
            var peo = new PromptEntityOptions("");
            peo.Message = "\n选择需要输出的表格";
            peo.SetRejectMessage("\n选择的不是Civil3D表格,请重新选择");
            peo.AddAllowedClass(typeof(Autodesk.Civil.DatabaseServices.Table), false);
            var per = ed.GetEntity(peo);
            if (per.Status != PromptStatus.OK) return;
            tableId = per.ObjectId;
        }
    }
}