news 2026/10/9 15:42:40

开源BOM管理软件:用集中式数据库替代Excel物料清单

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
开源BOM管理软件:用集中式数据库替代Excel物料清单

简介:这套开源物料清单管理工具是一份完整的C#桌面应用源码,面向电子制造企业的研发与采购人员,解决多用户协同维护元器件清单、跟踪版本变更等管理难题。得益于与Ciiva电子元件搜索接口的深度集成,系统能够在一个集中式数据库中统一管理元件库、物料清单及相关数据源,适合希望二次开发或深入学习API集成与WinForms项目架构的中高级开发者。压缩包共50个文件,主体为37个C#源程序,涵盖API调用封装、数据对象定义、主窗体交互界面等模块;另附5个动态链接库以及项目工程、配置文件,用于支撑编译运行;资源整体大小约315KB,结构清晰小巧。目前已有838人学习,下载后可直接查看请求与应答模型、库存价格查询等具体实现,也可参照其界面与逻辑分层方式,对理解电子元器件数据交互和物料清单管理流程具有实用参考价值。

1. BOM 管理软件:把 Excel 物料清单收进集中式数据库的开源方案

在产线上干了几年,你会发现最要命的不是缺料,而是没人能说清某台设备的 BOM 到底哪个版本是对的。Excel 表在每个人电脑里各存一份,改完不通知,通知了不更新,最终装配时只能用“以现场为准”。这个开源软件就是为解决这个问题来的:它把散在 Excel 里的物料清单统一收进集中式数据库,支持批量导入、版本对比、多级 BOM 展开和角色权限控制。适合电子工程师、工艺工程师和 PMC 去复现:几千行的 BOM 也能在几分钟内收进库里,之后每次改动都有迹可循。

2. 为什么选集中式数据库:Excel 管 BOM 的四宗罪与数据模型设计

2.1 Excel 管 BOM 的四个典型痛点

先说结论:用 Excel 管 BOM 并不是不行,而是“单机可用,协同必炸”。四个痛点我挨个说。

第一个是版本。一个产品 BOM 从样机到量产至少要改七八轮,每轮改完“另存为 v2_final_终版”之类的文件名,没过几天就会出现“到底哪个最终版”的口角。等到板上芯片电压标错,溯源时只能打开十几份 Excel 逐个比较,真正定位到变更行要花掉大半天,而且没人愿意给这种追溯过程签字。

第二个是权限。业务员、采购、工艺都有改表需求,但 Excel 没有细粒度权限。要么每个人都能动文件,要么锁死文件让协作效率归零。用共享文件夹,也只在“文件共享”层面做覆盖,不能做到“某个人只能改 BOM 里的替代料,碰不了主料用量”。这类需求一提出来,Excel 基本就败了。

第三个是数据一致性。同一个物料,在 BOM 里写“电阻 10kΩ 0603”,在另一份表里写“10K 0603”,系统不认为是同一个东西。哪怕人眼能认出是同一颗料,软件做不了自动合并。更麻烦的是单位混用,一根导线写成 0.5 m 或 500 mm,对 Excel 来说完全是两个字符串。数据一多,漏配错配自然就来了。

第四个是追溯。批次号、变更原因、生效日期,Excel 列一多就没人填。一旦产线问“这批料是什么时候换的”,只能翻聊天记录或者猜。电子行业追责时,最怕的就是“没有记录”。这四个痛点,本质上都是“文件操作”而不是“数据操作”,这也是我把注意力转向开源 BOM 管理软件的原因。

2.2 选集中式数据库的理由:从“文件共享”到“数据主权”

集中式数据库和 Excel 最大的区别,是“数据先入表,权限后分配”。常见方案是 SQLite 起步,数据量大了切 PostgreSQL。之所以选 SQLite 先跑,是因为它零配置、单文件备份、对几十万行的 BOM 足够用;到了多用户并发写,再迁到 PostgreSQL,表结构不用大改。

还有一点,集中式数据库天然支持事务。导入一份 BOM 时如果第 100 行出错,事务回滚可以恢复到导入前状态,这在 Excel 里是做不到的。Excel 的后悔药只有复制备份文件,备份多了自己都分不清哪个是最新的。而事务机制可以保证导入过程要么全部成功,要么全部失败,不会出现“改了一半,剩下半份没法要”的局面。

