财务统计局数据

👤 Jelly 📦 v1.0.0 ⭐ 4.5 ⬇️ 287 下载
💼 行业专业 免费

📖 技能介绍


name: 统计局_企业财务状况表 description: | 根据数据登记表或月报文件数据,生成统计局企业财务状况表(F203表)。 推荐使用数据登记表方式(仅需2个文件),也支持原始4文件方式。 触发条件:用户提供数据登记表+模版,或月报xls文件+模版时,按此流程生成财务状况模板结果文件。 agent_created: true


统计局_企业财务状况表

触发条件

当金鱼说"生成财务状况表"、"财务状况模板"、"填财务状况",或者提供数据登记表/月报文件要求生成财务状况结果时,使用此技能。

必需输入

方式一(推荐):数据登记表

用户提供以下2个文件: 1. 财务状况数据登记表.xlsx(统一填写所有原始数据,一家或多家公司) 2. 财务状况模版.xlsx(模板)

方式二(备选):原始文件

用户提供以下4个文件: 1. 月报.xls(如 2026年5期月报_深圳卓正瑞祥管理咨询有限公司_人民币(元)_月度财务报表_2026061010160054.xls) 2. 财务状况模版.xlsx(模板) 3. 多账簿科目余额表数据引出.xlsx(取应付职工薪酬和应交增值税,需分别引出2211和2221.01科目) 4. 发薪人数累计平均数v2.xlsx(取平均用工人数)


数据登记表结构(方式一)

数据登记表包含3个数据sheet + 1个说明sheet,用户一次性填写所有数据。

Sheet 1: 资产负债表

  • 第4行:列头
  • 第5行起:数据行,每行一家公司
  • 所有金额单位为
列名 说明
A 公司名称 必须与其它sheet一致
B 固定资产原价 资产负债表-对外填报 期末数
C 应收账款 资产负债表-对外填报 期末数
D 资产总计 资产负债表-对外填报 期末数
E 负债合计 资产负债表-对外填报 期末数
F 所有者权益合计 资产负债表-对外填报 期末数(股东权益合计)

Sheet 2: 利润表

  • 第5行:列头
  • 第6行起:数据行,每行一家公司
  • 所有金额单位为
  • 资产减值损失和信用减值损失:填利润表原值,程序会自动取相反数
列名 说明
A 公司名称 必须与其它sheet一致
B 主营业务收入 利润表 本年累计金额
C 其他业务收入 利润表 本年累计金额
D 主营业务成本 利润表 本年累计金额
E 其他业务成本 利润表 本年累计金额
F 营业税金及附加 利润表 本年累计金额
G 销售费用 利润表 本年累计金额
H 管理费用 利润表 本年累计金额
I 研发费用 利润表 本年累计金额
J 财务费用 利润表 本年累计金额
K 资产减值损失 填原值,程序自动取反
L 信用减值损失 填原值,程序自动取反
M 公允价值变动收益 利润表 本年累计金额
N 资产处置收益 利润表 本年累计金额
O 投资收益 利润表 本年累计金额
P 其他收益 利润表 本年累计金额
Q 营业外收入 利润表 本年累计金额
R 营业外支出 利润表 本年累计金额
S 所得税费用 利润表 本年累计金额

Sheet 3: 科目余额及用工

  • 第5行:列头

    小葱技能7w4.net持续更新中。

  • 第6行起:数据行,每行一家公司
  • 应付职工薪酬和应交增值税单位为,平均用工人数单位为
列名 说明
A 公司名称 必须与其它sheet一致
B 应付职工薪酬(本年累计贷方/元) 科目余额表2211科目
C 应交增值税(本年累计贷方/元) 科目余额表2221.01科目(注意:是2221.01应交增值税子科目,不是2221整个应交税费)
D 平均用工人数(人) 用工人数统计表

原始数据源结构(方式二备选)

月报.xls

  • 由财务系统导出,格式为.xls,需用 xlrd 读取
  • 中文编码问题:终端直接打印中文会乱码,需写入临时文件后再读取
  • 包含5个Sheet(按名称查找,不要按索引):
  • Sheet: 资产负债表(内部)
  • Sheet: 所有者权益变动表
  • Sheet: 利润表
  • Sheet: 合并
  • Sheet: 资产负债表-对外填报(取资产负债数据用这个)
  • 编制单位在"资产负债表-对外填报"sheet的 cell(1,0),格式为"编制单位:XXX"
  • 取数方式:利润表和资产负债表均使用关键词匹配方式取数(而非固定行号),以适应不同公司格式差异

