#!/usr/bin/env python3 """给三个统计 Sheet 添加颜色样式 - 使用 PUT /style appendStyle""" import json, requests, os CRED_DIR = "/root/.openclaw/credentials/xiaoxi" SPREADSHEET_TOKEN = "NoZqsFi47hIOHEt9j8WcfRtbnug" def get_token(): with open(os.path.join(CRED_DIR, "config.json")) as f: cfg = json.load(f) resp = requests.post("https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal", json={"app_id": cfg["apps"][0]["appId"], "app_secret": cfg["apps"][0]["appSecret"]}, timeout=15) return resp.json()["tenant_access_token"] def apply_style(token, sheet_id, col_start, row_start, col_end, row_end, style): rng = f"{sheet_id}!{col_start}{row_start}:{col_end}{row_end}" resp = requests.put( f"https://open.feishu.cn/open-apis/sheets/v2/spreadsheets/{SPREADSHEET_TOKEN}/style", headers={"Authorization": f"Bearer {token}", "Content-Type": "application/json"}, json={"appendStyle": {"range": rng, "style": style}}, timeout=30) code = resp.json().get("code") if code != 0: print(f" ❌ {rng}: {resp.json()}") return code == 0 # 颜色 BLUE = "#4472C4" WHITE = "#FFFFFF" LIGHT_BLUE = "#D6E4F0" PURE_WHITE = "#FFFFFF" YELLOW = "#FFF2CC" YELLOW2 = "#FFF9E6" GREEN = "#E2EFDA" BORDER = "#B4C6E7" def header_bg(): return {"backcolor": BLUE, "fontColor": WHITE, "bold": True, "fontSize": 10} def row_bg(odd): return {"backcolor": LIGHT_BLUE if odd else PURE_WHITE, "fontSize": 10} def yellow_bg(odd): return {"backcolor": YELLOW if odd else YELLOW2, "fontSize": 10} def green_bg(): return {"backcolor": GREEN, "fontSize": 10, "bold": True} def main(): token = get_token() # ===== 1. 销转总览 (2F2IcE) ===== print("=== 📊 销转总览 ===") sid = "2F2IcE" apply_style(token, sid, "A", 1, "L", 1, header_bg()) for r in range(2, 6): odd = (r % 2 == 0) apply_style(token, sid, "A", r, "C", r, row_bg(odd)) apply_style(token, sid, "D", r, "D", r, yellow_bg(odd)) apply_style(token, sid, "E", r, "G", r, row_bg(odd)) apply_style(token, sid, "H", r, "H", r, row_bg(odd)) apply_style(token, sid, "I", r, "I", r, row_bg(odd)) apply_style(token, sid, "J", r, "L", r, yellow_bg(odd)) print(" ✅ 完成") # ===== 2. 落单渠道分布 (2PlDl6) ===== print("=== 📊 落单渠道分布 ===") sid = "2PlDl6" apply_style(token, sid, "A", 1, "I", 1, header_bg()) for r in range(2, 7): odd = (r % 2 == 0) apply_style(token, sid, "A", r, "I", r, row_bg(odd)) # 合计行 apply_style(token, sid, "A", 7, "I", 7, green_bg()) print(" ✅ 完成") # ===== 3. 过程数据 (2PNMIM) ===== print("=== 📊 过程数据 ===") sid = "2PNMIM" apply_style(token, sid, "A", 1, "AA", 1, header_bg()) for r in range(2, 12): odd = (r % 2 == 0) apply_style(token, sid, "A", r, "B", r, row_bg(odd)) # 销售/月份 apply_style(token, sid, "C", r, "C", r, row_bg(odd)) # 线索总数 apply_style(token, sid, "D", r, "D", r, row_bg(odd)) # 手机号数 apply_style(token, sid, "E", r, "E", r, yellow_bg(odd)) # 手机号率 apply_style(token, sid, "F", r, "F", r, row_bg(odd)) # 注册数 apply_style(token, sid, "G", r, "G", r, yellow_bg(odd)) # 注册率 apply_style(token, sid, "H", r, "H", r, row_bg(odd)) # 首课人数 apply_style(token, sid, "I", r, "I", r, yellow_bg(odd)) # 首课率 apply_style(token, sid, "J", r, "J", r, yellow_bg(odd)) # 一节课转化率 apply_style(token, sid, "K", r, "K", r, row_bg(odd)) # 二次课人数 apply_style(token, sid, "L", r, "L", r, yellow_bg(odd)) # 二次课率 apply_style(token, sid, "M", r, "M", r, yellow_bg(odd)) # 二节课转化率 apply_style(token, sid, "N", r, "N", r, row_bg(odd)) # 三次课人数 apply_style(token, sid, "O", r, "O", r, yellow_bg(odd)) # 三次课率 apply_style(token, sid, "P", r, "P", r, yellow_bg(odd)) # 三节课转化率 apply_style(token, sid, "Q", r, "Q", r, row_bg(odd)) # 四次课人数 apply_style(token, sid, "R", r, "R", r, yellow_bg(odd)) # 四次课率 apply_style(token, sid, "S", r, "S", r, yellow_bg(odd)) # 四节课转化率 apply_style(token, sid, "T", r, "T", r, row_bg(odd)) # 五次课人数 apply_style(token, sid, "U", r, "U", r, yellow_bg(odd)) # 五次课率 apply_style(token, sid, "V", r, "V", r, yellow_bg(odd)) # 五节课转化率 apply_style(token, sid, "W", r, "W", r, row_bg(odd)) # 订单数 apply_style(token, sid, "X", r, "X", r, yellow_bg(odd)) # 转化率 apply_style(token, sid, "Y", r, "AA", r, row_bg(odd)) # GMV/退款/GSV print(" ✅ 完成") print("\n✅ 全部样式设置完成") if __name__ == "__main__": main()