从成本上看,开源软件比商业 PLM 轻得多。一个几百种物料的小团队,上重型 PLM 的采购和实施成本能顶小半年工资,而这个开源项目用一台普通办公机跑 SQLite 服务端完全够。而且开源的好处是你能看到数据是怎么存的,出了诡异问题能直接查库,不会像商业软件那样是个黑匣子。如果你是从 CAD 或 EDA 工具转过来的,比如 KiCad 生成的 BOM 文件,或者 SAP 物料分类视图导出的表格,导入这套系统后,Excel 就只承担“输入/输出”的角色,中间过程的加工、清洗、对比都在数据库里完成。

2.3 数据模型设计:核心表与字段定义

这个开源项目的核心模型其实不复杂,就是“料号-层级-数量-变更”四件事。我拆开看,主表是 boms、bom_items、materials、versions 四张。boms 表存 BOM 头信息,比如产品型号、描述、当前生效版本;bom_items 存明细,包含父项和子项的料号、用量、位号、替代料;materials 存物料主数据,统一单位、物料描述、分类;versions 存每次变更的版本号、变更人、生效日期。

下面这段建表 SQL 是我在这个场景下整理的参考结构,不是项目原样,但足够复现。对照这个结构,你可以理解为什么它能支撑版本对比和多级展开,而不是把 Excel 原样塞进去:

CREATE TABLE materials ( id INTEGER PRIMARY KEY AUTOINCREMENT, part_number TEXT NOT NULL UNIQUE, description TEXT, unit TEXT DEFAULT 'pcs', category TEXT ); CREATE TABLE boms ( id INTEGER PRIMARY KEY AUTOINCREMENT, product_number TEXT NOT NULL, name TEXT NOT NULL, current_version TEXT, created_at TEXT DEFAULT (datetime('now')) ); CREATE TABLE bom_items ( id INTEGER PRIMARY KEY AUTOINCREMENT, bom_id INTEGER NOT NULL REFERENCES boms(id), parent_part TEXT, child_part TEXT NOT NULL, quantity REAL NOT NULL DEFAULT 1, position TEXT DEFAULT '', alternate_part TEXT, version TEXT, UNIQUE(bom_id, parent_part, child_part, position) ); CREATE TABLE versions ( id INTEGER PRIMARY KEY AUTOINCREMENT, bom_id INTEGER NOT NULL REFERENCES boms(id), version TEXT NOT NULL, file_name TEXT, change_note TEXT, updated_by TEXT, created_at TEXT DEFAULT (datetime('now')) );

字段含义里值得注意的有几处:part_number 统一用大写字母加数字,方便做 join 匹配,导入前必须做大小写归一化;quantity 用 REAL 而不是 INTEGER,是因为有些 BOM 用量会写 0.1 或 0.05,比如胶水或锡膏按克算;position 存位号如 R1、R2,一个 child_part 可能有多个位号,所以 UNIQUE 约束里带上 position,避免同一行被覆盖。alternate_part 用来存替代料,多个替代料可以用逗号分隔,但实际项目中更好的做法是单独建一张替代料关系表,我为了演示简化为一个字段。versions 表专门记录版本变化,每次导入文件时插入一行,这样随时能查“当前版本从哪来”。

这就是集中式数据库的核心好处:Excel 文件只是输入,数据库里永远只有一份经过清洗的“真源”。后续的展开、对比、权限控制,全都在这一套表结构上做文章。

3. 快速部署与首轮导入:把第一份 Excel BOM 吃进数据库

3.1 环境准备与启动流程

这个项目用 Python 写,依赖不多。我一般会先新建虚拟环境,再装依赖。下载解压后项目根部有 requirements.txt,最核心的依赖是 Flask(提供 Web 界面)、openpyxl(解析 Excel)、sqlite3(内置)。启动命令如下:

cd bom-manager python -m venv venv source venv/bin/activate # Windows 下用 venv\Scripts\activate pip install -r requirements.txt python run.py --port 8000

