如何在对接Power BI的Python API中获取Xero带部门(跟踪类别)且按月拆分的利润表(P&L)数据?
如何在对接Power BI的Python API中获取Xero带部门(跟踪类别)且按月拆分的利润表(P&L)数据?
我之前在做Xero到Power BI的数仓同步时,完完全全碰到过和你一模一样的问题!当时要么只能拿到分月但没部门的P&L,要么是按部门汇总但看不到月度明细,折腾了好几天才摸透Xero API的门道,给你分享下我最终用的解决办法:
核心问题根源
首先得说清楚:Xero的ProfitAndLoss报表API默认不会同时返回时间维度拆分和跟踪类别维度的交叉数据,你之前的两种情况其实是API参数没搭配对——单独指定periods会返回分周期数据但忽略跟踪维度,单独指定跟踪类别过滤会返回汇总数据但不拆分周期。
具体解决步骤(附Python代码示例)
我用的是官方的xero-python SDK(比直接调requests省很多事),步骤如下:
正确构造P&L报表的API请求参数
你需要在请求里同时指定三个关键参数,把时间拆分和跟踪维度的开关都打开:periods:设置为你需要的周期数(比如你要11个月度周期就填11)period_type:明确设为"MONTH",确保按月份拆分show_tracking:必须设为True,强制API返回跟踪类别数据- 可选:用
tracking_category_id指定你要拉取的部门对应的跟踪类别ID(如果有多个跟踪类别,也可以用tracking_option_id锁定具体部门)
代码示例:
from xero_python.api_client import ApiClient, Configuration from xero_python.api.accounting_api import AccountingApi from xero_python.oauth2 import OAuth2Token import pandas as pd # 初始化Xero客户端(这里假设你已经完成OAuth2授权,拿到了有效token) configuration = Configuration( debug=False, oauth2_token=OAuth2Token( access_token="YOUR_ACCESS_TOKEN", token_type="Bearer", expires_in=3600 ) ) api_client = ApiClient(configuration) accounting_api = AccountingApi(api_client) # 构造P&L报表请求参数 report_params = { "date_from": "2023-01-01", "date_to": "2023-11-30", "periods": 11, "period_type": "MONTH", "show_tracking": True, "tracking_category_id": "YOUR_DEPT_TRACKING_ID" # 替换成你的部门跟踪类别ID } # 调用API获取带双维度的P&L报表 pnl_report = accounting_api.get_report_profit_and_loss(**report_params)解析嵌套的交叉维度数据
Xero返回的报表是层级嵌套结构,会先按部门分组,再在每个组下展示月度明细。你需要把这种嵌套结构扁平化成Power BI能直接识别的行数据:# 初始化存储最终数据的列表 flattened_pnl = [] # 遍历报表行,跳过标题/汇总行 for row in pnl_report.rows: if row.row_type not in ["SECTION", "ROW"]: continue # 提取部门名称(从跟踪类别单元格中匹配) dept_name = next( (cell.value for cell in row.cells if cell.tracking_category_name == "部门"), "未分配部门" ) # 提取会计科目名称 account_name = row.cells[0].value # 遍历每个月度的金额单元格 for idx, cell in enumerate(row.cells): if cell.type != "NUMBER" or not cell.value: continue # 匹配对应月度的起始日期 period_date = pnl_report.report_periods[idx].start_date # 转换金额为数值类型 amount = float(cell.value) flattened_pnl.append({ "月度日期": period_date, "部门名称": dept_name, "会计科目": account_name, "金额": amount }) # 转换成Power BI兼容的DataFrame pnl_df = pd.DataFrame(flattened_pnl) # 可选:调整数据类型适配Power BI模型 pnl_df["月度日期"] = pd.to_datetime(pnl_df["月度日期"])对接Power BI的收尾
直接输出整理好的pnl_df就行——Power BI在执行Python脚本时,会自动把这个DataFrame识别为数据源。如果需要更贴合Power BI的建模需求,还可以给列重命名、设置格式规则。
踩过的坑和注意事项
- 权限检查:确保你的Xero应用已经申请了
AccountingReports和Tracking相关权限,否则API会返回权限不足的错误 - 跟踪类别ID获取:可以先调用
accounting_api.get_tracking_categories()拉取所有跟踪类别,动态匹配“部门”对应的ID,别硬编码(避免后续ID变更导致脚本失效) - 空值处理:有些部门在特定月份可能无数据,Xero会返回空值,记得转成0.0或标记为“无数据”,防止Power BI加载报错
- 周期数匹配:
periods参数要和date_from/date_to的时间范围对应,比如要11个月度周期,日期范围就设为11个月,否则API会自动调整周期数
内容来源于stack exchange
相关产品推荐
相关产品推荐

