经常有搞制图的朋友问我ArcMap里怎么把图幅的四至经纬度标到图上说起来这个需求在测绘、规划、国土出图里非常常见但大部分人的做法还停在“手动打开数据框属性把坐标抄下来再敲进文本框”的阶段。比例尺一调、图幅一换所有坐标全部作废重新抄一遍效率低还容易抄错。我最早被这个需求折磨是给一份乡镇空间规划出图的时候项目负责人把图纸打回来要求图廓外标注东至、南至、西至、北四个方向的经纬度范围。我当时想当然地插了四个文本框把肉眼看到的坐标填进去交上去被打回理由是“经纬度精度不够度分秒格式也不对”。后来我老老实实把ArcMap数据框、坐标系、页面布局的关系理了一遍又用arcpy做了批量出图的自动化方案才算真正把这个需求吃透。今天这篇就把完整做法写出来覆盖ArcMap 10.x环境下的静态单图幅出图和批量地图册两种场景适合制图员、GIS数据处理工程师、测绘规划相关从业者参考。1. 四至经纬度到底是什么为什么地图规范里绕不开它1.1 一句话把“四至”讲明白四至简单说就是某一幅图或某一个地块最东、最南、最西、最北四个方向到达哪里。落到数值上一个矩形数据框的四至就是东至数据框范围内经度的最大值XMax南至数据框范围内纬度的最小值YMin西至数据框范围内经度的最小值XMin北至数据框范围内纬度的最大值YMax这里的关键是“经纬度”。很多人会下意识认为数据框显示什么数字四至就是什么数字。实际上ArcMap数据框里默认显示的是当前数据框坐标系的坐标可能是投影坐标系下的“大数”比如X坐标是500000这样的米制数值根本不是经纬度。标注四至之前必须先把数据框范围换算到地理坐标系下。1.2 规范里为什么强制要求这些坐标很多刚开始接触制图规范的人不理解为什么非要在图廓外面标四个方向的经纬度。从实际使用场景来说四至经纬度承担的作用是“图幅定位和接边检索”。比如纸质图或PDF图被归档后别人拿到图不用打开GIS软件只要看四至坐标就能判断这张图覆盖了哪个区域能不能和相邻图幅无缝拼接。国土、林业、水利系统的图件往往会要求四至坐标出现在图廓左下角或右下角有的甚至连地图册每一页都必须动态更新对应的坐标范围否则图幅编号和坐标对不上归档时会很麻烦。可以这样理解四至经纬度是这张图在真实世界里的“身份证”。地图上的图形可以被平移、缩放、旋转但真实世界的经纬度范围是固定不变的。所以规范里特别看重这个信息出图时如果漏标或标错轻则返工重则导致接边错误。1.3 先想清楚你是静态出图还是批量出图在做四至标注之前先判断应用场景因为方案完全不同静态单图幅图幅数量少只出几张图可以直接用数据框属性读取坐标手工放置文本框或者用经纬网自动带出坐标线。批量地图册可能有几十页甚至上百页每页范围不同四至标注必须跟随当前页面自动更新这就必须依赖数据驱动页面Data Driven Pages和arcpy脚本不能手工一个个抄。我的建议是即使只做一两张图也用脚本方式生成坐标文本而不是手动敲。原因很简单手动抄坐标的出错概率很高尤其是度分秒换算时60进制很容易换算错一旦图面比例尺或范围微调又要重新抄一遍。脚本只需要运行一次后面重复利用。2. 取四至之前先把数据框范围、坐标系和页面坐标这三者关系理清2.1 数据框范围由图层决定不随页面大小改变不少新手会把“数据框范围”和“页面范围”搞混。简单说ArcMap的布局视图里有纸张页面页面内嵌着一个数据框数据框框住了地图内容。四至经纬度指的是数据框所框住的地理范围而不是整张A4纸的物理范围。数据框的范围由以下两个因素决定数据框里加载的图层范围你在“数据框属性”里手动设置的比例尺或固定范围如果调整布局视图里数据框的宽高而数据框属性设置为“自动”范围会跟着变如果设置了固定比例尺改变数据框大小时可见地理范围也会变化。四至坐标必须和数据框当前的实际显示范围一致否则标注就是错的。为了防止后续误操作建议先把数据框范围锁定。操作方法右键数据框打开“数据框属性”切到“数据框”标签页在“范围”区域选择“固定范围”或“固定比例尺”这样后续拖拽布局时数据框的地理范围不会意外漂移。2.2 坐标系陷阱投影坐标不等于经纬度ArcMap中有两种坐标系需要区分地理坐标系用经纬度表示位置单位是度。常见的有WGS84地理坐标系、CGCS2000地理坐标系。投影坐标系用平面直角坐标表示位置单位是米。常见的有WGS84 Web Mercator、高斯-克吕格投影、UTM投影等。绝大多数专业数据都使用投影坐标系因为投影坐标便于测量长度和面积。但四至坐标要求经纬度所以必须把数据框范围从投影坐标系转换到地理坐标系。举个例子某幅图使用高斯-克吕格投影数据框范围可能是XMin504123.45YMin3387654.20这样的数值。如果把这个数字直接放到图廓外就是明显的制图错误因为四至标注应该写成“东经116°23′45″116°47′12″北纬30°35′28″30°51′06″”这样的形式。要特别注意的是如果数据本身是北京54、西安80等老坐标系转换到WGS84或CGCS2000经纬度时需要指定地理变换参数。ArcMap里有内置的变换方法但不同地区参数可能不同。不确定的情况下先用“投影”工具测试几个控制点确认转换结果是否符合预期。2.3 界面读取和arcpy读取分别怎么做先说界面读取方式适合快速查看右键数据框 → 数据框属性 → 数据框标签页下方会显示当前范围格式是XMin、YMin、XMax、YMax。在单位下拉框里可以切换显示单位。如果是投影坐标系单位下拉框里可选的是米、千米、英尺等未必能直接切到经纬度。此时我建议用arcpy方式更靠谱。arcpy读取数据框范围的代码非常简单在ArcMap的Python窗口中运行即可import arcpy mxd arcpy.mapping.MapDocument(CURRENT) df arcpy.mapping.ListDataFrames(mxd)[0] extent df.extent print(extent.XMin, extent.YMin, extent.XMax, extent.YMax) print(extent.spatialReference.name)这里有个容易忽略的点df.extent返回的是数据框当前的工作范围坐标系就是数据框的坐标系。如果数据框坐标系是投影坐标系打印出来的就是米制数值。要得到经纬度还需要进行投影转换下一节给出完整代码。3. 静态图幅做法从数据框属性到布局标注的完整流程3.1 锁定范围后再取四至避免坐标来回漂静态出图的规范流程我建议按以下顺序操作打开MXD加载好所有图层设置好数据框坐标系。在数据框属性里根据图幅要求设置比例尺或固定范围。在布局视图里调整数据框大小让图面构图合适。确认图幅范围不再变化后再开始标注四至。很多人的习惯是先构图再设置坐标系这也可以但务必确保“数据框属性 → 范围”里显示的最终范围和实际打印出图的范围完全一致。锁定范围这一步很容易被跳过。如果你用的是“自动”范围那么只要在布局视图里不小心拖动了一下数据框范围就会变化四至坐标自然也跟着变。等打印出来才发现图上标注的坐标和实际图面范围对不上返工成本很高。所以在出图前把范围锁定或比例尺固定是一个值得养成的习惯。3.2 用arcpy把数据框范围精确换算成经纬度这里直接给出可复用的转换代码。逻辑是先把数据框四角构造为面要素然后用projectAs换算到WGS84或CGCS2000地理坐标系再读取面的范围。# -*- coding: utf-8 -*- import arcpy def df_extent_to_geo(df, geo_code4326): 将数据框范围转换为经纬度范围 geo_code: 4326为WGS844490为CGCS2000地理坐标系 extent df.extent sr extent.spatialReference # 根据数据框范围构造闭合多边形 corners [ [extent.XMin, extent.YMin], [extent.XMax, extent.YMin], [extent.XMax, extent.YMax], [extent.XMin, extent.YMax], [extent.XMin, extent.YMin] ] array arcpy.Array([arcpy.Point(corner[0], corner[1]) for corner in corners]) polygon arcpy.Polygon(array, sr) geo_sr arcpy.SpatialReference(geo_code) # 投影转换 try: polygon_geo polygon.projectAs(geo_sr) except Exception as e: print(投影转换失败可能需要先定义地理变换, e) return None new_extent polygon_geo.extent return new_extent mxd arcpy.mapping.MapDocument(CURRENT) df arcpy.mapping.ListDataFrames(mxd)[0] geo_extent df_extent_to_geo(df, 4326) if geo_extent: print(经度范围{} ~ {}.format(geo_extent.XMin, geo_extent.XMax)) print(纬度范围{} ~ {}.format(geo_extent.YMin, geo_extent.YMax))这里的重点在于projectAs作用于几何对象而不是直接作用于数值。直接把投影坐标的XMin加个公式转换成经纬度是不严谨的因为投影变形在不同位置、不同带号下表现不一样。构造多边形再转换是让ArcGIS几何引擎去完成正确的地理计算。如果你面对的是高精度测绘出图建议使用CGCS2000地理坐标系代码4490而不是WGS84代码4326。虽然两者在多数小比例尺场景下差异不大但国土、规划领域的正式图件坐标系标注要跟项目基准一致用WGS84容易被人挑毛病。3.3 把十进制度格式化成度分秒并放置到布局中拿到十进制度经纬度后通常还需要转成度分秒格式放到图面上。格式转换函数可以这样写def decimal_to_dms(deg, coord_type): 十进制度转度分秒 coord_type: lon 或 lat if coord_type lon: hemi 东经 if deg 0 else 西经 else: hemi 北纬 if deg 0 else 南纬 abs_deg abs(deg) d int(abs_deg) m_full (abs_deg - d) * 60 m int(m_full) s (m_full - m) * 60 return {} {}°{:02d}′{:05.2f}″.format(hemi, d, m, s) # 用法示例 lon_min_dms decimal_to_dms(geo_extent.XMin, lon) lon_max_dms decimal_to_dms(geo_extent.XMax, lon) lat_min_dms decimal_to_dms(geo_extent.YMin, lat) lat_max_dms decimal_to_dms(geo_extent.YMax, lat) print(lon_min_dms, ~, lon_max_dms) print(lat_min_dms, ~, lat_max_dms)输出效果类似东经 116°23′45.60″ ~ 东经 116°47′12.30″ 北纬 30°35′28.10″ ~ 北纬 30°51′06.45″得到文本后在ArcMap布局视图里插入文本框把坐标放进去。常见的排版方式有两种图幅顶部写“北至”底部写“南至”左侧写“西至”右侧写“东至”。图幅右上角以“四至坐标N 30°51′06″S 30°35′28″E 116°47′12″W 116°23′45″”的形式集中于一处。我个人更推荐第一种分布在四个方向直接对应四至语义检查起来很直观。放置文本框时让坐标文字沿图廓线居中或对齐用等宽字体避免数字对不齐。3.4 配合经纬网标注图面更专业这里额外提一个制图技巧除了四至坐标文本可以添加经纬网Graticule让图面自动带上经纬度刻度。方法右键数据框 → 数据框属性 → 格网选项卡 → 新建格网 → 选择“经纬网”设置经纬网间隔比如每一度、每30分或每20分根据图幅比例尺灵活设置。在“属性”里可以设置标注格式ArcMap支持十进制度、度分秒、负号等多种格式。经纬网的好处是不只在图廓外标注四至图内还有经纬度参考线方便专业读者量算位置。缺点是如果比例尺大、图面密集经纬网容易把图层内容遮住。一般出图为A4或A3分辨率下经纬网文字大小不要超过7号字线宽设置细一些颜色用浅灰色避免喧宾夺主。4. 批量图幅做法数据驱动页面配合arcpy自动刷新四至坐标4.1 数据驱动页面的基础配置当图幅数量很多比如一个几十页的地图册手工标注四至完全不现实。这时应该用数据驱动页面Data Driven Pages配合arcpy在每一页根据当前索引范围动态更新文本元素。先做索引要素。ArcToolbox里有“制图工具 → 数据驱动页面 → 网格索引要素”可以快速生成一个覆盖整个工作区的格网索引面。每一个面代表一页地图属性里可以写页码、名称、图幅编号等。然后右键数据框 → 数据驱动页面 → 配置在“定义数据驱动页面”里选择索引图层选择名称属性比如图幅号勾选“按要素范围定义数据框范围”这样每一页数据框会自动缩放到当前索引面的范围然后在布局视图里插入页码、图幅号等动态文本这些ArcMap原生支持直接“插入 → 动态文本 → 数据驱动页面”选择对应属性即可。但要注意四至经纬度不属于数据驱动页面的标准属性列表。我试过用动态文本里的表达式去读取当前页面的范围但在ArcMap 10.x里非常不稳定有的版本能显示换台机器就变空白或者显示成0.000000。所以对于四至坐标这种需要转换的动态文本最稳妥的还是用arcpy逐页更新文本元素。4.2 为什么我放弃了“纯动态文本”方案曾经我天真地以为只要地图册是数据驱动页面四至坐标就能用某种动态文本属性直接插入。查了一圈官方文档又试了在动态文本里写VBScript表达式结果发现ArcMap的动态文本对数据驱动页面开放的是“页面名称”、“页码”、“页数”这类字段并没有直接暴露当前页面的XMin/YMin/XMax/YMax。也有网友分享用XML表达式方式去取范围但实测下来有两个问题一是表达式语法在不同Service Pack版本下兼容性不佳二是即便显示出来坐标仍然是投影坐标系的米制大数没法自动转成度分秒。出图时还经常遇到内容显示为“0.0000”的怪现象排查一圈发现是动态文本缓存没有刷新。所以我最终采用的方案是布局中放置一个固定名称的文本框每次切换页面时用arcpy读取当前数据框范围格式化好四至文本后直接修改文本框内容。这种方案极端稳定没有任何花哨的依赖项从ArcMap 10.0到10.8都能跑。4.3 完整脚本逐页更新四至坐标并导出PDF下面给出一个完整的脚本可直接改路径后使用。脚本的核心逻辑是打开MXD。定位到名为“四至坐标”的布局文本元素。逐页遍历数据驱动页面。每一页先切换到当前页刷新视图。读取数据框范围并转换为经纬度。更新文本元素内容。导出当前页为PDF或者把内容保存回MXD。# -*- coding: utf-8 -*- import arcpy import os mxd_path rD:\atlas\atlas.mxd out_dir rD:\atlas\pdf os.makedirs(out_dir, exist_okTrue) mxd arcpy.mapping.MapDocument(mxd_path) df arcpy.mapping.ListDataFrames(mxd)[0] # 假设布局中有一个文本框名称为“四至坐标” coord_text None for el in arcpy.mapping.ListLayoutElements(mxd, TEXT_ELEMENT): if el.name 四至坐标: coord_text el break if coord_text is None: raise Exception(未找到名为‘四至坐标’的文本元素请先在布局里添加一个文本框并命名) def decimal_to_dms(deg, coord_type): if coord_type lon: hemi 东经 if deg 0 else 西经 else: hemi 北纬 if deg 0 else 南纬 abs_deg abs(deg) d int(abs_deg) m_full (abs_deg - d) * 60 m int(m_full) s (m_full - m) * 60 return {} {}°{:02d}′{:05.2f}″.format(hemi, d, m, s) def build_coord_text(extent): lon_min decimal_to_dms(extent.XMin, lon) lon_max decimal_to_dms(extent.XMax, lon) lat_min decimal_to_dms(extent.YMin, lat) lat_max decimal_to_dms(extent.YMax, lat) text 东至 {}\n南至 {}\n西至 {}\n北至 {}.format(lon_max, lat_min, lon_min, lat_max) return text # 逐页处理 for page_num in range(1, mxd.dataDrivenPages.pageCount 1): mxd.dataDrivenPages.currentPageID page_num arcpy.RefreshActiveView() extent df.extent # 转换为经纬度 sr extent.spatialReference corners [ [extent.XMin, extent.YMin], [extent.XMax, extent.YMin], [extent.XMax, extent.YMax], [extent.XMin, extent.YMax], [extent.XMin, extent.YMin] ] array arcpy.Array([arcpy.Point(c[0], c[1]) for c in corners]) polygon arcpy.Polygon(array, sr) geo_sr arcpy.SpatialReference(4326) # 需要CGCS2000可改为4490 try: polygon_geo polygon.projectAs(geo_sr) except Exception as e: print(第{}页投影转换失败{}.format(page_num, e)) continue geo_extent polygon_geo.extent coord_text.text build_coord_text(geo_extent) # 导出当前页PDF out_pdf os.path.join(out_dir, page_{:03d}.pdf.format(page_num)) arcpy.mapping.ExportToPDF( mxd, out_pdf, page_range{}-{}.format(page_num, page_num), resolution300, image_qualityNORMAL ) print(已导出第 {} 页{}.format(page_num, out_pdf)) print(批量导出完成)需要注意如果要输出包含所有页面的单个PDF可以使用arcpy.mapping的PDFDocument类把每页PDF按顺序合并pdf_path os.path.join(out_dir, atlas_full.pdf) pdf_doc arcpy.mapping.PDFDocument.create(pdf_path) for page_num in range(1, mxd.dataDrivenPages.pageCount 1): page_pdf os.path.join(out_dir, page_{:03d}.pdf.format(page_num)) pdf_doc.appendPages(page_pdf) pdf_doc.saveAndClose()如果不方便生成单页PDF再合并也可以在导出时直接把整个文档导出为一个多页PDF但那样就无法在导出过程中修改文本元素。因此上面用“逐页导出再合并”的思路虽然多了一步但灵活性最高。4.4 批量流程中的文本对齐与命名细节在批量方案里文本元素的命名很关键。ArcMap中插入多个文本框时默认名称都是TEXT_ELEMENT如果不改名脚本会搞不清更新哪一个。建议在布局视图里选中文本框后在“属性”里把名称改成唯一标识比如四至坐标、NORTH_COORD。另外文本框中如果有换行符建议在脚本中用\n连接同时确保文本框的大小能容纳下四行文字。我遇到过因为文本框太小文字溢出到页面外的状况。可以在脚本中设置文本元素的宽度和高度coord_text.elementWidth 12 coord_text.elementHeight 4单位是页面单位通常为厘米依据实际情况调整。文字对齐方式设为居中并设置字体大小保证各种页面的四至文本不会忽大忽小。5. 我会踩过的那些坑单位、旋转、动态文本不刷新、跨坐标系转换5.1 坐标显示为“大数”而不是“经纬度”的排查链路批量运行时发现第一页导出的四至是XMin50412345.678这样的数值而不是经纬度。我的排查链路是这样的第一步先输出extent.spatialReference.name确认数据框坐标系是投影坐标系。第二步检查polygon.projectAs(geo_sr)这一行是否报错。结果没有报错但输出还是大数。最后发现问题出在我获取geo_extent polygon_geo.extent之后又错误地把geo_extent.XMin直接传给了格式化函数而没有确认XMin单位。实际上polygon_geo.extent返回的是地理坐标系的经纬度输出应该是116度左右。但当时我调试脚本时直接打印了没有转换前的df.extent.XMin打印出来自然是大数。看起来像是脚本没转换其实是我看错了变量。这个坑不算复杂但很能说明问题调试时一定要把中间结果逐行打印不能凭记忆推断。建议在转换后立刻打印一行print(转换成功, geo_extent.XMin, geo_extent.YMin, geo_extent.XMax, geo_extent.YMax)看到数字在-180到180之间经度范围就对了。5.2 数据框旋转后四至怎么算有些出图场景为了让道路走向尽量横平竖直会把数据框旋转一个角度比如真北方向不朝上需要旋转30度。这时候四至经纬度怎么算很多人会直接拿旋转前图层范围的四至作为结果这是错的。旋转数据框后图面显示的范围是旋转后的外接矩形四至必须按旋转后的实际可见范围来计算。在arcpy里df.extent已经考虑到了数据框旋转角会返回旋转后的外接矩形范围。因此脚本里用df.extent直接取数在大多数情况下是正确的。但如果你的地图册里还用了页面旋转字段比如根据线要素方向自动旋转需要验证一下每一页的df.extent是否为旋转后的范围。我遇到过一次页面旋转后四至和图上格网明显对不上的情况最后是在arcpy里手动读取df.rotation属性再对四个角点坐标做旋转矩阵换算解决问题。旋转角不为零时手动在布局视图里读取数据框范围是最容易出事的。界面显示的“范围”有时候还是旋转前轴对齐范围或者显示的是旋转后的外接矩形不同版本行为不一样。所以我始终建议用arcpy取数并且尽量专门写一个函数处理旋转角def get_rotated_extent(df): ext df.extent rotation df.rotation if abs(rotation) 0.0001: return ext # 通过数据框的矩形边框计算旋转后的外接范围更准确 corners [ [ext.XMin, ext.YMin], [ext.XMax, ext.YMin], [ext.XMax, ext.YMax], [ext.XMin, ext.YMax] ] import math rad math.radians(rotation) xs [] ys [] for x, y in corners: xr ext.XMin (x - ext.XMin) * math.cos(rad) - (y - ext.YMin) * math.sin(rad) yr ext.YMin (x - ext.XMin) * math.sin(rad) (y - ext.YMin) * math.cos(rad) xs.append(xr) ys.append(yr) return arcpy.Extent(min(xs), min(ys), max(xs), max(ys), ext.spatialReference)这个函数直接返回旋转后的包围盒再对这个包围盒做投影转换得到的就是图面实际显示的四至范围。5.3 动态文本不刷新、显示空白或旧值遇到最多的问题是脚本跑完网页生成的MXD里文本框内容还是上一次或空的。常见原因有三个文本框名称不对脚本更新了A文本框布局上展示的是B文本框。当前页面没有在ArcMap前台激活视图尚未刷新。MXD是以只读方式打开修改没有写入内存。解决办法脚本开头用arcpy.mapping.MapDocument(mxd_path)打开文件而不是CURRENT更新完文本元素后调用arcpy.RefreshActiveView()导出PDF之前可以调用一次arcpy.mapping.ExportToPDF强制读取最新内容。另外如果使用CURRENT方式在ArcMap里运行脚本每次更新文本后建议稍等一下因为ArcMap界面刷新是异步的。导出前临时把文本元素移个单位位置再移回来也可以触发强制刷新但属于偏门技巧非必要时不用。coord_text.text new_text arcpy.RefreshActiveView()5.4 北京54、西安80转WGS84容易忽略地理变换如果你的原始数据是北京54或西安80数据框范围转换到WGS84经纬度时不能直接用projectAs因为涉及不同基准面需要指定地理变换方法。在ArcMap中配置数据框属性 → 坐标系 → 地理坐标系变换可以添加适合当地的地理变换。在arcpy的projectAs方法中也可以在第二个参数位置传入变换对象。实际上polygon.projectAs(geo_sr)执行时如果没有找到默认变换会抛出异常。遇到报错时按ERROR信息提示去下载或选择合适的地理变换文件即可。这里建议如果最终出图要求是CGCS2000尽量直接把源数据通过“投影”工具或者“定义投影/投影栅格”工具统一成CGCS2000而不是在脚本阶段才转换。这样四至转换的误差更小也符合当前主流测绘标准。5.5 精度位数到底写多少才合适做四至标注时经常有人拿不准经纬度到底该保留几位小数。我的建议是分用途图面人工阅读度分秒格式写到秒秒保留12位即可对应地面精度大约3米到0.3米足够普通图幅定位使用。数据接口或数据库存储用十进制度保留6位小数约0.1米精度这是很多GIS系统的通用精度标准。正式测绘成果按照项目设计和规范执行有的要求秒后保留两位有的要求十进制度后保留8位不要擅自决定。我形成一个习惯图面上的四至文本统一走度分秒格式脚本内部计算和存储永远使用十进制度高精度值只在显示时格式化。这样既满足阅读习惯又不会丢失精度。另外格式函数里秒这一项我用了05.2f保证不足两位小数时补零比如30°35′28.10″。如果只是用普通整数秒会出现28.1″和28.10″混排的情况略显粗糙。最后分享一点个人经验做四至经纬度标注这件事看上去只是个不起眼的排版细节但真正做起来牵扯到坐标系转换、数据框范围逻辑、数据驱动页面、脚本自动化等一串东西。我踩过几轮坑之后最大的体会是不要用手在界面上抄坐标哪怕只出一张图也值得把arcpy脚本跑一遍。原因很简单脚本是可复现的今天的MXD被改动后明天重新运行一次脚本就得到最新坐标手动抄的话每次改动都得跟着重来一遍。另外一个体会是出图交活之前务必用其他工具交叉验证一下四至。比如在ArcMap里添加一个经纬度点或者用ArcGIS Online底图对比一下图幅位置。坐标标注错了容易被审图的人一眼看出来返工事小影响专业信誉事大。如果你用的是ArcGIS Pro改用布局中的动态文本加坐标属性会方便不少但ArcMap 10.x环境里用文本元素加arcpy更新这个方案依然是最稳、最通用的做法。希望这篇记录能帮你少走点弯路。