参数说明:run.py 是入口脚本,--port 指定端口,默认 8000,如果被占用就换 8001,然后前端访问 http://localhost:8001。首次启动会在项目目录下自动生成 bom.db 文件,这就是集中式数据库本体。如果你不想用浏览器,也可以直接用 Python 调它的 API 接口,但新手从 Web 界面开始更容易。

启动之后,页面会有一个“创建 BOM”的按钮。第一次用的时候,我发现它不会自动建演示数据,需要自己上传 Excel。这一步没什么坑,但前提是 Excel 要按模板整理。如果你希望先试试水,可以用项目自带的 sample 目录,里面通常有一份 demo_bom.xlsx,直接导入它就能看到效果。

3.2 Excel BOM 模板要求与首轮导入

不是所有 Excel 都能直接导入。这个项目认两张表:第一张叫“头信息”,第二张叫“BOM明细”。头信息里至少要有产品型号和 BOM 版本;明细里关键列是母件料号、子件料号、用量、位号、备注。列名可以自定义,但导入时要映射,所以界面里会有下拉框让你选择“哪一列是子件料号、哪一列是用量”。

我准备一个最小示例:

from openpyxl import Workbook wb = Workbook() ws = wb.active ws.title = "BOM明细" ws.append(["母件料号", "子件料号", "用量", "位号", "备注"]) ws.append(["PCB-V1.0", "R010", "2", "R1,R2", "1% 10K"]) ws.append(["PCB-V1.0", "C020", "4", "C1,C2,C3,C4", "100nF 0603"]) wb.save("demo_bom.xlsx")

这段只是造一份测试文件,真实导入时你手上肯定有从 CAD 或 EDA 工具导出的表。像 KiCad 生成的 BOM 文件,或者 SAP 物料视图导出的表格,都可以先整理成两行表头再导入。导入页面里,把 Excel 文件拖进去,勾选对应列名映射,点击“导入”即可。

这里有两个导入模式需要特别注意:一个是“新增版本”,一个是“替换现有物料”。我第一次使用时直接点了“覆盖导入”,结果把整个 BOM 的旧版本全部冲掉。后来才意识到,正确做法是每次上传都作为新版本追加到 versions 表,只在审批通过后切换 current_version。这个设计保证任何误操作都有后悔药。所以第一轮导入时,建议选“新增版本”,后续确认无误再手动切换。

3.3 用 SQL 查询验证导入结果

导入完别急着信界面,先用 SQL 验证数据条数和关键字段。我用 sqlite3 命令看一眼:

sqlite3 bom.db SELECT COUNT(*) FROM bom_items; SELECT product_number, name FROM boms; SELECT child_part, quantity, position FROM bom_items WHERE bom_id = 1;

逻辑说明:第一条是看明细总数,如果 Excel 有 100 行就应该接近 100 行;第二条查所有 BOM 头;第三条看一个 BOM 的具体用量。如果发现 count 比 Excel 行数少,说明导入器做了去重或跳过了空行,这是常见行为,不是错误。此时应该打开导入日志,确认哪些行被跳过,而不是直接开始改数据。我一般会把这个验证过程做成一个“导入后必查三步”的清单:

-- 检查是否有空料号的行 SELECT COUNT(*) FROM bom_items WHERE child_part IS NULL OR child_part = ''; -- 检查用量是否正常 SELECT child_part, quantity FROM bom_items WHERE quantity <= 0; -- 检查版本号是否全部填上 SELECT COUNT(*) FROM bom_items WHERE version IS NULL OR version = '';

这三个查询分别对应空料号、零数量、版本缺失三类问题。空料号说明 Excel 里有多余空行;数量为 0 或负数是 BOM 常见的脏数据;版本为空则会导致后面的版本对比失效。这三步走完,数据才算真正进了库。

如果导入后想改数据,最好不要直接在界面上逐行改,而是用 SQL 批量更新。比如把某个位号字段统一格式化,或者把某个料号的描述补全,SQL 都更高效。但注意改之前先备份 bom.db 文件,毕竟这是你辛辛苦苦建起来的真源,一条 UPDATE 语句写错,后果比 Excel 误删严重。