多账簿科目余额表

  • 金蝶系统导出xlsx,内部zip路径大小写不规范,需用 load_fixed() 修复后读取
  • Sheet名:Table1
  • 第1行:标题行(合并方案、期间、币别)
  • 第2行:列头(方案层级、科目编码、科目名称、期初余额(借)、期初余额(贷)、本期发生(借)、本期发生(贷)、本年累计(借)、本年累计(贷)、期末余额(借)、期末余额(贷))
  • ⚠️ 注意:无"核算维度编码"和"核算维度名称"列,共11列(而非13列)
  • ⚠️ 本年累计(贷)第9列(Col I),不是第11列(Col K)
  • 第3行起:数据行,按科目编码分组
  • 2211:应付职工薪酬(公司行在此分组下)
  • 2221.01:应交增值税(公司行在此分组下)
  • 方案层级:第1列,格式如"深圳卓正瑞祥管理咨询有限公司(002)"
  • 通过匹配方案层级中的公司名找到对应行

应交增值税科目余额表(单独引出)

  • 需单独从金蝶引出2221.01(应交增值税)科目余额表
  • 格式同上,11列,本年累计(贷)在Col 9
  • 不要用2221(应交税费)整个科目的数据,必须用2221.01(应交增值税)子科目

发薪人数累计平均数v2.xlsx

  • 普通xlsx,需用 data_only=True 读取
  • Sheet名:累计平均发薪人数
  • 第1行:列头
  • A列:支付主体(公司名)
  • B-E列:1-4月发薪人数
  • I列:4月累计平均人数(取此列作为平均用工人数)
  • 通过匹配公司名找到对应人数

取数逻辑

一、期末资产负债

模板字段 数据登记表列 原始来源(关键词匹配)
固定资产原价 资产负债表 B列 资产负债表-对外填报 "固定资产原值/固定资产原价"行 期末数
应收账款 资产负债表 C列 资产负债表-对外填报 "应收账款"行 期末数
资产总计 资产负债表 D列 资产负债表-对外填报 "资产总计"行 期末数
负债合计 资产负债表 E列 资产负债表-对外填报 "负债合计"行 期末数
所有者权益合计 资产负债表 F列 资产负债表-对外填报 "股东权益合计/所有者权益合计"行 期末数

二、损益

模板字段 数据登记表列 计算说明
营业收入 利润表 B+C 主营+其他业务收入合计
净服务收入 = 营业收入 等于营业收入
营业成本 利润表 D+E 主营+其他业务成本合计
税金及附加 利润表 F列 直接取
销售费用 利润表 G列 直接取
管理费用 利润表 H列 直接取
研发费用 利润表 I列 直接取
财务费用 利润表 J列 直接取
资产减值损失 利润表 K列 取相反数
信用减值损失 利润表 L列 取相反数
公允价值变动收益 利润表 M列 直接取
资产处置收益 利润表 N列 直接取
投资收益 利润表 O列 直接取
净敞口套期收益 - 填0
其他收益 - ⚠️ 固定填0,不取数
营业利润 按公式计算 见下方公式(不含其他收益)
营业外收入 利润表 Q+P 利润表营业外收入 + 其他收益总额
营业外支出 利润表 R列 直接取
利润总额 按公式计算 见下方公式
所得税费用 利润表 S列 直接取

三、成本费用及增值税

模板字段 数据登记表列 说明
应付职工薪酬 科目余额及用工 B列 2211科目本年累计贷方,元→千元
应交增值税 科目余额及用工 C列 2221.01应交增值税子科目本年累计贷方,元→千元(⚠️ 不是2221整个应交税费)

四、平均用工人数

模板字段 数据登记表列 说明
平均用工人数 科目余额及用工 D列 单位为人

计算公式

营业利润 = 营业收入 - 营业成本 - 税金及附加 - 销售费用 - 管理费用 - 研发费用 - 财务费用 + 资产减值损失 + 信用减值损失 + 公允价值变动收益 + 资产处置收益 + 投资收益 + 净敞口套期收益

