资讯动态

用 Python 对比两份装修报价单,自动标出价格差异项(附完整代码)

发布时间:2026/10/10 19:56:56 来源:尧图企业网站定制
装修报价单动辄几十上百行施工方版本和自留版本一对比最容易在「单价」「工程量」「合价」上动手脚。手动逐行核对又慢又容易漏。本文用openpyxl写一个本地脚本按「项目名称 规格」匹配两份清单自动算出单价差、合价差并把异常行高亮导出成新表全程零联网、零依赖服务端。一、思路两份清单结构通常一致序号 / 项目编码 / 项目名称 / 项目特征 / 单位 / 工程量 / 综合单价 / 合价 … 我们拿「项目名称 单位」做去重键项目特征可能表述不一致先用名称兜底逐行对齐对比单价和合价。二、代码importopenpyxlfromopenpyxl.stylesimportFont,PatternFill KEY_COLS{name:3,unit:5,price:7,total:8}# 列号按需调整REDPatternFill(solid,fgColorFFC7CE)defload(path):wbopenpyxl.load_workbook(path,data_onlyTrue)wswb.active rows{}forrinrange(2,ws.max_row1):name(ws.cell(r,KEY_COLS[name]).valueor).strip()unit(ws.cell(r,KEY_COLS[unit]).valueor).strip()ifnotname:continuekey(name,unit)pricews.cell(r,KEY_COLS[price]).valueor0totalws.cell(r,KEY_COLS[total]).valueor0rows[key](r,float(price),float(total))returnwb,ws,rowsdefdiff(a_path,b_path,out差异报告.xlsx):wb_a,ws_a,raload(a_path)wb_b,ws_b,rbload(b_path)out_wbopenpyxl.Workbook()wsout_wb.active ws.append([项目名称,单位,A单价,B单价,单价差,A合价,B合价,合价差])all_keyslist(dict.fromkeys(list(ra)list(rb)))forkinall_keys:ara.get(k,(None,0,0))brb.get(k,(None,0,0))dpround(b[1]-a[1],2)dtround(b[2]-a[2],2)ifdpordt:# 只留有差异的行ws.append([k[0],k[1],a[1],b[1],dp,a[2],b[2],dt])ifabs(dp)0orabs(dt)0:forcinrange(1,9):ws.cell(ws.max_row,c).fillRED out_wb.save(out)print(f已导出差异报告:{out}共{ws.max_row-1}行)if__name____main__:diff(报价单_施工方.xlsx,报价单_自留.xlsx)三、几个实战坑合价可能是公式用data_onlyTrue读缓存值若文件从没在 Excel 里打开过data_only会拿到None先手动打开保存一次。名称不完全一致施工方常把「地砖铺贴 800*800」写成「地砖 800×800」建议先做一层归一化去空格、统一x/×、*再比对否则匹配不到。工程量变动要单独标单价没变但工程量被调高合价照样涨。脚本里dt合价差就是抓这种「量价齐动」的。精度单价保留 2 位避免浮点误差把 0.00 判成差异可用abs(dp) 0.005做阈值过滤。四、延伸把报告再喂给一个「差异分级」函数单价差10% 标红、5%~10% 标黄就能一眼看出哪些是「真坑」、哪些是合理波动。整套逻辑也能套到工程量清单、采购单的版本对比上核心是同一套「键匹配 字段 diff 高亮导出」。maixuzi.cn 的在线报价系统也是基于类似的逐项核对思路做的有兴趣可以去 resources 页看看。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