4. 日常使用与进阶配置:物料归并、版本对比与权限管理

4.1 多级 BOM 展开与物料归并逻辑

单层 BOM 好理解,真正麻烦的是多级 BOM:一个装配件里包含子装配,子装配又包含零件。这个软件用递归展开实现多级 BOM 的“拍平”。拍平后每个底层物料只出现一次,但它的数量会乘上每一级的用量。

例如某套件 A 需要 2 个模块 B,每个 B 需要 4 个电阻 R10。拍平后 R10 的总量是 2×4=8。这是常见做法,叫“BOM 展开”或“多级展开”。项目里我一般会写一段递归 SQL 或 Python 脚本完成这件事。如果直接用 SQL,可以用公共表表达式递归,SQLite 3.8.3 以上支持 WITH RECURSIVE。参考写法:

WITH RECURSIVE bom_tree AS ( SELECT bom_id, child_part, quantity, 1 AS lvl FROM bom_items WHERE parent_part = 'A' UNION ALL SELECT b.bom_id, b.child_part, t.quantity * b.quantity, t.lvl + 1 FROM bom_items b JOIN bom_tree t ON b.parent_part = t.child_part ) SELECT child_part, SUM(quantity) AS total_qty FROM bom_tree GROUP BY child_part;

这段逻辑是:第一层找直接子件,第二层向上递归,直到没有子装配为止,最后汇总每个底层料号的数量。注意递归 CTE 的终止条件,如果 BOM 里有循环引用,比如 A 包含 B、B 又包含 A,这条 SQL 会死循环。我在一个模拟项目里碰到过一次,后来加了 lvl <= 10 的深度限制,避免数据库被拖死。深度限制可以在 SQL 里加 WHERE t.lvl < 10。

物料归并是展开后的一个必然动作。同一个底料在多个子装配里都可能出现,归并时除了数量求和,还要把位号用逗号拼到一起。位号太多时 Excel 单格有长度限制,可以只保留前 200 个字符,剩下的放到备注里。这个逻辑在 Python 里做比纯 SQL 更灵活,我一般先把展开结果取出来,再按料号 groupby,用','.join(position_list)拼接位号。实测几千行的 BOM 展开后,Python 端处理只需要一两秒,不会成为瓶颈。

4.2 版本对比与变更通知

版本对比是这个软件的核心亮点。两版 BOM 对比时,项目按“子件料号+位号”作为键,找出新增、删除、数量变化三类差异,并以表格形式展示。

具体实现上,是给 versions 表加一个 snapshot 字段,每次导入时保存整份明细的 JSON 快照。对比时用 Python 读两个快照,做一个字典差集。代码参考:

import json def diff_bom(old_snapshot, new_snapshot): old = {item['key']: item['qty'] for item in old_snapshot} new = {item['key']: item['qty'] for item in new_snapshot} added = new.keys() - old.keys() removed = old.keys() - new.keys() changed = {k for k in old.keys() & new.keys() if old[k] != new[k]} return {'added': list(added), 'removed': list(removed), 'changed': list(changed)}

diff_bom 函数返回三类差异列表。逻辑:先把明细转成以“料号-位号”为 key 的字典,然后做集合差运算。这样就算有几百行明细,对比也在毫秒级。参数说明:old_snapshot 和 new_snapshot 都可以直接从 versions 表里按版本号读出来,格式是[{"key": "R010|R1,R2", "qty": 2}, ...]。

变更通知则是靠定时任务,每小时扫一次 versions 表,发现新版本就推送消息到内部群;如果要求不高的团队,直接在导入时勾选“邮件通知”即可。定时任务在 Linux 上常用 cron,每小时的命令可以写成0 * * * * python /path/to/check_update.py。Windows 上则可以用计划任务触发。真正值得注意的坑是:对比前必须确保两版快照的 key 生成规则一致,否则会出现“全删全增”的假差异。比如旧版用part_number做 key,新版用part_number+position,对比结果就会乱套。

4.3 用户角色与权限:谁可以改、谁只能看

