
打印机催图这件事做过测绘和制图的人都不陌生。前一天下午五点接到电话明天上午要 180 张 1:1 万的图幅 PDFA3 打印图廓整饰要齐。如果你还在 ArcGIS 里一个一个地挪数据框、改图幅号、导 PDF那一晚上基本就交代了。我把这几年在 ArcGIS 分幅导出地图上摸出来的整套流程整理出来核心就是用索引图层加地图系列Map Series/数据驱动页面Data Driven Pages把重复劳动变成一次配置、批量产出再配合脚本把命名、排序、质检这些琐碎环节固化下来。不管你是刚接触 ArcGIS 的新手还是已经用了几年但每次出图还在手搓的老手这套东西都能直接用。1. 为什么地图非得拆成一幅一幅从纸张幅面到图幅接边很多人第一次接到分幅导出的需求时第一反应是我把地图范围拉大一点导一张大图不就行了。这个思路在小范围里能用一旦范围上到几十上百平方公里就会全面崩盘原因不在软件而在物理世界。1.1 一次导出大图的三个硬约束第一个约束是打印幅面。常规大幅面打印机最大也就到 A01189mm×841mm再大就得上喷绘或者拼版成本和精度都不划算。你在软件里导出一张巨幅地图最后还是要落到纸上纸张尺寸就是天花板。第二个约束是分辨率。假设你要覆盖 50km×50km 的范围硬塞进一张 A0 纸里比例尺大约是 1:42000。在这个比例尺下一栋房子不到一个像素道路和建筑的细节全部糊掉图面上根本认不出东西。想要细节就必须放大比例尺而放大比例尺就意味着单张纸能覆盖的范围变小范围一小就必须拆幅。第三个约束是文件体积和后期处理。一张覆盖几十平方公里的 300dpi 无损 TIFF 动辄好几个 GBPhotoshop 打不开看图软件卡死发给打印店还得压缩。拆成单页之后每个文件几十到几百 MB谁都能处理。这三个约束其实指向同一个结论分幅不是软件功能限制导致的妥协而是制图行业的常规工作方式它的本质是用固定的纸张幅面和固定的比例尺把连续的空间切成可管理、可打印、可拼接的碎片。1.2 分幅的三种底层逻辑选错一种后面全乱实际工作里遇到的分幅需求粗分只有三类但它们的索引图层构造方式完全不同一开始选错后面返工量巨大。标准图幅分幅按国家基本比例尺地形图的分幅规则来经纬差固定图幅号有严格编码规则。测绘成果、地形图、正式成果交付基本都走这条路。自由格网分幅按公里网或者按纸张尺寸反推的规则格网一格一公里、两公里都行工程图、施工图、规划图常用。图幅号自己定只要唯一就行。按要素分幅行政区、街道、片区、流域、项目标段直接拿边界要素当索引。管理类专题图、统计类图册基本是这种。这三种的共同点是都需要一个索引图层也就是一个由面要素组成的要素类每个面代表一页图的范围。ArcGIS 的批量分幅导出功能本质上就是遍历这个索引图层每个面生成一页布局。理解这一点后面所有配置都不难。1.3 比例尺、幅面、覆盖范围的换算先算清楚再动手分幅方案定不下来八成是因为没算过这三个量之间的关系。公式很简单实地宽度米 纸面宽度毫米× 比例尺分母 ÷ 1000把这个公式套到常用幅面上得到下表单位米纸张幅面横向尺寸(mm)1:50001:100001:200001:50000A4 横向297×2101485×10502970×21005940×420014850×10500A3 横向420×2972100×14854200×29708400×594021000×14850A2 横向594×4202970×21005940×420011880×840029700×21000A1 横向841×5944205×29708410×594016820×1188042050×29700A0 横向1189×8415945×420511890×841023780×1682059450×42050另一组必须记住的数据是国家基本比例尺地形图的分幅经纬差这是标准图幅索引图层能建对的前提比例尺经差纬差备注1:100万6°4°分幅编号的基准按行列号编码1:50万3°2°一幅 1:100万 含 4 幅1:25万1°30′1°一幅 1:100万 含 16 幅1:10万30′20′一幅 1:100万 含 144 幅1:5万15′10′一幅 1:10万 含 4 幅1:2.5万7′30″5′一幅 1:5万 含 4 幅1:1万3′45″2′30″一幅 1:5万 含 64 幅1:50001′52.5″1′15″一幅 1:1万 含 4 幅这里有个特别容易混淆的概念图幅范围和出图比例尺是两个独立的东西。一张 1:1 万的标准图幅实地范围大约 5.3km×4.6km随纬度变化如果你想把它打印在 A4 纸上打印比例尺必然接近 1:20000 而不是 1:10000。所以1:1 万图幅说的是图幅划分规则1:1 万打印说的是纸面比例两者能不能同时满足取决于你选的纸张够不够大。A4 装不下 1:1 万的 5km 范围A3 也勉强A2 横向 594mm 对应 5.94km 才刚好够。这个账一定要在动手前算清楚否则出到一半发现比例尺对不上整批图都得重来。2. 索引图层整套分幅出图的骨架怎么搭索引图层是整件事的地基地基歪了后面 Map Series 配得再漂亮也是白搭。我见过太多人离线数据做得漂漂亮亮最后卡在索引图层的图幅号重复、字段类型不对、坐标系不一致这些低级问题上。2.1 三种生成路径各自的适用场景和坑路径一生成渔网Create Fishnet。这是自由格网分幅的标配工具。你需要给定左下角原点坐标、行数、列数、单元格宽度和高度以及是否生成点要素和标注点。关键在于单元格宽高的单位必须和数据的投影坐标系一致。如果你的要素类是 CGCS2000 高斯克吕格投影单位米宽高就填 1000、2000 这样的米数如果数据是地理坐标系单位度你填 1000 就变成 1000 度生成的格网覆盖大半个地球这种错误我在初学阶段犯过一次之后就养成了先看数据坐标系再动手的习惯。渔网的另一个细节是格网原点。很多单位的图幅是按某个整公里数对齐的比如统一从 X500000、Y3000000 起算。渔网生成时可以把原点吸附到整公里这样生成的图幅号才规整。生成之后建议立刻加一个字段存图幅号命名规则用区域码行号列号行号和列号统一补零到三位比如A001007这样按文件名排序就是按空间位置排序打印店拼图的时候不会乱。路径二现成的标准分幅索引表。测绘单位一般都有按标准分幅做好的图幅索引矢量属性表里带图幅号、新旧图号、比例尺、经纬度范围、所属行政区。拿到这种数据先做三件事检查有没有重复图幅号、检查坐标系是不是投影坐标、检查几何有没有空值或者自相交。这三项检查用 ArcGIS 的属性表排序和几何检查工具几分钟就能搞定但能省掉后面几个小时的排查。路径三直接拿要素边界当索引。行政区、街道、片区这类数据看着最省事其实有两个坑一是飞地和多部件要素一个要素可能有多个分离的多边形Map Series 取外接矩形的时候会把不相关的区域一起框进来图面比例尺被拉得很小二是边界不规整相邻要素之间可能有细小缝隙或者重叠出图会出现莫名其妙的空白页或者重复区域。遇到多部件要素先做多部件至单部件拆分遇到缝隙先做拓扑检查。生成方式适合场景主要优点常见坑生成渔网工程图、规则格网尺寸精确可控可吸附整公里单位填错、原点没对齐标准分幅索引测绘成果、地形图图幅号规范直接可用图幅号重复、坐标系不统一要素边界行政区、片区管理图边界贴合业务无需额外建面多部件要素、缝隙与重叠2.2 属性表里必须提前备好的几个字段Map Series 和 Data Driven Pages 都靠读字段来决定这一页叫什么、多大比例尺、转多少度。这些字段在索引图层里必须提前建好临到配置面板里才发现没有就得退回去改数据特别耽误时间。字段名建议类型用途注意事项图幅号文本页面名称、导出文件名唯一、无非法字符、无首尾空格顺序号短整型/长整型控制导出顺序建议按空间位置排好再写值比例尺长整型每页固定的比例尺分母同一批图建议统一特殊图幅才单独设中心X / 中心Y双精度固定中心点位的分幅用计算几何取面要素质心旋转角双精度沿线路走向出图存的是数据框旋转角不是要素方位角备注文本成图日期、版本、责任人可绑定到动态文本文件名非法字符这个问题值得单独说。Windows 文件名里不能出现\ / : * ? |图幅号里如果带了斜杠或者冒号脚本导出时会直接报错或者更糟——静默生成一堆奇怪的目录。我的做法是在索引层里加一个文件名字段用字段计算器统一清洗一遍把所有非法字符替换成下划线脚本只认这个字段。排序同样是容易被忽略的一环。Map Series 默认按索引图层的 ObjectID 顺序翻页如果你的渔网是东一块西一块生成的ObjectID 顺序和空间位置完全对不上导出的文件顺序就是乱的。解决办法有两个用排序工具按图幅号生成一个新的索引要素类或者干脆新建一个顺序号字段手工按空间逻辑填一遍几十上百幅还好上千幅就用脚本按行列号算。2.3 索引图层的投影与要不要加缓冲索引图层必须和数据图层用同一个投影坐标系这条没有例外。我见过一次事故数据是投影坐标米索引层是从别的项目拷来的地理坐标度配好 Map Series 之后每页都显示一片空白因为数据框范围被解释成了度数范围和米制数据差了十几个数量级。至于要不要给索引面加缓冲Buffer这是分幅出图里一个经典分歧点严格分幅不加缓冲相邻图幅之间不重叠每个要素只出现在它所属的那幅图里跨界要素会被切断。正式成果、测绘交付多用这种图幅拼接后不重复、无冗余。带重叠分幅加缓冲给每个索引面外扩 20~100 米相邻图幅有重叠带接边处的道路、河流、注记在两幅图上都是完整的看图的人不用来回翻。工程汇报、施工交底图用这种体验更好。这两种做法的区别不在 Map Series 配置上而在索引图层本身。加缓冲是直接对索引要素类做 Buffer 并溶解得到的索引面之间自然重叠。但记住一旦加了缓冲每页的地图范围就比图幅本身大了一圈图幅号和图面范围之间就不再是严格对应关系交付的时候要在说明里写清楚否则验收会有争议。3. ArcGIS Pro 里跑通 Map Series参数逐项拆开讲ArcGIS Pro 的 Map Series 是现在的主流做法界面比老的 Data Driven Pages 清爽导出选项也多。但它的参数项比老版本多一些很多人卡在面板打不开翻页是翻页了但地图没跟着动这类问题上。我把整个流程按配置顺序讲一遍。3.1 建 Map Series 与关键参数的取舍前提是已经进入了布局视图Layout并且布局里有一个地图框Map Frame指向你要出图的地图。然后在功能区的插入Insert选项卡里找到地图系列Map Series按钮点击后布局右侧会弹出地图系列窗格。第一步是选类型。Spatial空间类型用于索引图层驱动Bookmark书签类型用于按预先保存的书签翻页Raster栅格类型用于影像分幅。做地图分幅导出99% 的情况选 Spatial。第二步是选索引图层然后勾选启用Enable。启用之后布局里会立刻跳到第一页你就能直观看到一页长什么样。接下来是真正决定成败的几个参数Page Name Field 和 Page Number Field。页面名称字段决定页面叫什么也决定动态文本和导出文件名能不能自动带上图幅号页码字段决定页序。这两个字段都必须在索引图层里存在而且名称字段最好唯一。Extent范围。这里有几种模式理解它们的差别比记住名字更重要居中并缩放Center and Scale模式页面范围由一个中心点加一个固定比例尺决定。这是规范出图必须用的模式。你可以在面板里填一个固定比例尺分母也可以绑定索引层里的比例尺字段让特殊图幅单独设置。最佳适配Best Fit模式页面自动适配索引要素的外接矩形比例尺由软件算结果是一堆小数。相邻图幅的比例尺会不一致拼图的时候对不上正式成果里绝对不能用。数据驱动Data Driven模式按索引层里存的范围字段来定页面灵活但容易出错除非有特殊需求一般不用。Margin边距。这个参数控制地图框内数据区到框边的留白单位是页面单位毫米或英寸。它的作用是给图廓整饰留空间——图幅号、图例、比例尺、指北针都要挂在布局上如果没有边距图面会顶到图框边缘打印出来被裁切。常规做法是四周留 10~15mm如果图廓整饰比较复杂留到 20mm。Rotation旋转。绑定索引层里的旋转角字段可以让每页的地图框按不同角度转。沿道路、沿河流、沿规划轴线出图的时候非常有用。这里有个经典错误索引层里存的应该是你希望数据框旋转多少度而不是要素本身的方位角。要素方位角 45 度东北方向数据框需要旋转的角度和它差 90 度很多人在这个换算上翻了车出图一看方向全反了。Optional Fields可选字段。可以把坐标系、空间参考、旋转、比例尺这些绑定到字段上让不同图幅用不同的设置。日常分幅出图一般只需要绑定比例尺和旋转角两个。3.2 动态文本与图廓整饰怎么和分幅绑定分幅出图最省事的地方在于图廓整饰里的可变信息全部可以用动态文本自动填不用改一次图幅就手打一次图幅号。ArcGIS Pro 里的插入动态文本入口在插入选项卡里常用的几类页Page类页名称、页码。对应图幅号和图序。地图框Map Frame类比例尺、坐标系名称、当前范围。比例尺文本会自动跟着每页变化。数据Data类可以从当前页对应的索引层记录里取字段值用来显示图幅备注、成图日期、作业单位这类信息。动态文本的语法看起来像 XML实际写起来不难比如显示页名的写法是dyn typepage propertyname/显示地图框比例尺会用带单位和取整属性的写法。我的建议是不要手工敲语法用面板里的插入对话框生成生成后再去改格式属性这样最不容易出错。接图表也叫图幅接合表是个比较特殊的整饰要素功能是标出当前图幅在整体中的位置。手工做不现实常规做法有两条路一是准备一份概略的总体范围底图作为固定装饰再单独准备一个代表当前图幅位置的点图层用地图系列查询Map Series Query让它只显示当前页对应的那个点二是干脆把接图表做成索引图层全局缩略图 当前页范围框的组合靠图层的定义查询配合脚本控制。第一条路更省事我一般推荐这条。顺便提一句Pro 里图层或者图层组可以绑定地图系列查询让图层只显示与当前页相交的要素。这个功能在做当前图幅范围线高亮接图表定位点这类效果时很好用具体选项的位置在不同版本里略有差异在图层属性或者图层组的右键菜单里找地图系列相关的设置项即可。3.3 导出格式、分辨率、地理信息三者的取舍配置好之后就是导出。布局标签页里有导出布局Export Layout功能弹出的窗格里几个选项需要重点理解格式选择。这是最影响最终效果的一项我整理成下面这张对照表格式矢量保留体积适用场景注意事项PDF是中等打印交付、正式成果必须勾选嵌入字体否则换机器字体错乱PNG否较大汇报截图、公众号配图无矢量放大后锯齿明显TIFF否极大存档、印刷厂印前建议 LZW 压缩否则体积失控JPG否小快速传阅有损压缩图上文字边缘会出现伪影正式交付我一律用 PDF理由有三个矢量要素线、面、文字在 PDF 里保持矢量放大不糊文件体积比同分辨率的栅格小得多PDF 还能保留地理配准信息用支持 geoPDF 的阅读器可以查看坐标。导出 PDF 时务必勾选嵌入字体选项这一项在字体环境不同的机器上就是能看和全是方框的区别。分辨率dpi。这里有个很多人搞混的点dpi 只影响栅格内容影像底图、透明图层、栅格化的图层效果不影响矢量要素。所以纯矢量地图150~200dpi 打印出来已经很清楚没必要拉到 600。带影像底图的地图底图按 dpi 采样300dpi 是打印的常规选择但要注意如果底图本身的源分辨率不够dpi 再高也只是把模糊放大。需要在屏幕上放大查看的图可以导 300dpi 的 PNG但单页体积会明显变大。页码范围与拆分。导出面板里可以选全部页、当前页或者指定范围。如果勾选按独立文件导出就会得到一堆单页文件不勾选则把多页合并进一个 PDF。批量交付通常要单页文件打印店好分配、好拼版把整套交给评审则合并成一个多页 PDF 更方便翻阅。导出面板本身对文件命名的控制能力有限想要按图幅号命名这种严格规则还是得走脚本。4. 还在用 ArcMapData Driven Pages 加 arcpy 批量脚本不少单位的工作环境还停在 ArcGIS Desktop 10.xData Driven Pages 就是那个时代的 Map Series。功能逻辑基本一致但配置入口、动态文本语法、导出方式都不同而且它和 Python 2.7 的 arcpy.mapping 搭配起来批量导出的脚本写法和 Pro 完全不一样。4.1 Data Driven Pages 的配置入口与几个限制配置入口在数据框属性里不是在菜单上。右键布局里的数据框选属性切到数据驱动页面选项卡。依次设置启用、索引图层、名称字段、排序字段、范围模式最佳适配或者居中加比例尺、旋转字段、空间参考、数据框边距。设置完点确定主工具栏上会出现翻页控件可以逐页预览。几个需要提前知道的限制一个 MXD 里可以放多个数据框但驱动分幅的通常是其中被指定为索引驱动的那一个其他数据框一般用来做定位图、剖面图这类辅助内容不要指望所有数据框都跟着翻页。这点在设计模板时就要想清楚。名称字段必须唯一否则翻页会出现重复页或者漏页。旋转字段和 Pro 一样存的是数据框旋转角方向换算的坑一样存在。索引图层一旦被别的程序锁定比如同时在另一个 ArcMap 会话里打开了配置会失败或者翻页卡住遇到这种情况先关掉其他会话或者把索引层复制到工程目录下再用。4.2 arcpy.mapping 批量导出脚本逐段解释在 ArcMap 里点文件导出地图也能一次导出全部页面并生成多页 PDF但文件命名不受控。要按图幅号命名就用脚本。下面这段是我常用的骨架# -*- coding: utf-8 -*- import arcpy import os mxd_path rD:\work\sheet_template.mxd out_dir rD:\work\out mxd arcpy.mapping.MapDocument(mxd_path) ddp mxd.dataDrivenPages if not os.path.exists(out_dir): os.makedirs(out_dir) for i in range(1, ddp.pageCount 1): ddp.currentPageID i name ddp.pageRow.getValue(SHEETNO) # 图幅号字段 name name.strip().replace(/, _).replace(:, _) out_pdf os.path.join(out_dir, name .pdf) arcpy.mapping.ExportToPDF( mxd, out_pdf, resolution300, image_qualityBEST, compress_vectorsTrue, image_compressionADAPTIVE, embed_fontsTrue, georef_infoTrue, jpeg_compression_quality85 ) arcpy.AddMessage(u已导出{}.format(name)) del mxd逐段说几个关键点mxd.dataDrivenPages拿到的是数据驱动页面对象前提是 MXD 里已经配置好并且启用了 DDP。如果这一步报错说明配置没生效别在脚本里折腾回去检查数据框属性。range(1, ddp.pageCount 1)是页号从 1 开始的遍历。currentPageID i切换当前页切换之后地图框范围会自动更新。这里有一个老版本的经典问题切页之后布局有时不刷新导出的还是上一页内容。补救办法是在循环里加一句强制刷新比如arcpy.RefreshActiveView()或者先导两页测试一下是否正常。ddp.pageRow.getValue(字段名)是读当前页对应索引记录的字段值。字段名大小写要完全一致写错了直接抛 IndexError这是新手最常见的报错。ExportToPDF的参数里resolution控制栅格采样精度embed_fontsTrue保证字体不丢georef_infoTrue写入地理配准信息image_qualityBEST让矢量路径尽量保留矢量特性。如果你的交付要求是 PNG把函数换成ExportToPNG并把 dpi 调低到 150 左右体积会友好很多。有一段经验值得单独提在 ArcMap 里跑这种循环导出一定要把工程里用不到的图层关掉。很多老 MXD 里躺着五六个从没删掉的在线底图或者历史数据图层平时不显示没关系逐页导出的时候每一页都要走一遍渲染管线200 页下来时间差可能是一小时和十分钟的区别。4.3 脚本跑不通时的排查顺序遇到脚本报错别急着改代码按下面这个顺序查八成问题都能定位现象最可能的原因处理方式IndexError 或字段取不到值字段名拼错或大小写不符打开属性表核对字段名逐字符比对导出全是空白页DDP 未启用、数据框未刷新检查数据框属性、加刷新语句重跑中文路径报编码错误Python 2.7 的编码问题换全英文路径或路径加 u 前缀只导出了第一页循环未正确切页检查 currentPageID 赋值是否在循环内导出速度极慢冗余图层、底图未关闭、网络盘写入关闭无关图层先写本地再拷贝文件名为空或乱码名称字段有空格或非法字符导出前统一清洗字段值排查这件事上我有个习惯先只导前 3 页做小样小样打开检查图幅号、比例尺、图廓、标注四项全部正确再跑全量。全量跑到一半发现图幅号字段用错了那种挫败感经历过一次就够了。5. 我踩过的坑分幅导出里最容易翻车的几个细节流程跑通只是及格真正决定出图质量的是一堆看起来不起眼的细节。下面这些坑都是我或者身边同事实际踩过的列出来供你对号排查。5.1 比例尺不一致与图幅错位最常见的事故来源就是用了最佳适配模式。它会按每个索引面的外接矩形自动算比例尺结果是相邻图幅的比例尺分母一个 9987、一个 10023你在屏幕上翻页看着没感觉打印出来并排一放同样的道路宽度差了一点点拼图的时候接不上验收方一眼就能看出来。规范做法是统一比例尺具体分两步先在索引层里新建比例尺字段统一填同一个值比如 10000然后在 Map Series 面板里把 Extent 设为居中并缩放并绑定这个字段。这样每一页的比例尺分母完全一致图幅范围也严格由索引面决定。另一个错位来源是坐标系不统一。索引层用地理坐标度、数据用投影坐标米配出来的结果就是每页范围忽大忽小纬度越高图幅看起来越窄。检查方法很简单把索引层和数据层放进同一个地图看两者的图幅框是否重合重合就没问题。还有一种错位来自渔网的单元格尺寸。有人按经纬度生成渔网格网宽度填 0.01 度看起来差不多是一公里实际上在不同纬度宽度差了不少图幅之间会出现细长缝隙。规则格网分幅一定要用投影坐标加米制尺寸。5.2 标注被裁、跨界要素被切断分幅出图的本质就是切图所以跨界要素被切断是正常现象但标注被切一半是很难看的。有三条处理思路一是给地图框设置一定的边距让边界外的要素能露出来一点点标注不至于正好卡在切线上。二是用 Maplex 标注引擎的允许标注超出要素范围和不移除标注选项减少标注被强行隐藏的情况。三是对于特别重要的地名标注在索引层里单独维护一份必须显示的注记点用动态文本或者专门的点图层挂上去。如果你想在严格分幅的前提下让接边要素看起来完整可以给数据框设置裁剪选项或者干脆接受每幅图只显示本幅范围内的部分这个事实在图的边角加接边说明。千万别用移动数据框的方式去凑那会让图幅边界和图幅号对不上后果比标注被切严重多了。5.3 字体、符号与渲染效果字体问题在跨机器协作时几乎必然出现。最常见的表现是你在自己电脑上标注是黑体到了打印店或者同事电脑上全变成方框。原因就是对方机器没装这个字体PDF 又没嵌入字体。三条对策把出图字体统一换成系统自带字体宋体、黑体、Arial 这类导出 PDF 时勾选嵌入字体或者把字体文件和模板一起打包交付。半透明图层和图层混合模式也要小心。图面上加了半透明的色块、光晕、阴影屏幕上很好看但导出 PDF 的时候这些效果有可能被栅格化打印出来颜色发闷、文字发糊。我的经验是正式出图的模板尽量克制图层效果透明色块能换成实色网纹就换掉投影和发光的装饰元素干脆不要。在线底图的分辨率上限也是个现实问题。在线瓦片在低比例尺下看着挺清楚一放到 1:2000 出图底图就糊了。这不是 dpi 的问题是源瓦片本身就只有那么多像素。要出大比例尺的图就必须换成本地的高分辨率影像或者矢量底图别指望提高 dpi 能把模糊救回来。5.4 批量导出的命名、排序与资源占用命名这块有三个坑非法字符、覆盖无提示、位数不对齐。非法字符前面说过统一清洗就好。覆盖无提示的问题在于图幅号重复的时候脚本会静默覆盖最后交付的文件少了几个你还在那儿纳闷。解决办法是在导出前做一次唯一性检查用字段统计功能看名称字段的唯一值个数是不是等于要素总数。位数不对齐的问题影响的是打印店图幅_1和图幅_10按字符串排序时顺序会乱所以行号列号统一补零到固定位数。资源占用方面最重要的一个习惯是整个批量导出过程只打开一次工程。有些脚本的写法是在循环里反复打开 aprx 或者 mxd跑几十页就内存爆掉。正确做法是循环外打开一次循环内只切换页码。另外如果输出目录是网络盘几百个 PDF 逐页写入会非常慢而且中途断网就前功尽弃。我现在的做法是全部先写到本地临时目录跑完之后用一个简单的拷贝操作整体搬到网络盘或者交付目录速度快很多也更可控。6. 把重复劳动交给脚本一套能直接抄的批量导出框架配置好模板之后剩下的工作本质上就是遍历页码、改文件名、导出、记录日志。这类活儿交给脚本人只需要管方案和验收。下面这套框架我在多个项目里复用过稍作修改就能用。6.1 ArcGIS Pro 版批量导出脚本# -*- coding: utf-8 -*- import arcpy import os import time APRX rD:\work\sheet.aprx LAYOUT_NAME 出图模板A3 NAME_FIELD SHEETNO OUT_DIR rD:\work\out_local start time.time() aprx arcpy.mp.ArcGISProject(APRX) layout aprx.listLayouts(LAYOUT_NAME)[0] ms layout.mapSeries if not ms.enabled: raise RuntimeError(地图系列未启用先在布局里配置好再跑脚本) if not os.path.exists(OUT_DIR): os.makedirs(OUT_DIR) idx ms.indexLayer total int(arcpy.management.GetCount(idx)[0]) print(索引图层要素数{}地图系列页数{}.format(total, ms.pageCount)) if total ! ms.pageCount: print(警告要素数与页数不一致检查空几何或重复要素) for i in range(1, ms.pageCount 1): ms.currentPageNumber i row ms.pageRow name str(row.getValue(NAME_FIELD)).strip() name .join(c for c in name if c not in r\/:*?|) out_pdf os.path.join(OUT_DIR, name .pdf) if os.path.exists(out_pdf): print(跳过已存在{}.format(name)) continue layout.exportToPDF( out_pdf, resolution300, image_qualityBEST, embed_fontsTrue, georef_infoTrue, page_range_typeCURRENT ) print([{}/{}] {}.format(i, ms.pageCount, name)) print(完成用时 {:.1f} 秒.format(time.time() - start)) del aprx这段代码里有几个设计上的取舍值得说明。ms.pageCount和索引要素数的对比是必做的一步。空几何、重复要素都会让页数和预期不一致早发现问题比导出几百页之后才发现强得多。文件名用列表推导式清洗非法字符看起来有点偷懒但胜在一行解决比写一长串 replace 清爽。如果图幅号里有中文str()在 Pro 的 Python 3 环境下不会出问题不需要像 10.x 那样纠结编码。跳过已存在文件这个判断在断点续跑的时候特别有用。批量导出到一半断网、断电、软件崩溃重跑的时候前面的成果不用重来直接从断的地方接着跑。page_range_typeCURRENT表示只导出当前页。如果你想要一个合并的多页 PDF改成全部页范围然后只调用一次导出即可。6.2 导出前后各做一次质检批量出图最怕的不是报错而是跑完了但有几页是坏的。所以导出前和导出后各做一次轻量质检成本很低收益很高。导出前的检查项索引层要素数与地图系列页数是否一致。图幅号字段是否有空值、是否有重复用属性表统计或者脚本检查。比例尺字段是否有空值如果绑定的是字段而不是常量。名称字段清洗后是否有重名。导出后的检查项我一般用文件体积做第一道筛子。正常的 A3 图幅 PDF 在几百 KB 到几 MB如果某个文件只有二三十 KB几乎可以肯定是空白页或者渲染失败的页面。写个小脚本扫一遍import os out_dir rD:\work\out_local for f in os.listdir(out_dir): p os.path.join(out_dir, f) size os.path.getsize(p) if size 50 * 1024: print(疑似异常{}{} 字节.format(f, size))第二道筛子是抽样。随机挑三到五页打开检查图幅号、比例尺文字、图廓整饰、边界处的标注是否正常。这一步花不了几分钟但能拦住绝大多数低级错误。6.3 模板和规范怎么在团队里固定下来一个人出图靠手感一个团队出图靠模板。把下面这些东西固化到模板工程里交接成本会低很多图层命名统一底图、影像、核心要素、注记、辅助线命名一致别人打开就知道哪层该开哪层该关。字体统一标注字体、字号、颜色全部在模板里定死不留下随便选一个的空间。图廓整饰尺寸固定内外图廓间距、图例位置、比例尺样式、指北针大小全部写成模板的一部分。导出预设固定把常用的导出设置存成导出预设脚本里也能直接引用避免每个人导出的 dpi 和压缩方式都不一样。索引层独立管理索引图层单独放在一个地理数据库里加一个版本或者更新日期字段出图记录里写清楚用的是哪个版本。交付清单建议固定成四项分幅 PDF 文件、索引图层含图幅号与范围、文件命名对照表、出图说明含坐标系、比例尺、成图日期、数据来源。打印店拿到这四样基本不用再来回问你。最后分享一个我自己用下来的小体会分幅出图这件事上花在前期算比例尺、建索引层、设计模板上的时间从来都不是浪费。我见过太多项目在后期发现比例尺不统一或者图幅号重复返工的工作量是前期准备的十倍以上。宁可前面多花两小时把账算清楚、把字段建全也不要指望后面用改一改把问题糊过去。至于脚本第一次写的时候可能会花上一个下午但从第二次开始每次出图就是改两个路径、按一下回车的事。