利润总额 = 营业利润 + 营业外收入 - 营业外支出

注意: - 以上公式中的各项均为千元值(转换后),在千元级别做加减运算 - 其他收益(330)固定填0,不参与营业利润计算 - 营业外收入 = 利润表营业外收入 + 其他收益(其他收益的金额并入营业外收入)

单位转换

  • 原始数据单位为,模板单位为千元
  • 转换方法:round(val / 1000),四舍五入取整
  • 资产减值损失和信用减值损失:先取相反数再转千元

模板结构(财务状况模版.xlsx)

  • Sheet名:Sheet1
  • 数据列:H列(第8列,openpyxl中为 col=8)
  • 数据行:Row 12 ~ Row 41
  • 校验公式列:P列(第16列)
指标名称 代码
11 一、期末资产负债 -
12 固定资产原价 209
13 应收账款 202
14 资产总计 213
15 负债合计 217
16 所有者权益合计 218
17 二、损益 -
18 营业收入 301
19 其中:净服务收入 340
20 营业成本 307
21 税金及附加 309
22 销售费用 312
23 管理费用 313
24 研发费用 331
25 财务费用 317
26 资产减值损失(损失以"-"号记) 320
27 信用减值损失(损失以"-"号记) 333
28 公允价值变动收益(损失以"-"号记) 321
29 资产处置收益(损失以"-"号记) 335
30 投资收益(损失以"-"号记) 322
31 净敞口套期收益(损失以"-"号记) 334
32 其他收益 330
33 营业利润 323
34 营业外收入 325
35 营业外支出 326
36 利润总额 327
37 所得税费用 328
38 三、成本费用及增值税 -
39 应付职工薪酬(本年贷方累计发生额) 401
40 应交增值税(本年累计发生额) 402
41 四、平均用工人数 -
41 平均用工人数 606

校验公式(P列)

位置 公式 含义 标红规则
P16 =H14-H15-H16 资产总计 - 负债合计 - 所有者权益合计 不为0时标红
P33 =H18-H20-H21-H22-H23-H24-H25+H26+H27+H28+H29+H30+H31+H32-H33 营业利润勾稽验证 不为0时标红

