ezdxf 快速上手:用 Python 批量读写 DXF 图纸的完整实战手册
ezdxf 快速上手用 Python 批量读写 DXF 图纸的完整实战手册【免费下载链接】ezdxfPython interface to DXF项目地址: https://gitcode.com/gh_mirrors/ez/ezdxf做机械或建筑相关开发的人迟早会撞上一堵墙手头有一堆 DXF 图纸要处理要么打开 AutoCAD 一张张手动改要么自己写解析器跟一堆坐标数字搏斗。ezdxf 这个纯 Python 库就是来拆这堵墙的——它让你不装任何 CAD 软件就能用几十行代码完成 DXF 文件的创建、读取、修改和批量处理覆盖 AutoCAD R12 到 R2018 的全部主流版本。一个星期五的下午想象这个场景你刚接手一批设备的出图工作客户发来 120 张 DXF 图纸要求把墙体图层全部换成标准名称、统一线宽还要在每张图右下角补一行公司信息的文字。打开 AutoCAD 一张张改一晚上就没了。用别的语言写脚本先得处理 DXF 那套繁杂的组码格式光调试就要一两天。问题出在哪DXF 本质上是一组按行排列的组码 值数据比如0后面跟实体类型、10后面跟 X 坐标。手写解析器意味着你要自己处理编码、块结构、图层表、版本差异……而这些 ezdxf 全都替你做好了。它不只是一个读写器而是一个完整的 DXF 对象模型文档、图层、块、布局、实体全部映射成直观的 Python 对象。先花三分钟认识 ezdxfezdxf 是 Python 生态里最成熟的 DXF 处理库MIT 协议开源要求 Python 3.10 及以上Windows、macOS、Linux 通吃。它的核心能力可以概括为四句话写新建任意版本R12 到 R2018的 DXF 文档doc.saveas()一行保存读加载已有文件连 AutoCAD 之外的第三方软件写入的陌生标签都会原样保留不丢数据改图层、实体、块引用都能查询和修改批量操作正是它的主场查内置类似 CSS 选择器的查询语法一条msp.query(LINE[layer墙线])就能筛出目标实体。安装很简单基础版一条命令pip install ezdxf需要画图渲染导出 PNG、PDF 预览就装完整版pip install ezdxf[draw]装完可以先用命令行验证一下ezdxf自带一套命令行工具ezdxf info能快速查看文件结构ezdxf browse能打开一个图形化浏览器翻看实体数据ezdxf audit能检查文件健康度——这些后面都会用到。五分钟画出你的第一张图先不聊理论跑通一个最基础的脚本感受一下 ezdxf 的用法。下面的代码创建一个 R2010 版本的文档建一个图层画一条线、一个圆和一段文字import ezdxf from ezdxf import colors from ezdxf.enums import TextEntityAlignment # 1. 新建文档指定 DXF 版本 doc ezdxf.new(dxfversionR2010) # 2. 在图层表里登记一个新图层指定颜色 doc.layers.add(设计图层, colorcolors.RED) # 3. 拿到模型空间——所有实体都画在这里 msp doc.modelspace() # 4. 添加基本实体 msp.add_line((0, 0), (100, 0), dxfattribs{color: colors.YELLOW}) msp.add_circle((50, 50), radius10) msp.add_text( Hello ezdxf, dxfattribs{layer: 设计图层}, ).set_placement((0, 0.2), alignTextEntityAlignment.CENTER) # 5. 保存 doc.saveas(my_first_drawing.dxf)逐步拆解一下这几步在做什么ezdxf.new()创建的是内存中的完整文档结构dxfversion参数决定文件格式版本不传则默认 R2010doc.layers是文档的图层表add()返回新建的图层对象颜色用ezdxf.colors里的常量即可不用背 ACI 色号modelspace()返回模型空间布局这是实体LINE、CIRCLE、TEXT 等的容器ezdxf 里所有add_xxx()方法都挂在布局上注意add_text()返回文本实体对象set_placement()负责设置插入点和对齐方式这是 ezdxf 文本处理的惯用两步法saveas()写出文件R2010 默认是 ASCII DXF二进制格式也支持。跑完这段代码你就已经掌握了 ezdxf 全部工作流的三分之二——剩下的无非是把add_line、add_circle换成别的实体把新建换成读取。实战任务把一百张图纸的图层规范统一现在回到开头的场景。批量修改是 ezdxf 最值得学的场景因为手动做最痛苦而代码做最轻松。任务要求遍历一个文件夹里的所有 DXF确保墙体和标注两个图层存在且颜色正确最后另存到输出目录。import ezdxf from pathlib import Path def batch_update_layers(input_dir: str, output_dir: str): input_path Path(input_dir) output_path Path(output_dir) output_path.mkdir(exist_okTrue) for dxf_file in input_path.glob(*.dxf): # 读取文件结构有问题时抛异常下面单独处理 doc ezdxf.readfile(dxf_file) # 图层不存在才新建避免覆盖原有设置 if 墙体 not in doc.layers: doc.layers.add(墙体, color7) # 白色 if 标注 not in doc.layers: doc.layers.add(标注, color1) # 红色 # 另存到输出目录保留原文件名 doc.saveas(output_path / dxf_file.name) print(f处理完成: {dxf_file.name}) batch_update_layers(raw_drawings, processed_drawings)这段代码的几个关键点ezdxf.readfile()是读取文件的标准入口返回的doc结构和新建的完全一样所以读进来再改再存和从零画用的是同一套 API学习成本很低墙体 not in doc.layers先判断再添加是写幂等脚本的好习惯——重复运行不会把已有图层重置Path.glob(*.dxf)直接配合pathlib用文件夹遍历、子目录扩展都很自然。但真实世界的图纸没那么乖。文件可能是旧版本、可能被第三方软件动过、可能缺块定义。这时候readfile可能抛DXFStructureError。ezdxf 为此提供了专门的恢复模块用法是把ezdxf.readfile换成ezdxf.recover.readfileimport ezdxf from ezdxf import recover try: doc ezdxf.readfile(old_drawing.dxf) except ezdxf.DXFError: # 正常读取失败尝试容错恢复 doc, auditor recover.readfile(old_drawing.dxf)recover.readfile返回两个值尽力恢复的文档和一个auditor审计器。恢复不等于修复——你还需要跑一遍检查auditor doc.audit() # 对文档做全面体检 if auditor.has_errors: print(发现, len(auditor.errors), 个错误)doc.audit()会检查句柄引用、图层、块表、实体完整性等问题错误清单可以逐条打印出来人工决定怎么处理。把这一套读取 → 恢复 → 审计流程写进批处理脚本100 张图里哪怕有 10 张是坏的也能在几分钟内全部收尾。从能画到会用块、尺寸标注与查询批量改图层只是热身。真正让 ezdxf 值回票价的是下面这三样块、尺寸标注、查询过滤。块BLOCK是 DXF 复用的核心机制。一个螺栓、一个图框画一次之后用INSERT实体到处引用图纸体积小、改一处全图生效。定义和使用都极其直观# 定义块在块里画内容 block doc.blocks.new(螺栓) block.add_circle((0, 0), radius2) block.add_line((-2, 0), (2, 0)) # 引用块模型空间里放两个实例 msp doc.modelspace() msp.add_blockref(螺栓, (10, 10)) msp.add_blockref(螺栓, (30, 10))doc.blocks.new()创建块定义add_blockref()在布局中放置引用第二个参数是插入点坐标。更妙的是add_blockref()返回的对象支持.set_scale()、.set_rotation()同一个块可以缩成不同大小、转成任意角度。尺寸标注是工程图纸的刚需ezdxf 里加一个线性标注只要两行# setupTrue 会预置一套默认标注样式推荐创建图纸时开启 doc ezdxf.new(R2010, setupTrue) msp doc.modelspace() msp.add_line((0, 0), (100, 0)) # base 是尺寸线的位置p1/p2 是两个测量点 dim msp.add_linear_dim(base(0, -15), p1(0, 0), p2(100, 0)) dim.render()注意add_linear_dim()返回的不是最终实体而是一个标注覆盖对象必须手动调用.render()才会真正生成标注几何。这种两步设计让你可以在渲染前修改文字、样式等属性。水平、垂直、角度、半径、直径、弧长标注分别有add_angular_dim、add_radius_dim、add_diameter_dim等对应方法都在同一套模式下工作。查询过滤让改一部分实体变得轻松。ezdxf 的query()支持类似 CSS 的语法# 取模型空间里所有 LINE lines msp.query(LINE) # 取指定图层的圆且半径小于 5 circles msp.query(CIRCLE[layer墙体][radius5]) # 拿到实体后直接改属性 for line in lines: line.dxf.color 3实体属性通过.dxf.color、.dxf.layer这样的接口读写改完保存即可。配合前面学的批处理流程把某图层所有线改成虚线、颜色改红这种需求就是几行query加一个循环的事。这些语法细节在examples/目录里都能找到对应案例比如块引用的examples/blocks/子目录尺寸标注的examples/render/dimension_linear.py。图纸太大或已经损坏还有这些后手批量脚本处理小文件没问题但要是遇到 5GB 的巨型图纸呢ezdxf.readfile会把整个文件读进内存大文件直接吃满内存。ezdxf 为此提供了iterdxf插件用流式方式逐实体扫描内存占用恒定from ezdxf.addons import iterdxf doc iterdxf.opendxf(huge_drawing.dxf) line_exporter doc.export(only_lines.dxf) # 输出端也是流式的 for entity in doc.modelspace(): if entity.dxftype() LINE: line_exporter.write(entity) line_exporter.close() doc.close()iterdxf.opendxf()只建立索引、不加载实体doc.modelspace()返回的是迭代器配合doc.export()可以把筛选结果直接写进新文件。代价是比一次性读取慢一些但这是大文件场景下能处理和崩溃的区别。完整用法可以参考examples/addons/iterdxf.py。反过来如果只是要快速生成大量简单实体比如一万个随机圆还有更轻量的r12writer插件——它不建内存结构直接流式写出 R12 格式适合批量出数据文件from random import random from ezdxf.addons import r12writer with r12writer(many_circles.dxf) as doc: for _ in range(100000): doc.add_circle( (1000 * random(), 1000 * random()), radius2, )注意r12writer只写实体段不写 HEADER 和表段适合快速导出数据而不是生成完整工程图纸这个取舍要在选型时想清楚。检查一张陌生图纸的内部结构可以试试命令行工具ezdxf browse drawing.dxf # 图形化浏览实体与组码 ezdxf info drawing.dxf # 打印版本、段、表概要 ezdxf audit drawing.dxf # 全面体检ezdxf browse会弹出一个带结构树和属性表格的窗口左侧是 HEADER、TABLES、BLOCKS、ENTITIES 等段右侧显示选中实体的组码数据非常适合理解 DXF 内部结构。往深走3D 实体、表格与更多插件如果前面这些还不过瘾ezdxf 的扩展插件生态才是真正的进阶副本。3D 实体建模。通过 ACIS 模块ezdxf 可以读写 3D SOLID 实体配合pycsg插件还能做基本的构造实体几何CSG布尔运算——立方体挖孔、切角、差集一步到位相关的完整示例在examples/acistools/和examples/addons/pycsg.py里包括 Menger 海绵、圆环面等经典造型。表格绘制。table_painter插件能把结构化数据画成带边框和表头的表格实体配合.dxf里的行高列宽控制适合把清单、明细直接画进图纸图形算法。edgeminer模块实现了链构建算法能把一堆散乱的线段拼成连续的多段线、识别圆弧曲线还能做交叉验证。对从点云/轮廓重建图形这类任务这是现成的轮子其他常用插件一句话带过text2path把文字转成轮廓路径MTextExplode把多行文本炸开成单行文本meshex在 STL/OFF/OBJ 和 DXF 网格之间互转dxf2code把已有 DXF 逆向生成可复用的 Python 代码是学习别人的图纸怎么画的的好工具Importer能把另一份文档的块、实体、表项导入当前文档做图纸合并时很省事。这些插件的说明和示例分散在src/ezdxf/addons/与examples/addons/目录里按名字找即可。写在最后回到开头那个周五下午。有了 ezdxf 之后那 120 张图纸的图层统一、文字追加任务大概就是二十行脚本加一次运行的事剩下的时间你可以去喝杯茶。给刚上手的你三条实在的建议从官方示例抄作业仓库的examples/目录有 200 多个可直接运行的脚本按blocks/、entities/、render/、addons/分类几乎覆盖所有功能点比查文档快得多善用文档与测试docs/source/下的教程tutorials/子目录是循序渐进的官方讲解而tests/目录里的测试用例展示了各种边界情况的正确用法——遇到奇怪报错去测试里搜往往有答案写幂等的批处理脚本批量任务里坚持先判断再修改、异常单独捕获、输出到独立目录三原则脚本才敢放心交给别人跑。DXF 处理这件事过去是 CAD 软件的专属领地如今几百行 Python 就能自己掌控。从画第一根线开始把 ezdxf 变成你工具箱里的常驻成员吧。【免费下载链接】ezdxfPython interface to DXF项目地址: https://gitcode.com/gh_mirrors/ez/ezdxf创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考