zhizhijie
2026-09-19 ade4387f72c876f779b0956295922003464434f0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
# -*- coding: utf-8 -*-
"""持续在规企业(545 家)分市州 1-8 月累计平均运距及同比 台账
 
口径:
  · 持续在规企业 = 2025 年 1-8 月与 2026 年 1-8 月均连续 8 个月上报 H203-2 月报的企业(545 家);
  · 累计平均运距(公里)= 1-8 月累计货物周转量 ÷ 1-8 月累计货运量(加权平均);
  · 同比 = 2026 年 1-8 月累计平均运距 ÷ 2025 年 1-8 月累计平均运距 − 1。
数据源:traffic_audit.h2032_enterprise_monthly 导出件 _tmp_persist_scope.tsv
"""
import io, os
from openpyxl import Workbook
from openpyxl.styles import Font, PatternFill, Alignment, Border, Side
from openpyxl.utils import get_column_letter
 
SRC = r'D:\文档\ChatGPT\traffic-audit\_tmp_persist_scope.tsv'
OUT = r'D:\文档\ChatGPT\traffic-audit\outputs\持续在规企业545家_分市州1-8月累计运距及同比_2026-09-19.xlsx'
 
ORDER = ['武汉市', '黄石市', '十堰市', '宜昌市', '襄阳市', '鄂州市', '荆门市', '孝感市', '荆州市',
         '黄冈市', '咸宁市', '随州市', '恩施州', '仙桃市', '潜江市', '天门市', '神农架林区']
SHORT = {'武汉市': '武汉', '黄石市': '黄石', '十堰市': '十堰', '宜昌市': '宜昌', '襄阳市': '襄阳', '鄂州市': '鄂州',
         '荆门市': '荆门', '孝感市': '孝感', '荆州市': '荆州', '黄冈市': '黄冈', '咸宁市': '咸宁', '随州市': '随州',
         '恩施州': '恩施州', '仙桃市': '仙桃', '潜江市': '潜江', '天门市': '天门', '神农架林区': '林区'}
CITY = dict(zip(['4201', '4202', '4203', '4205', '4206', '4207', '4208', '4209', '4210', '4211', '4212', '4213', '4228'],
                ORDER[:13]))
CITY.update({'429004': '仙桃市', '429005': '潜江市', '429006': '天门市', '429021': '神农架林区'})
 
 
def city_of(rc):
    rc = (rc or '').strip()
    return CITY.get(rc, CITY.get(rc[:4], '?'))
 
 
def dv(f, t):
    return (t / f) if f else None
 
 
def gth(a, b):
    return (a / b - 1) if (a is not None and b) else None
 
 
def num(x):
    try:
        return float(x)
    except Exception:
        return 0.0
 
 
rows = []
with io.open(SRC, 'r', encoding='utf-8') as fh:
    hdr = fh.readline().rstrip('\r\n').split('\t')
    for line in fh:
        p = line.rstrip('\r\n').split('\t')
        if len(p) < len(hdr):
            continue
        d = dict(zip(hdr, p))
        if int(num(d['m26'])) != 8 or int(num(d['m25'])) != 8:
            continue
        rows.append(dict(city=city_of(d['rc']), en=d['en'], ec=d['ec'], ucc=d['ucc'],
                         f26=num(d['f26']), t26=num(d['t26']), f25=num(d['f25']), t25=num(d['t25'])))
 
by_city = {}
for r in rows:
    c = by_city.setdefault(r['city'], dict(n=0, f26=0.0, t26=0.0, f25=0.0, t25=0.0))
    c['n'] += 1
    c['f26'] += r['f26']; c['t26'] += r['t26']; c['f25'] += r['f25']; c['t25'] += r['t25']
tot = dict(n=0, f26=0.0, t26=0.0, f25=0.0, t25=0.0)
for c in by_city.values():
    for k in tot:
        tot[k] += c[k]
 
THIN = Side(style='thin', color='BFBFBF')
BORDER = Border(left=THIN, right=THIN, top=THIN, bottom=THIN)
HDR_FILL = PatternFill('solid', fgColor='DDEBF7')
TOT_FILL = PatternFill('solid', fgColor='FFF2CC')
TITLE_FILL = PatternFill('solid', fgColor='1F4E79')
CT = Alignment(horizontal='center', vertical='center', wrap_text=True)
LT = Alignment(horizontal='left', vertical='center', wrap_text=True)
RT = Alignment(horizontal='right', vertical='center')
NF2, NFP = '#,##0.00', '0.00%'
 
wb = Workbook()
ws = wb.active
ws.title = '市州汇总'
heads = ['市州', '持续在规企业数(家)', '2026年1-8月累计货运量(万吨)', '2026年1-8月累计货物周转量(万吨公里)',
         '2026年1-8月累计平均运距(公里)', '2025年1-8月累计平均运距(公里)', '累计运距同比(%)', '备注']