开源版本默认没有很重的 RBAC,但一般会带一个简化的用户角色:admin、editor、viewer。admin 能创建用户、删除数据;editor 可以导入和编辑 BOM;viewer 只能查询。权限在 Web 层做拦截,后端接口会校验登录用户的角色字段。

在配置里,常见的做法是用 Flask-Login 加一个 require_role 装饰器。参考:

from functools import wraps from flask import session, abort def require_role(role): def wrapper(fn): @wraps(fn) def decorated(*args, **kwargs): if session.get('role') != role: abort(403) return fn(*args, **kwargs) return decorated return wrapper

这个装饰器挂在需要限制的路由函数上,比如@require_role('editor')。参数说明:session['role'] 在登录时写入,实际用的时候可以用flask_login.current_user.role代替,更安全。我之前只在前端隐藏编辑按钮、后端没做校验,结果有人绕过了界面直接调接口把 BOM 改了,从那以后所有类似项目都坚持后端校验。

如果你需要更细的权限,比如“采购只能看价格列,工艺只能看装配关系”,那就需要给 bom_items 表加单独的权限字段,或者按列做掩码。开源版一般不做这么细,但数据模型允许你扩展:在 materials 表加 price_visible、process_visible 等字段,前端根据角色渲染列。实现不复杂,难的是想清楚权限粒度,建议先从最小粒度开始,用不到的功能不要加,权限模型也是维护成本。

4.4 替代料与多供应商编码:真正贴近生产的用法

一个容易被忽略的点是替代料。很多 BOM 软件只管主料号,不管替代料,导致缺料时找不到可用替代方案。这个开源项目在 bom_items 里留了 alternate_part 字段,但实际使用时我会把它拆成一张 alt_parts 表,理由是一个物料可能有多个替代料,保存成逗号串很不好做查询。参考结构:

CREATE TABLE alt_parts ( id INTEGER PRIMARY KEY AUTOINCREMENT, bom_item_id INTEGER NOT NULL REFERENCES bom_items(id), alt_part TEXT NOT NULL, is_preferred INTEGER DEFAULT 0, UNIQUE(bom_item_id, alt_part) );

这样做的直接好处是,可以用一条 SQL 找到“哪些产品型号用了某颗主料,它又有哪些替代料”:

SELECT b.product_number, i.child_part, a.alt_part FROM bom_items i JOIN boms b ON i.bom_id = b.id LEFT JOIN alt_parts a ON i.id = a.bom_item_id WHERE i.child_part = 'R010';

多供应商编码也是同样的道理。同一个零件的不同供应商料号,可以挂在同一颗物料主数据下,在采购视图里展示。但注意,替代料不能随便进 BOM 计算,否则用量汇总会重复,建议替代料只做参考标记,不参与展开计算。这也是我踩过的一个坑,后续在避坑章节里会再说。

5. 避坑与常见问题排查:编码乱码、层级丢失、重复物料与性能瓶颈

5.1 Excel 中文列名导入后乱码

现象:导入后明细页显示“物料名称”变成乱码,但数字字段正常。

原因:Excel 文件编码是 GBK/GB2312,而项目默认按 UTF-8 解析。尤其是国内很多 EDA 工具导出的 Excel,看起来正常,实际上内部编码是 GBK,导入器用 UTF-8 读中文列名就乱了。

解决:导入前先把 Excel 另存为 UTF-8 编码的 CSV,或者用 openpyxl 读取时指定编码。如果是 CSV 导入,打开文件确认编码格式。若用 Pandas 读取,可以df = pd.read_csv('bom.csv', encoding='gbk')。如果已经乱码入库,用 UPDATE 语句按 id 把 description 字段重新赋值,别全表刷。还有一个土办法:在 Excel 里选中列,用公式=UNICODE()检查第一个字符的码位,能快速判断是哪类编码。

5.2 多级 BOM 层级关系丢失

现象:导入的 Excel 明明有缩进层级,导入后所有行都是平级,子装配件和零件混在一起。

原因:Excel 里的层级是视觉缩进,不是结构化字段。导入器只认“母件料号”和“子件料号”,不认空格。很多人喜欢用几个空格或 Tab 表示层级,导入器根本看不见。

