ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

Altium Designer交互式BOM生成:从数据导出到排错实战

2026/9/16 10:42:40 拓冰建站 浏览量
Altium Designer交互式BOM生成:从数据导出到排错实战 简介InteractiveHtmlBomForAD 是一份面向 AD 设计人员的快速 BOM 生成前端工具包基于 HTML、JavaScript 等技术实现可在浏览器中直接解析 AD 设计数据生成结构清晰、便于协作和审核的物料清单解决手动编制 BOM 效率低、易出错的问题。压缩包共 30 个文件以 js17 个、html3 个、css2 个等前端文件为主辅以 bat 批处理脚本、ini 配置文件、prjscr 项目脚本及 md 说明文档整体仅 139KB核心逻辑集中在 core 与 modules-lite 目录dist 目录则提供可直接运行的打包产物。工具支持通过 config.ini 自定义解析规则和输出格式Initialize.bat/UnInitialize.bat 可快速初始化和清理环境适合熟悉前端技术的 AD 用户集成到现有流程中。已有 1035 人学习下载对于需要提升 BOM 编制效率和准确性的工程团队是一份轻量而实用的参考实现。1. 拆开 InteractiveHtmlBom 压缩包之前先想清楚 BOM 为什么需要交互解开这个 zip里面是一套为 Altium Designer 准备的数据导出和 HTML 渲染脚本。熟悉 AD 的人都知道传统 BOM 是一张静态表格生产、贴片、维修时要拿着表格在板子上找位号眼睛累不说还容易漏。InteractiveHtmlBom 做的事是把 PCB 的元件位置图直接嵌进 HTML生成一个能点、能搜、能分层显示的交互式 BOM。这个工具解决的是“位号、坐标、封装和物料清单各在一处”的断档问题。适合正在做 PCB 评审、试产备料或文档归档的硬件工程师、工艺工程师和产线管理者。下面按数据从 AD 导出的顺序把这条链路拆开讲。2. InteractiveHtmlBom 的数据链路AD 导出的位号、坐标与封装如何组成 HTML2.1 从 AD 里正确导出三类文件InteractiveHtmlBom 本身不解析 AD 的工程文件它吃的是 AD 导出的纯文本数据。所以第一步不是写脚本而是从 AD 里导出三样东西坐标文件、BOM 表、板框信息。坐标文件在 AD 里叫 Pick and Place 文件路径是File - Assembly Outputs - Generates pick and place files。导出时需要确认单位选公制毫米格式选 CSV 或制表符分隔的 TXT这样后面用 Python 解析最省事。BOM 表的导出用Reports - Bill of Materials建议把 Designator、Comment、Footprint、Quantity 这几列固定带上其余列按项目需要勾选。板框信息较容易被忽略。坐标文件里有元件位置但没有电路板外轮廓生成的 HTML 里元件会散落在空白画布上观感很差。常见做法是在 AD 的Keep-Out Layer或Mechanical Layer上画好板框导出一份 DXF再在脚本里读出来换算成 HTML 的板框路径。很多快速 BOM 生成工具的 zip 里已经写好了这步转换但前提是板框层命名稳定换板子时记得检查。2.1.1 导出文件长什么样坐标文件打开后大概是这样的结构Designator Footprint Mid X Mid Y Ref X Ref Y Pad X Pad Y Layer Rotation Comment R1 0603 1.2345 2.3456 1.2345 2.3456 1.2345 2.3456 Top 90 10k C1 0402 3.4567 4.5678 3.4567 4.5678 3.4567 4.5678 Bottom 270 100nFBOM 文件则是一张行数很多的表一个位号一行同一物料在 AD 里可能拆成多行。标准的 InteractiveHtmlBom 流程要求 BOM 文件里至少有一列能唯一标识元件通常是位号列。按 Tab 分隔时行内不能有多余空格否则解析器容易错位。2.2 脚本怎么把坐标、位号和封装拼起来拿到上面两个文件后核心逻辑就一句话以位号为键把 BOM 的物料信息合并到坐标文件的每一行里。但这句话落地时有两个细节容易翻车。第一个细节是位号一对多。AD 的 BOM 里元件按位号展开但一个位号在坐标文件里只出现一行。如果直接按行合并最后生成的 HTML 里元件数量对不上。正确做法是先用位号聚合 BOM 行再按坐标文件的顺序输出。第二个细节是顶层和底层方向。AD 的 Pick and Place 文件里底层元件的坐标已经做了镜像换算坐标值是成品板上从正面投影看到的位置直接填入 HTML 即可不要再额外做镜像。如果脚本里自己又乘了一次 -1元件会全部翻到板框外面去。import csv from collections import defaultdict def load_bom(path): bom defaultdict(list) with open(path, encodingutf-8-sig, newline) as f: reader csv.DictReader(f, delimiter\t) for row in reader: des row[Designator].strip() bom[des].append({ Value: row.get(Comment, ), Footprint: row.get(Footprint, ), Quantity: row.get(Quantity, 1), }) return bom def merge_placement(pl_file, bom, out_file): with open(pl_file, encodingutf-8-sig, newline) as f, \ open(out_file, w, encodingutf-8, newline) as g: reader csv.DictReader(f, delimiter\t) writer csv.DictWriter(g, fieldnamesreader.fieldnames [Value, Qty]) writer.writeheader() for row in reader: rows bom.get(row[Designator].strip(), []) if rows: row[Value] rows[0][Value] row[Qty] len(rows) writer.writerow(row) merge_placement(pick_and_place.txt, bom.tsv, merged.txt)这段代码先用encodingutf-8-sig读文件是为了滤掉 Excel 或 AD 在 CSV 头部留下的 BOM 字节序标记不加这个参数时第一列的列名会变成\ufeffDesignator后面按列名取值全部取空。后面合并输出时用集合去重了同一个位号的多行 BOM 数据Qty列反映的是这个位号实际占几个位置。如果你用的 AD 版本导出的坐标文件列名不是Designator而是RefDes改一下DictReader取值即可其余逻辑不用动。3. AD 快速 BOM 生成工具本地跑通最小命令与关键参数3.1 先说最小可用的调用方式如果你拿到的 zip 里只是脚本和模板没有自带可执行文件那就需要自己准备 Python 环境。先确认python --version是 3.8 以上然后安装渲染依赖。常见做法是用 pip 安装interactivehtmlbom这个包它会自带命令行入口。python -m pip install interactivehtmlbom python -m interactivehtmlbom \ --layout merged.txt \ --bom bom.tsv \ --layer-view FB \ --dark-mode \ --output board_bom.html--layout传入上一步合并后的坐标文件--bom传入原始的 BOM 文件。这里要强调一个容易误解的点--bom参数不是必须的如果你只传--layout生成的 HTML 里只有元件位置图而没有任何物料信息。对于只做位置确认的场景这够用但既然目标是快速 BOM 生成工具BOM 文件必须传。--layer-view FB表示同时显示顶层和底层后续在 HTML 界面里可以手动切换。--dark-mode只是改变底色不影响坐标精度喜欢浅色背景的删掉即可。--output指定输出 HTML 的路径默认是ibom.html。3.1.1 输出失败时先看什么命令行跑完没有任何报错但生成的 HTML 里元件数量明显比板上少这种情况几乎都是合并那一步出了问题。回到上一节的merge_placement.py在两个csv.DictReader之间分别打印一列位号做对比。python -c import csv for p in [pick_and_place.txt, bom.tsv]: with open(p, encodingutf-8-sig) as f: r csv.DictReader(f, delimiter\t) print(p, len([x for x in r])) 位号数量对不上时去检查 AD 导出 BOM 时是否勾选了Export to Excel并设置成Tab Delimited。AD 默认导出为.xlsx选成这个格式后脚本读不了命令行会直接报KeyError: Designator看到这个错误先回来改 AD 的导出选项。3.2 决定 HTML 好不好用的参数表参数名可选值作用备注--layer-viewF/B/FB控制生成文件中包含顶层、底层还是双层默认FB单面 PCB 可以改成F减小文件体量--bom-viewgrouped/list左侧 BOM 面板显示方式grouped按物料合并list按位号逐条显示--show-fabrication无显示助印层和丝印层加了之后丝印字符会压住焊盘适合工艺检查--extra-fields列名列表把 BOM 里额外的列带进 HTML 元件详情和搜索例如供应商、封装名--group-fields列名列表多个列做分组时用到常见做法是Value,Footprint两个字段同时分组--no-compression无关闭 HTML 压缩生成速度慢但便于修改模板调试时用这张表是 InteractiveHtmlBom 在 AD 场景下最常用的几个。--extra-fields值得多说一句如果你希望 HTML 里点某个元件能直接看到“厂家”“订货号”这些字段忘了加这个参数左侧 BOM 列表里就永远只显示位号、数值、封装三列别等到产线发来反馈才想起来。3.3 多板或拼板时怎么同时出图拼板项目在 AD 里常把一个 PCB 文件复制多个原点拼在一起。直接导出再生成 HTML会出现整板元件连成一大片、板框分不清的情况。处理办法是在 AD 里为每个小板分别设置原点然后逐个导出 Pick and Place 文件。for file in board_a.txt board_b.txt; do python -m interactivehtmlbom \ --layout $file \ --bom ${file%.txt}.tsv \ --layer-view FB \ --output ${file%.txt}.html done这个循环每条命令的逻辑和单个文件完全一致区别只在于用 shell 变量把三个文件名串起来。批处理跑完后拼板的每块小板都有独立的 HTML评审时逐块打开比在一个文件里切换原点方便得多。4. 坐标原点、镜像和编码InteractiveHtmlBom 排错实战4.1 元件整体偏移 2 毫米但相对位置没错症状是生成的 HTML 里所有元件都落在板框外同一个方向移动一下 HTML 画布能看到元件之间距离完全正确就是整组位置不对。这说明坐标数据本身没问题是坐标原点和 AD 里的原点没对齐。AD 的坐标文件有一个不少工程师没注意的特性导出的坐标是相对于用户原点不是绝对原点。如果打开 PCB 文件后没有手动设置过原点用户原点和机械坐标系的原点可能差出好几个毫米。解决办法是在 AD 里用Edit - Origin - Set把原点重新设置到 PCB 板框左下角再重新导出坐标文件。设置完成后在 PCB 编辑器左下角状态栏确认坐标显示为X: 0mm Y: 0mm此时导出的文件才可以和 DXF 里板框坐标对齐。提示已经出过一版 HTML 给产线时临时改原点再重新导出会造成新旧版本坐标不一致。建议项目一开始就约定原点固定在板框左下角并写进评审检查清单。4.2 元件旋转角度对不上板子HTML 里元件位置正确但角度全部转错常见于底层元件。AD 坐标文件中 Rotation 列对顶层和底层用同一套规则底层元件在 Pick and Place 文件里已经换算成从顶层俯视的角度。如果你在脚本里做了angle 360 - angle之类的转换底层元件反而会被转成 90 度倍数加一个斜角。正确做法是角度直接透传不做任何换算。只有一种情况需要手动处理坐标文件来自某些第三方转换工具时底层角度会保持 AD 内部值这时候才需要补一个 180 度旋转。判断办法是找一个 0603 电阻对比它丝印的方向HTML 里显示的方向和 AD 里一致就不用改。row[Rotation] row[Rotation].strip() if float(row[Rotation]) 0: row[Rotation] str(float(row[Rotation]) 360)这段代码只做归一化把 AD 偶尔导出的负角度统一到 0 到 360 度之间。float(row[Rotation])支持带小数点的度数有些封装会旋转到 12.5 度这种非直角角度转换后依然保留精度。如果角度列出现了空字符串说明这一行可能是板框或钻孔标记误入坐标文件直接跳过不处理比强行补 0 更安全。4.3 中文注释变成乱码BOM 里器件值写中文生成的 HTML 里显示成乱码原因几乎都出在读文件那一步的编码上。AD 导出 CSV/TXT 文件在中文 Windows 上默认是 ANSI 编码即 GBK而 Python 默认用 UTF-8 读取自然乱码。处理方式有两种。第一种是在代码读取时指定 GBK如果你拿到的 zip 里脚本写的是 UTF-8则需要改动打开文件的open()函数。第二种更稳妥直接在 AD 导出 BOM 时把格式改成 CSV并在 AD 的偏好设置里把默认编码改成 UTF-8一劳永逸。def load_bom(path): for enc in (utf-8-sig, gbk, gb18030): try: with open(path, encodingenc, newline) as f: reader csv.DictReader(f, delimiter\t) rows [r for r in reader if any(r.values())] return rows except UnicodeDecodeError: continue这段代码的逻辑是一次尝试三种编码直到成功gb18030比gbk覆盖字符更全如果 BOM 里出现生僻字GBK 会解码失败GB18030 能兜住。any(r.values())是为了过滤掉行尾多余的空行因为 AD 导出的文件结尾经常有一个只有分隔符的空行不滤掉会在 HTML 中显示一个没有位号的幽灵元件。4.4 元件数量对但点击后不跳转HTML 里所有元件都在但点左侧 BOM 列表里的某一项时元件不高亮。这属于按钮和元件的关联 ID 对不上。InteractiveHtmlBom 的联动机制是给每个元件分配一个以位号为基础的 ID如果 BOM 数据里有两个完全相同的位号ID 会冲突点其中一个时浏览器不知道该高亮哪个。根治办法是在合并步骤为每个物理位置生成唯一 ID而不是直接用位号。常见做法是在脚本输出时给位号加一个自增序号例如R1_1、R1_2。同时把原始位号放到extra-fields里这样 BOM 界面仍能看到 R1内部索引不会重复。5. 让 HTML BOM 更顺手批处理生成与内容验证5.1 一个命令跑完整个项目一个稍大的混合信号板卡散热焊盘、去耦电容、连接器加起来轻轻松松上千个位置。逐个文件生成 HTML 的效率太低zip 工具里通常会有个批处理脚本没有就自己补一个。echo off set SCRIPT_DIR%~dp0 for %%f in (%SCRIPT_DIR%output\*.txt) do ( echo Processing %%f python -m interactivehtmlbom ^ --layout %%f ^ --bom %SCRIPT_DIR%output\%%~nf.tsv ^ --layer-view FB ^ --extra-fields Manufacturer,Supplier_PartNumber ^ --output %SCRIPT_DIR%html\%%~nf.html )这个批处理遍历output目录下所有坐标文件%%~nf取文件名不带后缀用来匹配同名 BOM 文件。%~dp0取脚本自身所在目录避免在别的盘符下运行时路径出错。执行前需要确认 BOM 文件名和坐标文件名完全一致否则匹配失败会生成一个没有物料信息的空 HTML。批处理场景下建议把--no-compression加上调试时输出速度快很多。等确认所有板卡的 HTML 内容无误后再重新跑一遍不带该参数的正式版。5.2 用代码做一次坐标还原验证生成 HTML 后花五分钟做一次自动化验证能避免把带问题的 BOM 发给产线。思路是直接解析生成的 HTML统计里面的元件数量再和 AD 里的标注数对比。import re html_text open(board_bom.html, encodingutf-8).read() ids set(re.findall(rid([^]?), html_text)) has_ref re.findall(rdata-ref([^]?), html_text) print(f元件 ID 数量: {len(ids)}) print(f带位号数量: {len(has_ref)}) print(位号重复:, len(has_ref) ! len(set(has_ref)))这个验证段落里id是元件唯一标识style="width:16px;margin-left:4px;vertical-align:text-bottom;cursor:text;" />