widths = [12, 16, 22, 26, 22, 22, 14, 46]
ws.cell(1, 1, '持续在规企业(545 家)分市州 1-8 月累计平均运距及同比').font = Font(bold=True, size=14, color='FFFFFF')
ws.cell(1, 1).fill = TITLE_FILL
ws.cell(1, 1).alignment = Alignment(horizontal='center', vertical='center')
ws.merge_cells(start_row=1, start_column=1, end_row=1, end_column=len(heads))
ws.row_dimensions[1].height = 28
notes = [
    '口径说明:',
    '① 持续在规企业 = 2025 年 1-8 月与 2026 年 1-8 月均连续 8 个月上报《道路货物运输月度生产情况》(H203-2)月报的企业,共 %d 家;两年间新进、退出的企业不计入本表同比。' % tot['n'],
    '② 累计平均运距(公里)= 1-8 月累计货物周转量 ÷ 1-8 月累计货运量(加权平均);同比 = 2026 年 1-8 月累计平均运距 ÷ 2025 年 1-8 月累计平均运距 − 1。',
    '③ 全省行 = 17 个市州之和(按累计周转量、累计货运量分别求和后相除,不是市州同比的算术平均)。',
    '④ 仙桃市 2026 年持续在规的 2 家企业 2025 年 1-8 月无连续上报记录,本表无可比基数,同比不适用。',
    '数据来源:交通统计报表审核系统数据库(H203-2 企业月报,2025 年 1 月—2026 年 8 月)。生成日期:2026-09-19。',
]
r = 2
for i, t in enumerate(notes):
    c = ws.cell(r, 1, t)
    c.font = Font(size=9, bold=(i == 0), color='404040')
    c.alignment = LT
    ws.merge_cells(start_row=r, start_column=1, end_row=r, end_column=len(heads))
    r += 1
hdr_row = r
for j, h in enumerate(heads, 1):
    c = ws.cell(hdr_row, j, h)
    c.font = Font(bold=True); c.fill = HDR_FILL; c.alignment = CT; c.border = BORDER
    ws.column_dimensions[get_column_letter(j)].width = widths[j - 1]
ws.row_dimensions[hdr_row].height = 42
 
 
def put(row, vals, fill=None, bold=False):
    for j, v in enumerate(vals, 1):
        c = ws.cell(row, j, v)
        c.border = BORDER
        c.alignment = LT if j == 8 else (CT if j == 1 else RT)
        if j in (3, 4, 5, 6):
            c.number_format = NF2
        elif j == 7:
            c.number_format = NFP
        if fill:
            c.fill = fill
        if bold:
            c.font = Font(bold=True)
 
 
rr = hdr_row
d26 = dv(tot['f26'], tot['t26']); d25 = dv(tot['f25'], tot['t25'])
rr += 1
put(rr, ['全省', tot['n'], tot['f26'] / 10000.0, tot['t26'] / 10000.0, d26, d25, gth(d26, d25), ''], TOT_FILL, True)
for city in ORDER:
    c = by_city.get(city)
    rr += 1
    if not c or c['n'] == 0:
        put(rr, [SHORT[city], 0, None, None, None, None, None,
                 '该市州 2026 年持续在规企业在 2025 年 1-8 月无连续上报记录,同比不适用'])
        continue
    a, b = dv(c['f26'], c['t26']), dv(c['f25'], c['t25'])
    put(rr, [SHORT[city], c['n'], c['f26'] / 10000.0, c['t26'] / 10000.0, a, b, gth(a, b), ''])
ws.freeze_panes = ws.cell(hdr_row + 1, 2).coordinate
 
# 企业明细
ws2 = wb.create_sheet('企业明细(545家)')
h2 = ['序号', '市州', '企业名称', '统一社会信用代码', '2026年1-8月货运量(万吨)', '2026年1-8月周转量(万吨公里)',
      '2026年1-8月累计平均运距(公里)', '2025年1-8月累计平均运距(公里)', '累计运距同比(%)']
w2 = [6, 12, 42, 24, 20, 24, 22, 22, 14]
for j, h in enumerate(h2, 1):
    c = ws2.cell(1, j, h)
    c.font = Font(bold=True); c.fill = HDR_FILL; c.alignment = CT; c.border = BORDER
    ws2.column_dimensions[get_column_letter(j)].width = w2[j - 1]
ws2.row_dimensions[1].height = 40
order = {c: i for i, c in enumerate(ORDER)}
idx = 0
for i, x in enumerate(sorted(rows, key=lambda z: (order.get(z['city'], 99), -z['t26'])), 1):
    a, b = dv(x['f26'], x['t26']), dv(x['f25'], x['t25'])
    vals = [i, SHORT[x['city']], x['en'], x['ucc'], x['f26'] / 10000.0, x['t26'] / 10000.0, a, b, gth(a, b)]
    for j, v in enumerate(vals, 1):
        c = ws2.cell(i + 1, j, v)
        c.border = BORDER
        c.alignment = LT if j in (3, 4) else (CT if j in (1, 2) else RT)
        if j in (5, 6, 7, 8):
            c.number_format = NF2
        elif j == 9:
            c.number_format = NFP
ws2.freeze_panes = 'C2'
ws2.auto_filter.ref = 'A1:I%d' % (len(rows) + 1)
 
os.makedirs(os.path.dirname(OUT), exist_ok=True)
wb.save(OUT)
print('OK ->', OUT)
print('企业数 %d;全省 2026 %.4f / 2025 %.4f -> %.4f%%' % (tot['n'], d26, d25, gth(d26, d25) * 100))