解决:整理表格时保证每一行都正确填写母件料号,不能只在第一行写,后续行留空。建议用一个辅助列,用公式把上一行母件料号填充下来,再导入。比如新增一列父项,写=C5,然后下拉填充。导入前用脚检查母件料号列是否为空:

SELECT COUNT(*) FROM bom_items WHERE parent_part IS NULL OR parent_part = '';

如果检查结果不是 0,就先回 Excel 补全再导入。另外,我习惯把“父项”列放在子件料号左边,因为导入界面的列映射部分实现是按列索引匹配的,列位置错了全乱。

5.3 重复物料和单位不一致

现象:同一个电阻,在三个 BOM 里分别写“10K”“10kohm”“10KΩ”,展开后出现三行同料号不同描述。更麻烦的是单位不一致,一根导线写成 0.5 m 或 500 mm,导入系统后会被当成两种物料。

原因:物料主数据没有统一规范,Excel 里的描述是自由文本,软件无法智能识别“这是同一个料”。

解决:导入前先跑一遍“物料主数据清洗”,把描述去空格、统一大写、单位统一转成标准单位。可以在 materials 表加唯一索引,比如part_number + unit + description。具体清洗脚本可以用 Python:

def clean_part_no(s): return str(s).strip().upper().replace('Ω', 'ohm').replace('K', 'K') def clean_unit(s): mapping = {'个': 'pcs', 'pcs': 'pcs', '米': 'm', 'mm': 'mm'} return mapping.get(str(s).strip().split()[0], str(s).strip())

这段脚本在导入前对 part_number 和 unit 做标准化。逻辑很简单:去掉空格、统一大小写、把中文单位映射成英文。注意清洗的逻辑要放在导入函数的第一步,否则生成的 part_number 永远对不上。如果发现已有数据混乱,先跑一次UPDATE materials SET description = REPLACE(description, 'Ω', 'ohm')之类的语句,再考虑合并。

5.4 大批量导入时长时间无响应

现象:一次导入 2 万行的 BOM,界面转了 5 分钟没反应,最后报超时。

原因:导入逻辑逐行 INSERT,并且每条都做唯一性检查,数据库连接没有开事务,每插入一条都要 fsync 一次,慢是必然的。

解决:把导入改成批量提交。常见做法是每 500 行 INSERT 后 commit 一次,或者用 executemany 一次插入多行。同时给 bom_items 表建复合索引(bom_id, parent_part, child_part),查询才能快。参考批量插入写法:

import sqlite3 conn = sqlite3.connect('bom.db') cur = conn.cursor() rows = [(1, 'PCB-V1.0', 'R010', 2, 'R1,R2', '', 'v1'), (1, 'PCB-V1.0', 'C020', 4, 'C1,C2,C3,C4', '', 'v1')] cur.executemany("INSERT INTO bom_items (bom_id, parent_part, child_part, quantity, position, version) VALUES (?,?,?,?,?,?)", rows) conn.commit()

这里 executemany 的参数是元组列表,SQL 里的?占位符依次对应每条数据的字段。注意每条元素数量必须和 SQL 字段数一致,少了会直接报 OperationalError。另外实测中,打开PRAGMA journal_mode=WAL;也能减少锁竞争。落库之后记得跑一下ANALYZE,让查询计划走索引。

5.5 版本字段为空导致对比失败

现象:两版 BOM 对比时页面报错,对比结果是空的。

原因:明细行里的 version 字段没填。导入器把版本号从文件名或头信息取过来,如果取不到就置空。版本为空,版本对比功能就找不到基准,自然只能报错。

解决:导入前在 Excel 头信息里补全版本号;如果已经导入,用 UPDATE 按 bom_id 回填 current_version。再保险一点,导入流程里强制校验版本字段不为空,否则拒绝导入。回填语句参考:

UPDATE bom_items SET version = 'V1.0' WHERE bom_id = 1 AND (version IS NULL OR version = '');

执行前先 SELECT 确认影响范围,别把别的 BOM 一起刷了。正确做法是先把版本表里的版本号查出来,一条条核对,再执行 UPDATE。