标红样式:红色字体 + 粉色底色(#FFC7CE),使用 openpyxl 条件格式 CellIsRule

  • 期间不更新(用户明确要求不修改模板中的年月信息)

执行步骤 - 方式一:数据登记表(推荐)

Step 1: 判断输入方式

检查用户提供的文件: - 如果有「财务状况数据登记表.xlsx」→ 使用方式一 - 如果有月报.xls → 使用方式二 - 必须有「财务状况模版.xlsx」

Step 2: 读取数据登记表

import openpyxl
import shutil
import os
from openpyxl.styles import Font, PatternFill
from openpyxl.formatting.rule import CellIsRule

data_path = '财务状况数据登记表.xlsx'  # 用户提供
template_path = '财务状况模版.xlsx'       # 用户提供

wb_data = openpyxl.load_workbook(data_path, data_only=True)
ws_balance = wb_data['资产负债表']
ws_income = wb_data['利润表']
ws_other = wb_data['科目余额及用工']

# 收集所有公司名(以资产负债表sheet为准)
companies = []
for row in range(5, ws_balance.max_row + 1):
    name = ws_balance.cell(row, 1).value
    if name and str(name).strip():
        companies.append((row, str(name).strip()))

Step 3: 按公司提取数据并生成文件

def to_thousands(val):
    """元→千元,四舍五入取整"""
    if val is None or val == 0:
        return 0
    return round(float(val) / 1000)

def safe_val(ws, row, col):
    """安全取值,空值返回0"""
    v = ws.cell(row, col).value
    return float(v) if v is not None else 0

# 利润表和科目余额sheet的公司名→行号映射
def build_row_map(ws, data_start_row):
    """建立公司名→行号的映射"""
    m = {}
    for r in range(data_start_row, ws.max_row + 1):
        name = ws.cell(r, 1).value
        if name and str(name).strip():
            m[str(name).strip()] = r
    return m

income_row_map = build_row_map(ws_income, 6)    # 利润表数据从第6行开始
other_row_map = build_row_map(ws_other, 6)      # 科目余额数据从第6行开始

# 校验公式样式
red_font = Font(color='FF0000', bold=True)
red_fill = PatternFill(start_color='FFC7CE', end_color='FFC7CE', fill_type='solid')

for bal_row, company_name in companies:
    # --- 资产负债表 (数据在第5行起,A=名称, B-F=数值) ---
    fixed_assets = to_thousands(safe_val(ws_balance, bal_row, 2))    # B列
    accounts_recv = to_thousands(safe_val(ws_balance, bal_row, 3))   # C列
    total_assets = to_thousands(safe_val(ws_balance, bal_row, 4))    # D列
    total_liabilities = to_thousands(safe_val(ws_balance, bal_row, 5)) # E列
    equity = to_thousands(safe_val(ws_balance, bal_row, 6))          # F列

    # --- 利润表 (数据在第6行起,A=名称, B-S=数值) ---
    inc_row = income_row_map.get(company_name)
    if not inc_row:
        print(f"警告:公司 {company_name} 在利润表sheet中未找到,跳过")
        continue

    main_revenue = safe_val(ws_income, inc_row, 2)     # B列
    other_revenue = safe_val(ws_income, inc_row, 3)    # C列
    main_cost = safe_val(ws_income, inc_row, 4)        # D列
    other_cost = safe_val(ws_income, inc_row, 5)       # E列
    tax_surcharge = safe_val(ws_income, inc_row, 6)    # F列
    selling_exp = safe_val(ws_income, inc_row, 7)      # G列
    admin_exp = safe_val(ws_income, inc_row, 8)        # H列
    rd_exp = safe_val(ws_income, inc_row, 9)           # I列
    finance_exp = safe_val(ws_income, inc_row, 10)     # J列
    asset_impair = safe_val(ws_income, inc_row, 11)    # K列
    credit_impair = safe_val(ws_income, inc_row, 12)   # L列
    fair_value = safe_val(ws_income, inc_row, 13)      # M列
    asset_disposal = safe_val(ws_income, inc_row, 14)  # N列
    invest_income = safe_val(ws_income, inc_row, 15)   # O列
    other_income = safe_val(ws_income, inc_row, 16)    # P列
    non_op_income = safe_val(ws_income, inc_row, 17)   # Q列
    non_op_expense = safe_val(ws_income, inc_row, 18)  # R列
    income_tax = safe_val(ws_income, inc_row, 19)      # S列

    # 转千元
    revenue = to_thousands(main_revenue + other_revenue)
    net_service = revenue
    cost = to_thousands(main_cost + other_cost)
    tax_surcharge_k = to_thousands(tax_surcharge)
    selling_exp_k = to_thousands(selling_exp)
    admin_exp_k = to_thousands(admin_exp)
    rd_exp_k = to_thousands(rd_exp)
    finance_exp_k = to_thousands(finance_exp)
    asset_impair_k = to_thousands(-asset_impair)    # 相反数
    credit_impair_k = to_thousands(-credit_impair)  # 相反数
    fair_value_k = to_thousands(fair_value)
    asset_disposal_k = to_thousands(asset_disposal)
    invest_income_k = to_thousands(invest_income)
    net_hedge_k = 0
    other_income_k = 0  # ⚠️ 其他收益固定填0,不取数

    # 营业利润(不含其他收益)
    operating_profit = (revenue - cost - tax_surcharge_k - selling_exp_k - admin_exp_k
                        - rd_exp_k - finance_exp_k + asset_impair_k + credit_impair_k
                        + fair_value_k + asset_disposal_k + invest_income_k + net_hedge_k)

    # 营业外收入 = 利润表营业外收入 + 其他收益
    non_op_income_k = to_thousands(non_op_income + other_income)
    non_op_expense_k = to_thousands(non_op_expense)

    # 利润总额
    total_profit = operating_profit + non_op_income_k - non_op_expense_k

    income_tax_k = to_thousands(income_tax)

    # --- 科目余额及用工 (数据在第6行起) ---
    oth_row = other_row_map.get(company_name)
    payroll_k = 0
    tax_vat_k = 0
    employee_count = 0
    if oth_row:
        payroll_k = to_thousands(safe_val(ws_other, oth_row, 2))    # B列
        tax_vat_k = to_thousands(safe_val(ws_other, oth_row, 3))    # C列(2221.01应交增值税)
        emp_val = ws_other.cell(oth_row, 4).value                    # D列
        employee_count = int(emp_val) if emp_val else 0

    # --- 填入模板 ---
    output_path = f'{company_name}.xlsx'
    shutil.copy2(template_path, output_path)

    wb_dst = openpyxl.load_workbook(output_path)
    ws_dst = wb_dst['Sheet1']

    fill_map = {
        12: fixed_assets,
        13: accounts_recv,
        14: total_assets,
        15: total_liabilities,
        16: equity,
        18: revenue,
        19: net_service,
        20: cost,
        21: tax_surcharge_k,
        22: selling_exp_k,
        23: admin_exp_k,
        24: rd_exp_k,
        25: finance_exp_k,
        26: asset_impair_k,
        27: credit_impair_k,
        28: fair_value_k,
        29: asset_disposal_k,
        30: invest_income_k,
        31: net_hedge_k,
        32: other_income_k,  # 固定0
        33: operating_profit,
        34: non_op_income_k,
        35: non_op_expense_k,
        36: total_profit,
        37: income_tax_k,
        39: payroll_k,        # 应付职工薪酬
        40: tax_vat_k,        # 应交增值税(2221.01)
        41: employee_count,   # 平均用工人数
    }

    for row, val in fill_map.items():
        ws_dst.cell(row, 8).value = val

    # --- 校验公式 ---
    # P16: 资产总计 - 负债合计 - 所有者权益合计
    ws_dst.cell(16, 16).value = '=H14-H15-H16'
    ws_dst.cell(16, 16).number_format = '0'
    ws_dst.conditional_formatting.add(
        'P16',
        CellIsRule(operator='notEqual', formula=['0'], font=red_font, fill=red_fill)
    )

    # P33: 营业利润勾稽
    ws_dst.cell(33, 16).value = '=H18-H20-H21-H22-H23-H24-H25+H26+H27+H28+H29+H30+H31+H32-H33'
    ws_dst.cell(33, 16).number_format = '0'
    ws_dst.conditional_formatting.add(
        'P33',
        CellIsRule(operator='notEqual', formula=['0'], font=red_font, fill=red_fill)
    )

    wb_dst.save(output_path)
    print(f"已生成: {output_path}")

Step 4: 验证

生成后验证: - 读取每个输出文件,确认每行H列值正确 - 对比利润表原始营业利润/利润总额与计算值(千元级可能因四舍五入有±1差异) - 确认P16和P33校验公式不为0的已标红 - 确认文件以公司名称命名 - 如有多家公司,确认全部生成


执行步骤 - 方式二:原始文件(备选)

Step 1: 读取月报xls

import xlrd
import openpyxl
import shutil
import os

# 定位文件
xls_path = '...'  # 用户提供
template_path = '财务状况模版.xlsx'

wb_src = xlrd.open_workbook(xls_path)

# ⚠️ 按名称查找sheet,不要按索引(不同公司sheet数量/顺序可能不同)
def find_sheet_by_name(wb, target_name):
    for i in range(wb.nsheets):
        ws = wb.sheet_by_index(i)
        if ws.name.strip() == target_name.strip():
            return ws
    return None

ws_balance = find_sheet_by_name(wb_src, '资产负债表-对外填报')
ws_income = find_sheet_by_name(wb_src, '利润表')

# 提取编制单位名称
company_raw = ws_balance.cell(1, 0).value  # "编制单位:XXX"
company_name = company_raw.replace('编制单位:', '').replace('编制单位:', '').strip()

Step 2: 提取数据并转换(关键词匹配方式)

def to_thousands(val):
    """元→千元,四舍五入取整"""
    if val is None or val == 0:
        return 0
    return round(float(val) / 1000)

def safe_float(val):
    """安全转换为float,空值返回0"""
    if val is None or val == '':
        return 0.0
    try:
        return float(val)
    except (ValueError, TypeError):
        return 0.0

# --- 资产负债表-对外填报(关键词匹配取数)---
fixed_assets = 0
accounts_recv = 0
total_assets = 0
total_liabilities = 0
equity = 0

for r in range(ws_balance.nrows):
    cell_a = str(ws_balance.cell(r, 0).value).strip()
    cell_d = str(ws_balance.cell(r, 3).value).strip()
    val_col1 = safe_float(ws_balance.cell(r, 1).value)  # 左侧(资产)期末数
    val_col4 = safe_float(ws_balance.cell(r, 4).value)  # 右侧(负债及权益)期末数

    if '固定资产原值' in cell_a or '固定资产原价' in cell_a:
        fixed_assets = val_col1
    elif '应收账款' in cell_a and '坏账' not in cell_a and '净值' not in cell_a:
        accounts_recv = val_col1
    elif '资产总计' in cell_a:
        total_assets = val_col1
    elif '负债合计' in cell_d:
        total_liabilities = val_col4
    elif '股东权益合计' in cell_d or '所有者权益合计' in cell_d:
        equity = val_col4

# --- 利润表(关键词匹配取数,本年累计金额 = col 2)---
main_revenue = 0
other_revenue = 0
main_cost = 0
other_cost = 0
tax_surcharge = 0
selling_exp = 0
admin_exp = 0
rd_exp = 0
finance_exp = 0
asset_impair = 0
credit_impair = 0
fair_value = 0
asset_disposal = 0
invest_income = 0
other_income = 0
non_op_income = 0
non_op_expense = 0
income_tax = 0

for r in range(ws_income.nrows):
    cell_a = str(ws_income.cell(r, 0).value).strip()
    val = safe_float(ws_income.cell(r, 2).value)

    if '主营业务收入' in cell_a and '成本' not in cell_a and '利润' not in cell_a:
        main_revenue = val
    elif '其他业务收入' in cell_a:
        other_revenue = val
    elif '主营业务成本' in cell_a:
        main_cost = val
    elif '其他业务成本' in cell_a:
        other_cost = val
    elif '营业税金及附加' in cell_a or '税金及附加' in cell_a:
        tax_surcharge = val
    elif '销售费用' in cell_a:
        selling_exp = val
    elif '管理费用' in cell_a:
        admin_exp = val
    elif '研发费用' in cell_a:
        rd_exp = val
    elif '财务费用' in cell_a and '其中' not in cell_a and '利息' not in cell_a and '手续费' not in cell_a and '汇兑' not in cell_a and '使用权' not in cell_a and '关联方' not in cell_a:
        finance_exp = val
    elif '资产减值损失' in cell_a:
        asset_impair = val
    elif '信用减值损失' in cell_a:
        credit_impair = val
    elif '公允价值变动收益' in cell_a:
        fair_value = val
    elif '资产处置损益' in cell_a or '资产处置收益' in cell_a:
        asset_disposal = val
    elif '投资收益' in cell_a and '联营' not in cell_a and '合营' not in cell_a:
        invest_income = val
    elif '其他收益' in cell_a and '营业' not in cell_a:
        other_income = val
    elif '营业外收入' in cell_a:
        non_op_income = val
    elif '营业外支出' in cell_a and '非流动' not in cell_a:
        non_op_expense = val
    elif '所得税费用' in cell_a and '当期' not in cell_a and '递延' not in cell_a:
        income_tax = val

# 转千元
fixed_assets_k = to_thousands(fixed_assets)
accounts_recv_k = to_thousands(accounts_recv)
total_assets_k = to_thousands(total_assets)
total_liabilities_k = to_thousands(total_liabilities)
equity_k = to_thousands(equity)

revenue_k = to_thousands(main_revenue + other_revenue)
net_service_k = revenue_k
cost_k = to_thousands(main_cost + other_cost)
tax_surcharge_k = to_thousands(tax_surcharge)
selling_exp_k = to_thousands(selling_exp)
admin_exp_k = to_thousands(admin_exp)
rd_exp_k = to_thousands(rd_exp)
finance_exp_k = to_thousands(finance_exp)
asset_impair_k = to_thousands(-asset_impair)
credit_impair_k = to_thousands(-credit_impair)
fair_value_k = to_thousands(fair_value)
asset_disposal_k = to_thousands(asset_disposal)
invest_income_k = to_thousands(invest_income)
net_hedge_k = 0
other_income_k = 0  # ⚠️ 其他收益固定填0,不取数

# 营业利润(不含其他收益)
operating_profit_k = (revenue_k - cost_k - tax_surcharge_k - selling_exp_k
                      - admin_exp_k - rd_exp_k - finance_exp_k
                      + asset_impair_k + credit_impair_k
                      + fair_value_k + asset_disposal_k + invest_income_k + net_hedge_k)

# 营业外收入 = 利润表营业外收入 + 其他收益
non_op_income_k = to_thousands(non_op_income + other_income)
non_op_expense_k = to_thousands(non_op_expense)

# 利润总额
total_profit_k = operating_profit_k + non_op_income_k - non_op_expense_k
income_tax_k = to_thousands(income_tax)

Step 2.5: 提取科目余额表和用工人数数据

import zipfile, io
import re
from openpyxl import load_workbook
from openpyxl.styles import Font, PatternFill
from openpyxl.formatting.rule import CellIsRule

CASE_MAP = {
    '[content_types].xml': '[Content_Types].xml',
    'xl/sharedstrings.xml': 'xl/sharedStrings.xml',
}

def load_fixed(path):
    """修复金蝶导出xlsx的大小写问题"""
    buf = io.BytesIO()
    with zipfile.ZipFile(path, 'r') as zin:
        with zipfile.ZipFile(buf, 'w') as zout:
            for item in zin.namelist():
                zout.writestr(CASE_MAP.get(item, item), zin.read(item))
    buf.seek(0)
    return load_workbook(buf, data_only=True)

def strip_code(level_str):
    """从'深圳卓正瑞祥管理咨询有限公司(002)'中提取纯公司名"""
    if not level_str:
        return ''
    return re.sub(r'\([^)]*\)$', '', str(level_str)).strip()

# --- 读取应付职工薪酬(2211)---
wb_2211 = load_fixed('多账簿科目余额表_2211.xlsx')  # 2211应付职工薪酬
ws_2211 = wb_2211['Table1']

payroll_map = {}
current_section = None
for r in range(3, ws_2211.max_row + 1):
    code = ws_2211.cell(r, 2).value
    level = ws_2211.cell(r, 1).value
    if code and str(code).strip() == '2211':
        current_section = '2211'
        continue
    if not level or str(level).strip() == 'None' or '合计' in str(ws_2211.cell(r, 3).value or ''):
        continue
    company = strip_code(str(level))
    ytd_credit = safe_float(ws_2211.cell(r, 9).value)  # ⚠️ Col 9 = 本年累计(贷),不是Col 11
    payroll_map[company] = ytd_credit

# --- 读取应交增值税(2221.01)---
wb_2221 = load_fixed('多账簿科目余额表_2221.01.xlsx')  # ⚠️ 2221.01应交增值税子科目
ws_2221 = wb_2221['Table1']

vat_map = {}
for r in range(4, ws_2221.max_row + 1):  # 从第4行开始(跳过标题和合计行)
    name_raw = ws_2221.cell(r, 1).value
    if not name_raw or str(name_raw).strip() == 'None':
        continue
    company = strip_code(str(name_raw))
    ytd_credit = safe_float(ws_2221.cell(r, 9).value)  # ⚠️ Col 9 = 本年累计(贷)
    vat_map[company] = ytd_credit

payroll_k = to_thousands(payroll_map.get(company_name, 0))
tax_vat_k = to_thousands(vat_map.get(company_name, 0))

# --- 读取发薪人数 ---
wb_emp = openpyxl.load_workbook('发薪人数累计平均数v2.xlsx', data_only=True)
ws_emp = wb_emp['累计平均发薪人数']

employee_count = 0
for r in range(2, ws_emp.max_row + 1):
    name = ws_emp.cell(r, 1).value
    if name and str(name).strip() == company_name:
        avg4 = ws_emp.cell(r, 9).value  # I列 = 4月累计平均
        employee_count = int(avg4) if avg4 else 0
        break

Step 3: 复制模板并填入数据

output_path = f'{company_name}.xlsx'
shutil.copy2(template_path, output_path)

wb_dst = openpyxl.load_workbook(output_path)
ws_dst = wb_dst['Sheet1']

fill_map = {
    12: fixed_assets_k,
    13: accounts_recv_k,
    14: total_assets_k,
    15: total_liabilities_k,
    16: equity_k,
    18: revenue_k,
    19: net_service_k,
    20: cost_k,
    21: tax_surcharge_k,
    22: selling_exp_k,
    23: admin_exp_k,
    24: rd_exp_k,
    25: finance_exp_k,
    26: asset_impair_k,
    27: credit_impair_k,
    28: fair_value_k,
    29: asset_disposal_k,
    30: invest_income_k,
    31: net_hedge_k,
    32: other_income_k,   # 固定0
    33: operating_profit_k,
    34: non_op_income_k,
    35: non_op_expense_k,
    36: total_profit_k,
    37: income_tax_k,
    39: payroll_k,         # 应付职工薪酬(2211)
    40: tax_vat_k,         # 应交增值税(2221.01)
    41: employee_count,    # 平均用工人数
}

for row, val in fill_map.items():
    ws_dst.cell(row, 8).value = val

# --- 校验公式 ---
red_font = Font(color='FF0000', bold=True)
red_fill = PatternFill(start_color='FFC7CE', end_color='FFC7CE', fill_type='solid')

# P16: 资产总计 - 负债合计 - 所有者权益合计
ws_dst.cell(16, 16).value = '=H14-H15-H16'
ws_dst.cell(16, 16).number_format = '0'
ws_dst.conditional_formatting.add(
    'P16',
    CellIsRule(operator='notEqual', formula=['0'], font=red_font, fill=red_fill)
)

# P33: 营业利润勾稽
ws_dst.cell(33, 16).value = '=H18-H20-H21-H22-H23-H24-H25+H26+H27+H28+H29+H30+H31+H32-H33'
ws_dst.cell(33, 16).number_format = '0'
ws_dst.conditional_formatting.add(
    'P33',
    CellIsRule(operator='notEqual', formula=['0'], font=red_font, fill=red_fill)
)

wb_dst.save(output_path)

Step 4: 验证

生成后验证: - 读取输出文件,确认每行H列值正确 - 对比利润表原始营业利润/利润总额与计算值(千元级可能因四舍五入有±1差异) - 确认P16和P33校验公式不为0的已标红 - 确认文件以编制单位命名


注意事项

  • 输出文件以公司名称命名(如 深圳卓正瑞祥管理咨询有限公司.xlsx
  • 不更新期间:模板中的年月信息保持原样
  • 资产减值损失和信用减值损失取利润表值的相反数填入
  • 其他收益(330)固定填0,不取数;其他收益的金额并入营业外收入
  • 营业外收入 = 利润表营业外收入 + 其他收益总额
  • 营业利润公式中不含其他收益
  • 净敞口套期收益在利润表中无对应项目,填0
  • 应交增值税取2221.01子科目本年累计贷方(⚠️ 不是2221整个应交税费科目)
  • 数据登记表方式:多家公司只需一个文件,每个sheet一行一家公司,公司名须完全一致
  • 原始文件方式:多个月报文件都适用,每个文件独立生成
  • .xls文件中文在终端显示乱码,验证数据时需写入临时文件再读取
  • 科目余额表(金蝶导出xlsx)有大小写问题,需用 load_fixed() 修复后再读取
  • 科目余额表本年累计(贷)在Col 9(第9列),不是Col 11
  • 科目余额表无核算维度列,共11列(而非13列)
  • 月报xls包含5个sheet,按名称查找(而非按索引),不同公司sheet可能不同
  • 利润表/资产负债表使用关键词匹配取数(而非固定行号),适应不同公司格式差异
  • 校验公式:P16(资产=负债+权益)和P33(营业利润勾稽),不为0标红
  • 平均用工人数取自发薪人数累计平均数v2.xlsxI列(4月累计平均),需 data_only=True 读取

🤖 AI 评测

这是一个高质量的财务表生成技能,能根据财务数据自动生成符合统计局要求的F203报表。优点是支持两种输入方式(简单2文件或多文件),对易错点有明确提醒,数据校验机制完善。不足是文档较长,查找特定信息需要花费较多时间;部分专业术语较多,对非财务背景用户可能造成理解障碍。总体而言,这是一个功能完整、业务细节考虑周到的实用技能。

📊 多维度评分

适应性4.5
规范性4.4
有效性4.6
可靠性4.3
可信度5

📁 包含文件 (1 个)

📄 SKILL.md 31.1 KB