做2D排样(2D Nesting)的朋友,无论是用商业套料软件还是自己写脚本,恐怕都遇到过同一个坎:图形文件拖进去很容易,零件数据却不知道往哪里填。排样引擎真正要的不是一张画满轮廓的图,而是一份它能读懂的零件清单——哪个零件要做多少个、多厚、什么材质、允不允许旋转。这份清单在绝大多数软件里,就是CSV文件。
围绕这个主题,我结合自己用过的几款排样工具和踩过的坑,把"如何定义一份让排样软件满意的CSV零件数据"这件事完整梳理一遍。这篇文章不会只讲"点哪里导入",而是会把字段设计、生成方式、编码陷阱、验证思路和排查路线都串起来。适合正在做激光切割、钣金下料、木工开料或任何涉及二维套料的工程师阅读,也适合写排样脚本的开发人员参考。
1. 先把CSV在2D排样流程中的真实位置摆正
1.1 排样引擎需要的不只是图形
很多第一次接触2D Nesting的人会误以为排样软件主要吃DXF或者DWG,把图导进去就能自动套料。这个理解只对了一半。图形文件解决的是"零件长什么样"的问题,而排样引擎在计算时还需要知道"这个零件要做多少个""用什么板材""板厚多少""纹理方向能不能转"这些工艺属性。
我最早做套料的时候,直接在CAD里手动画完所有零件,然后一股脑导入排版模块,结果软件只识别出了第一块板上的几个图形,数量完全乱套。后来才醒悟,商业排样软件的标准输入方式通常是两条腿走路:DXF或DWG提供轮廓几何,CSV提供零件属性。两者通过零件编号(Part ID)关联起来。CSV里的每一行对应一种零件,而不是一个物理零件。
所以CSV在排样流程中的定位,可以理解成一张"加工任务单"。图纸负责描述形状,CSV负责描述"做多少、用什么做、有什么限制"。缺了CSV,再漂亮的DXF在排样引擎眼里也只是一堆没有归属的线条。
1.2 一份零件CSV背后是完整的工艺数据
用CSV承载零件数据,本质上是在做信息建模。它把三维世界里的零件信息降维成二维表格,供排样程序逐行解析。排样计算时涉及的数据通常可以分为四层:
- 识别层:零件编号、零件名称、所属图号或订单号。
- 数量层:单个零件需要的数量,以及是否按套(Set)计算。
- 几何层:零件的外形尺寸(长、宽),有时还包括面积和周长。
- 工艺层:板材材质、厚度、允许旋转角度、纹理方向、配对关系、优先级。
这四层信息里,识别层和数量层是CSV必须解决的,几何层有争议——因为图形文件里理论上已经包含轮廓尺寸,但部分软件的排样内核确实会优先读取CSV里的宽高来生成外接矩形,用于快速碰撞检测,再用DXF里的实际轮廓做精细排样。工艺层字段越多,排样结果越贴近车间真实加工条件,比如不允许旋转的零件如果强行旋转,虽然排版密度上去了,但后续丝印方向、木纹方向全错了,得不偿失。
1.3 为什么偏偏是CSV而不是Excel或数据库
这里有一个经常被问到的点:好多软件明明支持Excel,为什么还要强调CSV?原因很实际。CSV是纯文本格式,没有宏、没有隐藏工作表、没有格式干扰,每一行就是一条记录,解析逻辑极其简单,任何语言一个文件读取操作就能搞定。Excel格式本质上是Zip压缩包,里面是多个XML文件,解析起来复杂度高一个量级,而且同一列里出现数字和文本混合时,程序化读取会遇到很多类型推断问题。
排样软件面对的是上万个零件的数据量,用CSV传输数据最稳妥。它跨平台、跨语言、跨区域设置的表现都可控,排样引擎只要按逗号或分号切分每一行就能工作。对使用者来说,CSV还可以直接用记事本、Notepad++、VS Code打开检查,不用启动庞大的办公软件。这也是为什么几乎所有排样软件的文档里,导入零件数据的示例文件都是CSV。
2. 零件数据CSV的字段设计:最小集与进阶参数
2.1 无论如何都要有的核心字段
不同排样软件对CSV表头的要求不完全一致,但抽掉外壳,核心字段高度相似。我整理了一张通用字段表,任何一个排样项目基本都能映射到这个框架上:
| 字段名 | 类型 | 必填 | 说明 |
|---|---|---|---|
| Part ID | 字符串 | 是 | 零件唯一编号,与DXF中的图元/块名对应 |
| Quantity | 整数 | 是 | 该零件的需求数量 |
| Material | 字符串 | 是 | 材质名称,如Steel、Aluminum、MDF |
| Thickness | 浮点数 | 是 | 板厚,单位mm |
| Width | 浮点数 | 是 | 零件外形宽度,单位mm |
| Length | 浮点数 | 是 | 零件外形长度,单位mm |
Part ID是关联图形和属性的关键。很多软件要求CSV里的Part ID必须严格匹配DXF文件里的块名、图层名或特定属性值,大小写都不能差。如果两头对不上,软件通常会在日志里标注"未找到对应图形"一类的警告,但不会阻止你继续操作,结果就是零件进了清单却没进排版区,事后核对才发现少了一大片。
Quantity最好写成纯数字,不要带"个""件""pcs"这类单位后缀。排样软件解析整数时,遇到非数字字符可能直接报错,或者静默地把该行当成0处理。Thickness字段同理,用12.0而不是12mm。单位必须全项目统一,最常用的是毫米,但如果你的软件默认英寸,那所有尺寸字段都要用英寸值,混用单位导致成品放大的情况我见过不止一次。
2.2 能显著提升排样品质的进阶字段
最小字段只能让排样器"跑起来",真要让排样结果能直接下车间,进阶字段更重要。我按实用度排序说明:
- Rotatable(允许旋转):布尔值或枚举值,0表示禁止旋转,1表示可旋转90度,2表示任意角度。木工开料和带纹理的钣金件通常禁止旋转,普通金属板件则建议放开旋转以提升材料利用率。
- Grain Direction(纹理方向):字符串或布尔值,标识零件是否有纹理方向要求。这个字段在排样器内部起作用的方式是:有方向要求的零件只能以0度或180度摆放,不能做90度旋转。
- Pair ID(配对编号):用于成对出现的零件,比如左右对称件。指定配对关系后,排样器会尽量让成对零件处在同一张板上,方便后续折弯和焊接。
- Priority(优先级):整数。高优先级的零件优先占用板材的优质区域,低优先级零件用剩余边角料填充。
- Mirror(允许镜像):布尔值。某些冲压件镜像后模具方向不同,需要明确标识。
这些字段不是所有软件都支持,而且同一个意思在不同软件里字段名可能完全不同。比如有的软件用Allow Rotation,有的用Rotation Limit。所以拿到一个排样项目的CSV模板时,先打开软件的示例文件研究字段名,比对着文档猜效率高得多。
2.3 理解"尺寸字段"与轮廓文件的关系
这里要展开讲一个新手最容易困惑的点:既然DXF里已经有轮廓了,CSV里为什么还要Width和Length?
原因在于排样算法的数据结构。排样引擎在做碰撞检测和板材摆放时,第一阶段用的是零件的外接矩形(Bounding Box),快速粗排定位;第二阶段才用精确多边形做边界贴合和嵌套计算。CSV里的Width和Length承担的是第一阶段的加速职责。如果这个尺寸和DXF里的实际轮廓偏差过大,粗排阶段就会算出错误的占位,导致零件相互重叠或离得太远。
另一个实际场景是:有些企业从ERP导出的BOM里只有长宽和数量,没有对应图纸。这时候排样软件可以只用CSV的矩形数据做"矩形排样",先估算材料用量,等图纸到位再做精确排样。所以尺寸字段要尽力保证准确,如果你只有DXF而没有BOM尺寸,宁可先用CAD的测量工具量一遍再填,也别随手估一个。
2.4 一份可直接套用的字段模板
下面是我在实际项目中用过的模板,兼容性好,大多数软件都能识别:
Part ID,Quantity,Material,Thickness,Width,Length,Rotatable,Priority P-001,12,Steel_Q235,2.0,150.0,220.0,1,2 P-002,8,Steel_Q235,2.0,80.0,410.0,1,2 P-003,4,Al5052,1.5,120.0,120.0,0,1 P-004,20,MDF_18mm,18.0,60.0,900.0,0,3我习惯把Rotatable和Priority这类不一定每个软件都认的字段放在最后,这样即使软件只读取前六列,也不会导致列错位。类似的字段顺序策略,在对接不同客户提供的CSV时非常实用。
3. 三种生成零件CSV的实用路径
3.1 手工整理:适合小批量与打样
项目初期或者打样阶段,零件数量少,用手工整理完全够用。操作上最顺手的方式是打开Excel,按模板填入数据,然后另存为CSV。需要注意Excel的默认编码问题,我在下一章会详细讲,这里先提醒一句:尽量选择"CSV UTF-8(逗号分隔)"这个选项,而不是直接点另存为选CSV。
手工整理有个隐藏陷阱:零件编号里的前导零。如果零件号是00123,Excel默认会把它当数字处理,另存为CSV后前导零直接消失,变成123,DXF里却还有一个叫00123的零件,两边匹配不上。解决办法是在Excel里先把零件号列设为文本格式,或者自定义格式为"00000"。即使这样,导入排样软件后也要在数据预览里确认编号没变。
对于打样场景,手工整理的流程通常是:先在CAD里创建好零件块,再照着块名逐行填CSV。花十分钟把表填完,换来的是排样结果的确定性。手填时我习惯每条记录写完立刻复查一遍数量,这个环节出错率最高,往往不是填错行,而是漏填了某种零件。
3.2 Excel/BOM导出:适合已有物料清单的场景
如果公司已经有ERP或者生产BOM,零件数据通常不需要手敲,直接从系统导出Excel,再整理成CSV就行。这个路径下,最大的工作量在字段映射。ERP里的"物料编码"对应CSV里的Part ID,"需求数量"对应Quantity,"规格长宽"对应Width和Length,"材质描述"对应Material。
我处理过一次从用友系统导出的BOM,物料编码列里混着空格和中文全角括号,数量列里有的带单位后缀,长宽列是"150*220"这种合并格式。这些脏数据直接进排样CSV基本是废的,需要清洗。清洗的规则其实就几条:去空格、统一大小写、拆开合并尺寸列、剔除单位后缀。用Excel的函数能干,但数据量大或者规则复杂时,建议交给Python脚本处理,可持续性完全不一样。
BOM导出的一个常见误区是把所有层级都倒出来。一张订单可能有装配体、子装配体、单件三层结构,排样只需要最底层的单件数据。导出前一定要做过滤,只保留"自制件"和"原材料级"的零件,外购件和子装配体要在SQL或Excel里提前剔除。
3.3 Python脚本生成:大批量自动化的正解
排样项目一旦上了规模,比如一次性处理上千种零件,脚本生成是唯一靠谱的方式。最常见的做法是直接从DXF文件里提取零件块信息,自动生成CSV。这样Part ID和尺寸字段都不用二次录入,天然不会对不上。
我写过一个简单的脚本,核心思路是用ezdxf库读取DXF里的块定义,取块的边界框作为Width和Length,再把块名按规则映射到物料编码。代码大概长这样:
import csv import ezdxf doc = ezdxf.readfile("parts.dxf") msp = doc.modelspace() parts = {} for block_ref in msp.query("INSERT"): block_name = block_ref.dxf.name block = doc.blocks.get(block_name) extents = block.bbox() # ezdxf 0.18+ 支持快速包围盒 width = extents.size.x length = extents.size.y parts[block_name] = { "width": round(width, 2), "length": round(length, 2), } with open("parts_data.csv", "w", newline="", encoding="utf-8") as f: writer = csv.writer(f) writer.writerow(["Part ID", "Quantity", "Material", "Thickness", "Width", "Length"]) for pid, geom in parts.items(): writer.writerow([pid, 1, "Steel_Q235", 2.0, geom["width"], geom["length"]])这里quantity写死为1,实际项目中通常要从BOM导入。更完整的做法是脚本接受一个BOM文件作为输入,BOM里有每个块名的需求数量,脚本再解析DXF补全尺寸。用脚本的好处是整个过程可重复,图纸更新了重新跑一遍就能得到新CSV,不会出现"CSV和DXF版本不一致"这种经典事故。
脚本生成还有一个附带好处:可以在生成CSV时顺手写一个校验文件,记录每种零件的面积之和、数量之和,方便后面和排样结果对照。
4. 导入时最容易翻车的编码、分隔符和数值格式
4.1 编码问题:Excel另存为的默认编码与乱码
这一节值得每一个做排样的人认真看,因为编码问题占CSV导入失败的半壁江山。Windows上的Excel直接"另存为CSV"时,默认保存为ANSI编码,对于简体中文系统就是GBK。如果你的CSV里只有ASCII字符,GBK和UTF-8没区别,能正常导入。一旦零件名称或材质里有中文,比如"MDF_中纤板",用GBK编码的文件到了一个以UTF-8为默认编码的排样软件里,中文就会乱码。
更隐蔽的是UTF-8 BOM问题。大家知道Windows记事本存UTF-8文件时会加三个字节的BOM头(EF BB BF),很多排样软件的CSV解析器并不会跳过BOM,于是第一列表头就变成了"\ufeffPart ID"。有些软件容错性强能自动处理,有些则直接提示"找不到Part ID列"。这个问题在Linux服务器上运行的排样服务里尤其常见。
我自己的处理原则是:统一使用UTF-8无BOM编码,用VS Code或Notepad++把文件另存一遍。Excel保存的CSV如果实在想保留原样,就在导入排样软件前用脚本批量转一次编码。Python里一行就能搞定:
with open("raw.csv", "r", encoding="gbk") as f: content = f.read() with open("final.csv", "w", encoding="utf-8-sig") as f: f.write(content)注意这段代码读出来再写回去,实际生产环境里我会用errors="replace"先检查一遍有没有无法解码的字符,避免静默丢数据。
4.2 分隔符:逗号还是分号,这由区域设置决定
CSV的全称是Comma-Separated Values,按理说分隔符就是逗号,但实操里经常碰到用分号或者Tab分隔的文件。原因在于欧洲一些国家和地区的系统区域设置里,列表分隔符默认就是分号,Excel另存CSV时就会用分号替代逗号。
导入排样软件时,"导入后所有零件变成一个长字符串"或者"明明分了六列,软件只认出一列",八成就是分隔符不匹配。解决办法有三个:在源系统里改区域设置后重新导出;在排样软件的导入界面选择分隔符类型;用文本编辑器全局替换分号为逗号。但全局替换有风险,如果材质名称里本来就带着分号或逗号,直接替换会把字段内容截断。更稳妥的做法是用支持CSV引号解析的脚本去转换:
import csv with open("input.csv", "r", encoding="utf-8") as f: reader = csv.reader(f, delimiter=";") rows = list(reader) with open("output.csv", "w", encoding="utf-8", newline="") as f: writer = csv.writer(f, delimiter=",") writer.writerows(rows)csv库会自动处理引号包裹的字段,逗号和分号只要被双引号包住,就不会被错误切分。
4.3 前导零丢失与科学计数法的隐形坑
前面提过前导零问题,实际发生频率比我预想的高得多。有一次项目里所有零件编号是"01001"这种格式,我从ERP导出的Excel BOM里看着还正常,另存为CSV后导入排样软件,日志里一片"找不到零件01001的轮廓",最后定位到的原因是Excel把01001当成数字1001保存了。看起来只差一个0,匹配关系全断。
长数字科学计数法同样坑人。如果零件编号超过11位,Excel会显示为8.20123E+12这种科学计数法形式,写入CSV的也是这个字符串,排样软件拿它去匹配DXF块名,必然失败。
应对技巧很简单:在Excel里把编号列设置为文本格式,或者直接用记事本做"另存为"。如果数据已经在CSV里变成了1001,而你知道原本是01001,可以在Python里用zfill补回去:
part_id = "1001" fixed = part_id.zfill(5) # 得到 "01001"但最理想的还是源头控制,数据从ERP出来之前就定义好字段类型。
4.4 行结束符、空行和引号转义
行结束符是个存在感很低但偶尔发作的问题。Windows系统的CSV用CRLF(\r\n)作为行结束,Linux和macOS通常用LF(\n)。绝大多数解析器两种都认识,但一些老旧的排样组件可能只认CRLF,导致导入后最后一行数据不完整或者所有行挤成一团。如果遇到这种情况,用VS Code右下角把行结束符统一成CRLF再保存,通常能解决。
空行问题常出现在Excel导出的CSV末尾。Excel有时会在数据末尾多写一个空行,解析器如果不跳过空行,会在数据集里多出一条全是空值的记录。有的排样软件会把空行当成数量为0的零件,有的直接崩溃。导入前用文本编辑器检查一下文件末尾有没有空行,随手删掉,能省不少事。
引号转义则关系到字段内容本身带逗号的情况。按CSV规范,字段里如果包含逗号、引号或换行,需要用双引号把整个字段包起来,字段内的双引号用两个双引号转义。比如材质名称写成"Steel, Q235",解析器能正确识别为一个字段。但有些排样软件的解析器实现不完整,不支持引号转义,看到引号就直接报错。这种时候最省事的办法是让所有字段内容里都不要出现逗号,材质名称里用空格或者连字符替代。
5. 从CSV到排样结果:一次完整的验证流程
5.1 导入前的文件体检
拿到CSV之后,第一件事不是急着导入排样软件,而是先做一次文件体检。我用的是最朴素也最有效的方法:用VS Code或Notepad++打开文件,肉眼扫一遍。
体检清单如下:
- 第一行表头是否符合软件要求的字段名。
- 每一行的列数是否一致,可以用文本编辑器的列模式选中看对齐情况。
- 所有Part ID是否都有对应的DXF块名。
- Quantity列是否有0或负数。
- 所有数值列的小数点是否都是英文句点。
- 文件编码是UTF-8无BOM还是别的格式。
- 文件末尾是否有空行。
这些检查看起来琐碎,但能拦截掉八成以上的导入失败。其中列数一致性检查最容易被忽略,因为Excel里复制单元格时不注意会把两个字段塞进一个单元格,导出的CSV这一行就只有七列而其他行有八列,排样解析器按固定索引取字段时就会取到错位的值。
5.2 用脚本校验数据的数量与字段完整性
体检完了,我习惯再用Python脚本做一道程序化校验,尤其是在处理几千行数据的时候。脚本做三件事:统计总零件数、找出缺失字段的记录、检查Part ID是否有重复。
import csv from collections import Counter with open("parts_data.csv", "r", encoding="utf-8") as f: reader = csv.DictReader(f) rows = list(reader) total_quantity = 0 part_counter = Counter() missing_fields = [] for idx, row in enumerate(rows, start=2): if not row.get("Part ID") or not row.get("Quantity"): missing_fields.append(idx) try: qty = int(row.get("Quantity", 0)) total_quantity += qty except ValueError: missing_fields.append(idx) continue part_counter[row["Part ID"]] += qty print(f"总零件数: {total_quantity}") print(f"零件种类数: {len(part_counter)}") print(f"缺失字段的行: {missing_fields}") for pid, qty in part_counter.items(): if qty <= 0: print(f"异常数量: {pid}: {qty}")这里有一段需要注意:如果单个零件出现多次且Quantity求和后与BOM对不上,就要回头查是不是Part ID写重了。有些软件允许同一Part ID多行存在然后自动累加,有些则会直接报错,行为差异很大,尽量保证一个Part ID只出现一行。
5.3 在排样软件里核对最终结果
导入成功后,不能直接看排样图就完事。我的习惯是在生成预览后立刻做三组核对:
第一组:零件清单核对。排样软件的零件列表里,每个Part ID后面的数量是否和CSV里的Quantity一致。这个环节最能暴露匹配问题——如果某零件在列表里数量显示为0或者缺失,说明Part ID和DXF块名没对上是大概率事件。
第二组:板材利用率核对。先算一块理论上的简单排样,比如只放同一种矩形零件,把软件算出的利用率和手算值对比,偏差超过两个百分点就要警惕是不是尺寸字段或间距设置有误。这个数据同时也可以反过来验证CSV里的Width和Length是否正确。
第三组:输出报告核对。排样软件生成的下料报告或切割代码里,会注明每张板上有哪些零件。抽查其中一块板,和生产工单对照,确认零件归属和数量都正确。这一步虽然繁琐,但能让排样流程形成一个完整闭环。
6. 数据读不进去时,按这条路线排查
6.1 六个检查点按顺序走一遍
CSV导入报错或者数据读不进去的时候,按什么顺序排查直接决定了你要花多少时间。我给团队定过一个固定排查路线,按概率从高到低排列:
- 编码:有没有中文乱码,第一列字段名前面有没有BOM字符。
- 分隔符:导入界面里预览的列数对不对,如果是整段挤在一列,先查分隔符。
- 表头:字段名是否和软件要求完全一致,包括大小写和下划线。
- 数据类型:数量列有没有非数字字符,尺寸列有没有单位后缀。
- Part ID匹配:CSV里的零件编号和DXF块名能否对应上,重点看空格和零。
- 列顺序:软件是固定列顺序还是按表头识别,这决定了调整空间。
这六个检查点,每一步都可以用文本编辑器直接确认。我见过太多人抱着排样软件的报错日志反复研究,却忘了先用记事本看一眼文件本身——其实答案早就写在那里,只是没看。
比如热词里出现的"csv log unsuccessful"这类日志,经常是某一行数据格式不对导致整批导入中断。处理方式很简单:把日志指向的行号打开看一眼,改掉那一行的坏数据,重新导入。没必要为了一条脏数据反复整体调配置。
6.2 一个容易被忽略的列错位陷阱
有一个情况特别容易误导人:CSV文件本身没问题,软件也显示"导入成功",但实际数据全是错的。这通常发生在软件按固定列顺序读取、而你的CSV列顺序又不匹配的时候。比如软件认为第二列是Quantity,你的第二列却是Material,程序不报错,把"Steel_Q235"当成数量去解析。如果能解析成数字就可能忽略,解析不了就报类型错误;最隐蔽的是恰好某个材质名是"63",直接被当成数量63用了,这种错误排查起来极耗时间。
应对办法是:导入后立即在软件的数据预览界面里逐列核对,不要只看零件数量总数。如果软件没有预览功能,就导入一种已知数量很少的测试CSV,比如三行数据,这样即使读错位了也容易发现。
6.3 排查工具的推荐
除了排样软件自带的日志,我常用的排查工具就三样:
- VS Code:看编码、看BOM、看行结束符,右下角状态栏都能直接显示。
- Python的csv库:做分隔符转换、列数检查、字段校验,批量处理效率极高。
- Excel的数据预览:打开CSV时它会自动按当前区域设置切分,可以用来快速观察列结构。但注意Excel打开再保存CSV会改动编码和格式,所以Excel只用来"看",不要用来"存"。
这三个工具组合起来,基本覆盖了我遇到过的所有CSV导入问题。
最后再分享一个个人习惯:每次排样项目开始前,我会先把CSV模板和一份填写说明放在共享目录里,团队所有人都按同一套字段规则做事。CSV是排样流程里最不起眼的一环,但因为它和所有环节都相关,反而值得花二十分钟做一次标准化。模板一旦定下来,后面每个项目的效率都会明显不一样。