6. 用导出脚本把数据库 BOM 变回 Excel:保住格式与公式的小技巧

很多公司产线还是认 Excel 表单。数据库管理好了,最后还得导回去给产线用。这个开源项目自带导出功能,但默认导出的样式比较朴素,表格边框、列宽都不会保留。我一般会写个小脚本做“格式恢复”。示例使用 openpyxl,把查到的 bom_items 明细写入工作表,并设置边框和自动筛选:

import sqlite3 from openpyxl import Workbook from openpyxl.styles import Border, Side from openpyxl.utils import get_column_letter conn = sqlite3.connect('bom.db') rows = conn.execute("SELECT parent_part, child_part, quantity, position FROM bom_items WHERE bom_id=1").fetchall() wb = Workbook() ws = wb.active ws.append(["母件料号", "子件料号", "用量", "位号"]) for row in rows: ws.append(row) thin = Border(left=Side(style='thin'), right=Side(style='thin'), top=Side(style='thin'), bottom=Side(style='thin')) for cell in ws[1]: cell.border = thin ws.auto_filter.ref = ws.dimensions wb.save("export_bom.xlsx")

逻辑说明:这段脚本先连本地 SQLite 库,把查询结果写入 Excel,然后统一加边框并开启自动筛选。参数说明:bom_id=1要替换成你的 BOM 主键;如果需要多级展开,就先把递归查询结果存成视图,再导出。列宽可以在导出前用ws.column_dimensions['A'].width = 20调整,避免中文列名显示不全。

我踩过最大的坑是忘了处理位号列里的换行符。某些 EDA 导出的 BOM 中,位号是逗号分隔的,导回 Excel 后被识别为公式的一部分或者自动变成科学计数法。解决办法是导出的单元格格式设置成文本,或者在写入前把位号里的逗号换成空格,比如position.replace(',', ' ')。从那以后我每次导完都强制检查一列位号列的长度和中文字段是否溢出,确认导出的 Excel 行数和数据库查询数一致才敢发给产线。希望帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/9 15:40:52

COSCon‘25女性开源论坛:从贡献者到社区领袖的成长路径

COSCon‘25 的女性开源论坛议程刚出&#xff0c;朋友圈就炸了一圈。我盯着那份议程看了半天&#xff0c;第一反应不是“又有大会要开了”&#xff0c;而是“这个论坛终于从‘喊口号’变成‘给路径’了”。做个背景交代&#xff1a;COSCon是中国开源年会&#xff0c;每年吸引国内…

作者头像 李华
网站建设 2026/10/9 15:40:14

Claude Code辅助测试:API测试与pytest自动化

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/9 15:39:28

长尾效应与肥尾效应:从商业策略到风险管理的双尾思维

1. 从一个反直觉的现象说起&#xff1a;为什么“小众”反而能撑起大盘很多人第一次听到“长尾效应”和“肥尾效应”这两个词&#xff0c;是在讨论商业模式或者投资风险的时候。但这两个概念其实离我们非常近&#xff0c;近到每天刷短视频、逛电商、看文章推荐&#xff0c;背后都…

作者头像 李华
网站建设 2026/10/9 15:39:19

Ghidra 11.0.2 落地指南:从JDK 21配置到自动化分析脚本

简介&#xff1a;Ghidra 11.0.2 是一款开源软件逆向工程框架&#xff0c;特别为 Linux 平台用户打包&#xff0c;适用于恶意代码分析、漏洞研究、协议逆向与 CTF 对抗等场景。该版本内置反汇编、反编译、绘图、脚本化等完整分析能力&#xff0c;支持多种处理器指令集和常见可执…

作者头像 李华
网站建设 2026/10/9 15:38:31

.NET Framework 3.5 x64 下 SQLite 互操作 DLL 部署指南

简介&#xff1a;本资源是专为.NET Framework 3.5 SP1环境设计的SQLite数据库官方二进制发行包&#xff0c;面向使用Visual Studio 2008开发64位Windows应用的中初级C#或VB.NET开发者&#xff0c;解决轻量级嵌入式数据库集成难题。包内共21个文件&#xff0c;涵盖4个核心DLL&am…

作者头像 李华