Перейти к основному содержимому

Аналитический портал ФНС (analytic.nalog.gov.ru) — выгрузки и витрина

ПризнакЗначение
Уровень и охватФедеральный; субъекты РФ и консолидированные ряды по бюджетной системе в логике портала
Тип доступаHTTP GET к выгрузке налоговых паспортов (архив ZIP); веб-интерфейс с интерактивными графиками и картами
Основные форматыZIP с таблицами Excel BIFF8 (.xls) по территориям в составе дампа паспортов; HTML/скрипты для дашбордов на главной и внутренних страницах
ОператорФНС России
Режим доступаОткрытый просмотр и скачивание публичных материалов; при автоматизации запросов соблюдайте разумную нагрузку и идентифицируемый User-Agent

Коротко: analytic.nalog.gov.ru даёт машиночитаемую годовую выгрузку налоговых паспортов всех субъектов РФ одним ZIP-файлом и интерактивную аналитику (в т.ч. поступления в бюджетную систему РФ на главной странице). Для кассового исполнения по КБК по-прежнему ориентируйтесь на отчёты Казначейства и сводки Минфина, сопоставляя смысл показателей.

Описание​

Карточка фиксирует публичные каналы данных аналитического портала ФНС: (1) налоговые паспорта субъектов РФ — единый дамп за выбранный календарный год в виде ZIP с отдельными таблицами Excel по регионам; (2) поступления в бюджетную систему РФ и иные показатели — прежде всего через интерактивные графики и виджеты на сайте (без отдельного документированного JSON/API под каждый блок). В объём не входят персонифицированные сервисы, каталог открытых данных ФНС с паспортами наборов и ППД ФНС.

Оператор​

Федеральная налоговая служба — аналитический портал: https://analytic.nalog.gov.ru/

URL и точки доступа​

Тип доступаURLФормат
Главная страница (дашборды, в т.ч. поступления в бюджетную систему РФ)https://analytic.nalog.gov.ru/HTML; интерактивные графики
Выгрузка налоговых паспортов субъектов РФ за год (один архив)https://analytic.nalog.gov.ru/api/TaxPassports/ExportAll?year=<YYYY>application/zip: внутри — Excel-файлы по субъектам, федеральным округам и РФ

Параметр year: номер календарного года в имени архива. 17 июля 2026 года запросы за 2014, 2023 и 2024 вернули 200 и application/zip; запрос за 2025 вернул 400. Публичного каталога доступных годов endpoint не публикует, поэтому не выводите диапазон лет из единичного успешного запроса.

Объекты данных и показатели​

  • Налоговые паспорта — сводные табличные наборы по субъекту РФ за год; состав столбцов и листов задаётся шаблоном паспорта на дату выгрузки (при сравнении между годами проверяйте изменения структуры файлов).
  • Интерактивные блоки на портале — агрегированные ряды для графиков (поступления в бюджетную систему, структура, динамика и др. по разделам); воспроизводимый машинный ряд чаще получают из первичных форм и налоговой статистики ФНС, а портал используют для обзора и визуализации.
  • Связка с бюджетными рядами — на уровне экономической интерпретации и согласования определений показателя с методикой ФНС; прямого единого ключа с казначейскими отчётами нет.

Структура опубликованных файлов​

Ниже — результат программной инвентаризации полностью распакованных архивов endpoint за 2014 и 2024 годы (проверка 17 июля 2026 года). Полная машиночитаемая спецификация с точными путями всех многоуровневых заголовков, типами и примерами находится в профиле структуры. Примеры значений в этом разделе — из проверенного файла НП_2024_Томская область.xls; значений из листа «Руководители» здесь нет.

Схема поставки: ZIP за year → .xls с территорией в имени → лист паспорта → строки показателей. Это именно старый формат Excel BIFF8 (.xls), а не XLSX: openpyxl не читает исходные файлы напрямую; для них подходит xlrd или LibreOffice.

Архив и выбор файла территории​

ГодФайлы и охватИмена и расширениеРазмер распакованных файловКонтроль структуры
201492: 83 субъекта, 8 федеральных округов и РФНП_2014_<наименование>.xls, например НП_2014_Томская область.xls, НП_2014_РОССИЙСКАЯ ФЕДЕРАЦИЯ.xls17 682 944 байта; один файл 186 368–194 048 байтодинаковых payload по SHA-256 нет; SHA-256 ZIP: 58e6979d…128ade991
202494: 85 субъектов, 8 федеральных округов и РФНП_2024_<наименование>.xls, например НП_2024_Томская область.xls, НП_2024_СИБИРСКИЙ ФЕДЕРАЛЬНЫЙ ОКРУГ.xls15 397 888 байт; один файл 159 744–165 376 байтодинаковых payload по SHA-256 нет; SHA-256 ZIP: 6613d105…6bb729cc

Имя файла содержит отображаемое наименование территории, но не ОКТМО, ОКАТО, код субъекта, ISO или иной ключ. Сохраняйте его как file_label. В 2024 по сравнению с 2014 добавились только файлы НП_2024_Республика Крым.xls и НП_2024_г.Севастополь.xls; в обоих проверенных архивах есть восемь файлов с ФЕДЕРАЛЬНЫЙ ОКРУГ и один файл РОССИЙСКАЯ ФЕДЕРАЦИЯ. Округа и РФ — самостоятельные готовые агрегаты, а не дубликаты региональных строк.

Инвентарь листов и физическая разметка​

Все найденные листы видимы; скрытых листов и скрытых столбцов нет. Столбцы и строки в таблице ниже — физический размер листа, то есть он включает скрытые строки и форматные пустые ячейки. Руководители отсутствует только в книге РФ: поэтому в 2014 это 91 книга с листом, в 2024 — 93.

ЛистРазмер 2014Размер 2024Merged cells, 2014 / 2024Шапка и назначение
ТИТУЛ29×1229×1212–18 / 12–18анкета книги: дата среза, территория, центр, округ, код УФНС
Содержание15–17×1116×1113–14 / 14навигационный перечень листов и их заголовков
Руководители17–23×7–88–14×76 / 6многоуровневая шапка, содержит персональные данные
Раздел169–72×465–68×42 / 1социально-экономические индикаторы
Раздел2102×4134×41 / 1налоговая база по администрируемым доходам
Раздел332×426×41 / 1льготы
Раздел429×418×41 / 1контрольная работа
Раздел564–67×1345×1318 / 18поступления в разрезе бюджетов
Раздел652×1510–12×417 / 4в 2014 — поступления по видам деятельности; в 2024 — страховые взносы
Раздел743–44×1047×18–1911–12 / 21–22в 2014 — задолженность; в 2024 — поступления по видам деятельности
Раздел857×10нет12 / —задолженность по видам деятельности (только 2014)
Раздел940×5нет7 / —налоговая нагрузка (только 2014)
Раздел1028–29×6–726×58 / 4в 2014 — нагрузка по отраслям; в 2024 — нагрузка к ВРП
Раздел1163×519×83 / 5в 2014 — оценка/прогноз; в 2024 — нагрузка по отраслям за два года
Раздел12нет47×5— / 1оценка и прогноз отдельных налогов (только 2024)

В 2024 у Раздел7 18 содержательных полей (A:R), а 19-й столбец региональных книг только форматный. Во всех годах многоуровневые шапки объединены через merged cells; для кода их надо разворачивать сверху вниз и именовать путь заголовка через →, как в YAML-профиле. Строка с порядковыми номерами колонок (1, 2, …) следует после шапки и не является данными.

В исходных ячейках за оба года наблюдались только строки, числа и пустые значения; отдельных Excel-дат не найдено. Даты в заголовках — текст, например ПО СОСТОЯНИЮ НА 01.01.2025 в книге year=2024. Числовые форматы включают #,##0, #,##0.0 и #,##0.00; не округляйте значения до визуального формата. В BIFF-потоке всех 92 книг 2014 обнаружено 5 000 записей FORMULA, тогда как в 94 книгах 2024 — ни одной: при чтении старых книг забирайте кэшированные значения, не пытайтесь считать формулы неизменной публичной моделью.

ТИТУЛ​

Зерно — одна книга. Лист не надо читать через header=: значения лежат в ячейках-анкерах внутри merged blocks. Для 2024 в проверенной региональной книге присутствуют подписи СУБЪЕКТ РОССИЙСКОЙ ФЕДЕРАЦИИ, ОБЛАСТНОЙ (РЕСПУБЛИКАНСКИЙ, КРАЕВОЙ) ЦЕНТР, ФЕДЕРАЛЬНЫЙ ОКРУГ, КОД УПРАВЛЕНИЯ ФНС РОССИИ и текст среза. Их можно сохранить как метаданные книги, но самым устойчивым ключом территории остаётся исходный file_label: координаты анкеты зависят от класса территории.

Содержание​

Зерно — один лист паспорта. Две фактические текстовые колонки дают техническое имя (Раздел5) и развёрнутый заголовок. Используйте их для контроля семантики перед объединением годов: номер раздела в 2014 и 2024 не гарантирует одинаковый предмет.

Руководители​

Зерно — должность. Точные заголовки: ПОКАЗАТЕЛЬ, Код строки, Фамилия, имя, отчество, Адрес → почтовый, Адрес → электронной почты, Код и номер → телефона, Код и номер → факса. Это единственный лист с фамилиями, адресами, e-mail и телефонами. Он не нужен для анализа показателей и должен исключаться из обычного пайплайна и из публикации результатов без отдельного основания для обработки ПДн.

Раздел1 — социально-экономическая характеристика​

Зерно — строка показателя в территории и year; измерения — file_label, год и внутренний Код строки. Пример 2024: код 101, значение 912.4494 для показателя ВРП. Единица не едина: она указана в тексте конкретного показателя (например, млрд руб. или проценты).

Раздел2 — налоговая база​

То же зерно; показатель может быть суммой, количеством или отношением, поэтому value_yyyy нельзя объявлять «суммой в рублях» для всего листа. Пример 2024: код 201, 2043162.124, рост 105.1387209131.

Раздел3 — льготы​

То же зерно; в тексте строк встречается сумма налога, не поступившая в бюджет, и подгруппы льгот. Пример 2024: код 301, 1496.714, рост 49.4643641458. Строки из них: без кода — не самостоятельные записи.

Раздел4 — контрольная работа​

То же зерно, но значения смешивают количества (единиц) и деньги (млн. руб.). Пример 2024: код 401, 32, рост 72.7272727273; это не денежное значение. В проверенном файле есть скрытая строка со служебным отрицательным кодом -401; сохраняйте её отдельно либо исключайте по явному правилу, а не по положительности кода.

Точный заголовок в Раздел1–Раздел4Нормализованное имяТип после чтенияСмысл и единицаПример из 2024Примечание
ПОКАЗАТЕЛЬindicator_labelstringназвание показателя; единица обычно внутри текстаДоходы от реализации, включая внереализационные доходы (млн. руб.)хранить исходный текст
Код строкиrow_codestringвнутренний код строки201в разных листах может быть числом или строкой; это не КБК/ОКВЭД/ОКТМО
2014 год / 2024 годvalue_2014 / value_2024number or stringфактическое значение; единица зависит от indicator_label2043162.124X не преобразовывать в 0
В % к предыдущему годуpct_to_previous_yearnumber or stringотношение к предыдущему году, %105.1387209131маркер X означает нечисловое/неприменимое значение в файле

Раздел5 — поступления по бюджетам​

Зерно — вид администрируемого дохода в территории и году; ключ — [year, file_label, "Раздел5", row_code]. В 2014 в строке с названием территории есть отдельная надпись млн.руб., в проверенной книге 2024 отдельной единицы в шапке нет: её нельзя автоматически проставить по сходству шаблонов. Строка ВСЕГО ПО АДМИНИСТРИРУЕМЫМ ДОХОДАМ уже содержит итог; не складывайте её с детализацией.

Точный путь заголовкаНормализованное имяТипСмысл / единицаПример, код 501 за 2024Примечание
ПОКАЗАТЕЛЬindicator_labelstringвид доходаВСЕГО ПО АДМИНИСТРИРУЕМЫМ ДОХОДАМстроки в том числе: исключить
Код строкиrow_codestringвнутренний код501не классификатор доходов
Поступило в консолидированный бюджет Российской Федерации → Всегоconsolidated_budget_rf_totalnumber/stringпоступило; единица не объявлена в шапке 2024413862.958X и пустота не ноль
Поступило в консолидированный бюджет Российской Федерации → В % к предыдущему периодуconsolidated_budget_rf_pct_prev_periodnumber/stringтемп, %121.073815673—
Поступило в консолидированный бюджет Российской Федерации → Удельный вес (%)consolidated_budget_rf_share_pctnumber/stringдоля, %100—
в том числе → В федеральный бюджет → Всегоfederal_budget_totalnumber/stringпоступило в федеральный бюджет330137.04часть предыдущего итога
в том числе → В федеральный бюджет → В % к предыдущему периодуfederal_budget_pct_prev_periodnumber/stringтемп, %124.9854783623—
в том числе → В федеральный бюджет → Удельный вес (%)federal_budget_share_pctnumber/stringдоля, %100—
в том числе → В консолидированный бюджет субъекта РФ → Всегоsubject_consolidated_budget_totalnumber/stringпоступило в бюджет субъекта83725.918часть общего итога
в том числе → В консолидированный бюджет субъекта РФ → В % к предыдущему периодуsubject_consolidated_budget_pct_prev_periodnumber/stringтемп, %107.7738758063—
в том числе → В консолидированный бюджет субъекта РФ → Удельный вес (%)subject_consolidated_budget_share_pctnumber/stringдоля, %100—
из него → В местный бюджет → Всегоlocal_budget_totalnumber/stringпоступило в местный бюджет17190.169вложено в бюджет субъекта
из него → В местный бюджет → В % к предыдущему периодуlocal_budget_pct_prev_periodnumber/stringтемп, %120.7092734146—

Раздел6​

Это несовместимые по смыслу листы. В 2014 зерно — вид экономической деятельности; 15 колонок раскрывают поступления по федеральным, региональным, местным налогам и специальным режимам. В 2024 зерно — вид страхового взноса; фактические поля: ПОКАЗАТЕЛЬ, Код строки, Поступление доходов по страховым взносам на обязательное социальное страхование в Российской Федерации → Всего, … → В % к предыдущему периоду. Пример 2024: код 601, всего 76561.789. Полный список полей версии 2014 и 2024 — в YAML-профиле; номера строк 601 в этих двух шаблонах нельзя считать одинаковым измерением.

Раздел7​

В 2014 это задолженность: срез на 01.01.2015 и изменение за 2014 год с разложением на недоимку, реструктурированную и приостановленную задолженность. В 2024 это поступления по видам экономической деятельности. Зерно последнего — текстовое наименование деятельности; опубликованного кода ОКВЭД нет, Код строки не заменяет его. 18 содержательных колонок 2024 включают общий итог, долю, федеральные/региональные/местные налоги, спецрежимы и три поля страховых взносов. Пример итоговой строки: код 701, Поступило в консолидированный бюджет, всего = 413861.021. Точные пути всех 18 заголовков и нормализованные имена приведены в профиле.

Раздел8​

Есть только в 2014. Зерно — вид экономической деятельности на дату задолженности; колонки содержат общую задолженность, недоимку, отсроченные/реструктурированные и приостановленные платежи — для каждого денежное значение и долю. Единицы денежной части прямо указаны в шапке: млн. рублей; доли — %. В 2024 эквивалентного листа нет.

Раздел9​

Есть только в 2014. Зерно — вид администрируемого дохода; поля нагрузки — в консолидированный бюджет Российской Федерации, в федеральный бюджет, в консолидированный бюджет субъекта РФ под общей шапкой НАЛОГОВАЯ НАГРУЗКА (В % К ВРП) В 2014 ГОДУ. Это предшественник по тематике, но не по номеру, Раздел10 2024.

Раздел10​

В 2014 лист измеряет нагрузку по четырём видам деятельности в копейках с 1 рубля; это не процент и не тот же набор, что в 2024. В 2024 зерно — вид администрируемого дохода, а три показателя — нагрузка в процентах к ВРП в консолидированный бюджет РФ, федеральный бюджет и бюджет субъекта. Пример 2024: код 1001, нагрузка в консолидированный бюджет РФ 45.3573598711. Три скрытые служебные строки имеют коды -1010, -1001 и -1002; среди них находятся ВРП и численность населения, поэтому простое «читать только видимое» меняет набор данных.

Раздел11​

В 2014 это оценка и прогноз: 2014 год (базисный год - факт), 2015 год (текущий год - оценка), Планируемый период (прогноз). В 2024 это другой лист: нагрузка по видам деятельности с парой колонок 2023/2024 — Поступило в консолидированный бюджет РФ, млрд.руб, Оборот организаций, млрд.руб., Налоговая нагрузка, %. Зерно 2024 — деятельность и год-колонка; в длинной модели эти три пары нужно разворачивать в строки. Пример кода 1101: за 2024 поступления 413.861021 млрд руб., оборот 1625.3 млрд руб.

Раздел12​

Есть только в 2024 и содержит оценку/прогноз, перенесённые из Раздел11 2014. Зерно — показатель налога и горизонт: 2024 год (базисный год - факт), 2025 год (текущий год - оценка), Планируемый период (прогноз). Единица каждого числового поля определяется текстом показателя: среди них есть млн руб., проценты, доллары за баррель и физические объёмы. Пример: код 1200, базисный факт 92024 для суммы прибыли по прибыльным организациям.

Изменения между проверенными годами​

  • Состав файлов вырос с 92 до 94 из-за двух названных субъектов; набор из 8 округов и файла РФ остался.
  • Физическая шапка в Раздел1–Раздел5 поднялась с строк 13–17 в 2014 к строкам 4–8 (либо 4–6) в 2024. Жёсткий skiprows=12 годится только для старого шаблона.
  • Раздел2 вырос со 102 до 134 физических строк; Раздел3 и Раздел4, напротив, сократились.
  • Блок задолженности Раздел7–Раздел8 2014 в 2024 отсутствует. Поступления по деятельности переместились из Раздел6 2014 в Раздел7 2024 и получили страховые взносы.
  • Нагрузка к ВРП переместилась из Раздел9 2014 в Раздел10 2024; отраслевая нагрузка в копейках (Раздел10 2014) заменена иной двухлетней таблицей в Раздел11 2024.
  • Оценка/прогноз перешли из Раздел11 2014 в Раздел12 2024. В 2014 есть 5 000 BIFF-формул, в 2024 формул не обнаружено.

Ограничения интерпретации​

  • year в URL — версия паспорта, а не гарантированно единый период всех ячеек: книга 2024 имеет срез 01.01.2025, Раздел11 включает 2023 и 2024, а Раздел12 — оценку 2025 и прогноз.
  • Не складывайте строку ВСЕГО с подстроками в том числе/из него; не суммируйте одновременно субъекты, федеральные округа и РФ. Они пересекаются по охвату.
  • Одна колонка value_yyyy в Раздел1–Раздел4 смешивает деньги, количества, индексы и физические величины. Единицу определяет текст строки, а не имя листа.
  • X, - и пустая ячейка — три наблюдаемых представления отсутствующего/неприменимого значения, а не нули. До преобразования числа сохраняйте исходное текстовое значение и причину пропуска.
  • Код строки — локальный код шаблона, а подписи деятельности не сопровождаются кодами ОКВЭД. Для межгодового сопоставления проверяйте вместе заголовок листа, текст показателя, единицу и смысл колонки.
  • Скрытые строки могут содержать служебные значения или вспомогательные расчёты. По умолчанию сохраняйте признак скрытости; удаляйте их только после явного правила для конкретного листа.

Рекомендуемая модель для машинной обработки​

source:
url_template: "https://analytic.nalog.gov.ru/api/TaxPassports/ExportAll?year={year}"
request_parameter: {year: "календарный год версии паспорта"}
archive:
expected_format: "ZIP with BIFF8 .xls files, not XLSX"
file_selector: "НП_{year}_{file_label}.xls"
territory_key: [year, file_label]
aggregate_labels: ["*ФЕДЕРАЛЬНЫЙ ОКРУГ", "РОССИЙСКАЯ ФЕДЕРАЦИЯ"]
workbook:
parser: "pandas + xlrd for .xls; openpyxl only if operator later changes to .xlsx"
ignore_by_default: ["Руководители # PII"]
metadata_sheet: "ТИТУЛ"
schema_sheet: "Содержание"
record_model:
key: [year, file_label, sheet_name, row_code]
dimensions: [year, file_label, sheet_name, row_code, indicator_label]
metrics: "all numeric leaves after reconstructed multi-row header"
row_code_type: "string; retain decimal and negative codes"
activity_dimension: "activity_label only; no OKVED code published"
normalisation:
headers: "fill merged cells downward/rightward; join levels with ' → '"
drop_rows: "serial-number row and rows without row_code"
missing: {"X": null, "-": null, "empty": null, preserve_raw_value: true}
numbers: "parse only after retaining source text; do not round display formats"
joins_and_aggregation:
cross_year: "map semantic header path plus indicator text; never row_code alone"
cross_file: "do not add RF/FD aggregates to subject files"
totals: "do not sum totals with nested detail without a checked hierarchy"
versioning: "branch schema by year; 2014 and 2024 section numbers are not stable"

Полный вариант этой модели, включая все 13 полей Раздел5, 18 полей Раздел7 2024, 2014-листы задолженности и точные строки шапок, расположен в analytic-nalog-gov-ru.schema.yaml.

Периодичность обновления​

ZIP-выгрузки паспортов пересобираются при обновлении данных/шаблонов на стороне портала; точный календарь публикаций в карточке не фиксируется. Для интерактивных графиков ориентируйтесь на дату/подпись периода в интерфейсе виджета и на уточнения в карточке ИС (раздел про актуальность интерфейса).

Ограничения и особенности​

  • Документированность API: описанный здесь endpoint ориентирован на скачивание готового архива; это не полноценный каталог opendata с метаданными на уровне каждого показателя.
  • Интерактив без стабильного API: для большинства графиков на главной и во внутренних разделах нет публичной спецификации REST на уровне wiki — при необходимости пайплайна используйте выгрузки паспортов, формы статистики и открытые данные ФНС.
  • Автоматизация: при серии запросов задавайте осмысленный User-Agent и интервалы; при 403 повторите запрос с заголовками, типичными для клиента браузера (см. примеры в налоговой статистике ФНС).

Примеры доступа​

Скачать проверенный архив за 2024 год:

curl --fail --location \
--user-agent "Mozilla/5.0 (compatible; finguide-data-audit/1.0; +https://github.com/ibegtin/finguide)" \
--output "tax-passports-2024.zip" \
"https://analytic.nalog.gov.ru/api/TaxPassports/ExportAll?year=2024"

Ниже воспроизводимый пример для Раздел2 и фактически опубликованного .xls. Он намеренно выбирает НП_2024_Томская область.xls, который был в проверенном архиве. Для другой территории меняйте только REGION_FRAGMENT на точную часть имени файла. Нужны requests, pandas и xlrd>=2 (openpyxl здесь не используется, потому что он не поддерживает BIFF8 .xls).

from __future__ import annotations

import re
import sys
from pathlib import Path
from zipfile import ZipFile

import pandas as pd
import requests


YEAR = int(sys.argv[1]) if len(sys.argv) > 1 else 2024
REGION_FRAGMENT = "Томская область" # существует в проверенных 2014 и 2024
SHEET = "Раздел2"
URL = "https://analytic.nalog.gov.ru/api/TaxPassports/ExportAll?year={year}"
HEADERS = {
"User-Agent": (
"Mozilla/5.0 (compatible; finguide-data-audit/1.0; "
"+https://github.com/ibegtin/finguide)"
)
}

work_dir = Path(f"tax-passports-{YEAR}")
work_dir.mkdir(exist_ok=True)
zip_path = work_dir / f"tax-passports-{YEAR}.zip"

response = requests.get(URL.format(year=YEAR), headers=HEADERS, timeout=120)
response.raise_for_status()
if "zip" not in response.headers.get("Content-Type", "").lower():
raise RuntimeError(f"Expected ZIP, got {response.headers.get('Content-Type')!r}")
zip_path.write_bytes(response.content)

extracted = work_dir / "extracted"
extracted.mkdir(exist_ok=True)
with ZipFile(zip_path) as archive:
archive.extractall(extracted)

files = sorted(path for path in extracted.iterdir() if path.is_file())
print("files:", len(files))
for path in files:
print(f"{path.name}\t{path.stat().st_size} bytes")

region_file = next(
(path for path in files if path.name == f"НП_{YEAR}_{REGION_FRAGMENT}.xls"),
None,
)
if region_file is None:
raise FileNotFoundError(f"No file for {REGION_FRAGMENT!r}; see printed archive list")
if region_file.suffix.lower() != ".xls":
raise RuntimeError(f"Unexpected format: {region_file.name}")

# Файлы endpoint за проверенные годы — BIFF8 .xls, поэтому нужен xlrd, не openpyxl.
engine = "xlrd"
excel = pd.ExcelFile(region_file, engine=engine)
print("selected:", region_file.name)
print("sheets:", excel.sheet_names)

# pandas читает скрытые строки тоже. Ищем именно строку с двумя исходными заголовками,
# а не фиксированный номер: в Раздел2 это 13-я строка в 2014 и 4-я в 2024.
raw = pd.read_excel(region_file, sheet_name=SHEET, header=None, dtype=object, engine=engine)
matches = raw.index[
raw.iloc[:, 0].astype("string").str.strip().eq("ПОКАЗАТЕЛЬ")
& raw.iloc[:, 1].astype("string").str.strip().eq("Код строки")
]
if len(matches) != 1:
raise RuntimeError(f"Cannot identify one header row in {SHEET}: {matches.tolist()}")
header_row = int(matches[0]) # zero-based for pandas; 3 for 2024, 12 for 2014
print("header_row_zero_based:", header_row)

table = pd.read_excel(
region_file, sheet_name=SHEET, header=header_row, dtype=object, engine=engine
).dropna(how="all")


def normalise_column(value: object) -> str:
label = str(value).strip()
if label == "ПОКАЗАТЕЛЬ":
return "indicator_label"
if label == "Код строки":
return "row_code"
year_match = re.fullmatch(r"(\d{4}) год", label)
if year_match:
return f"value_{year_match.group(1)}"
if label == "В % к предыдущему году":
return "pct_to_previous_year"
raise ValueError(f"Unexpected {SHEET} column: {label!r}")


def normalise_row_code(value: object) -> str | None:
if pd.isna(value):
return None
text = str(value).strip()
# Excel may return an integer code as 201.0; decimal template codes such as 530.1 remain.
if re.fullmatch(r"-?\d+\.0+", text):
text = text.split(".", 1)[0]
return text or None


table.columns = [normalise_column(column) for column in table.columns]
table["row_code"] = table["row_code"].map(normalise_row_code)
table["indicator_label"] = table["indicator_label"].astype("string").str.strip()

# Убираем строку 1/2/3/4 и контекстные заголовки «в том числе», у которых нет кода.
table = table.loc[
table["row_code"].str.fullmatch(r"-?\d+(?:\.\d+)?", na=False)
& ~table["indicator_label"].str.fullmatch(r"\d+", na=False)
].copy()

value_column = next(column for column in table.columns if column.startswith("value_"))
table[f"{value_column}_raw"] = table[value_column].astype("string")
table["pct_to_previous_year_raw"] = table["pct_to_previous_year"].astype("string")
table[value_column] = pd.to_numeric(table[value_column], errors="coerce")
table["pct_to_previous_year"] = pd.to_numeric(
table["pct_to_previous_year"], errors="coerce"
)
table.insert(0, "year", YEAR)
table.insert(1, "file_label", REGION_FRAGMENT)
table.insert(2, "sheet_name", SHEET)

key = ["year", "file_label", "sheet_name", "row_code"]
duplicates = table.duplicated(key, keep=False)
print("rows after filtering:", len(table))
print("dtypes:\n", table.dtypes)
print("potential-key duplicates:", int(duplicates.sum()))
print(table.head(5).to_string(index=False))

try:
import pyarrow # noqa: F401
except ImportError:
output = work_dir / f"{region_file.stem}-{SHEET}.csv"
table.to_csv(output, index=False)
else:
output = work_dir / f"{region_file.stem}-{SHEET}.parquet"
table.to_parquet(output, index=False)
print("saved:", output)

Для Раздел5, Раздел6, Раздел7, Раздел10 и Раздел11 не передавайте несколько строк шапки непосредственно как header=: сначала прочитайте header=None, заполните значения merged cells, соберите путь заголовка через →, затем начните данные после строки с номерами колонок. Точные номера строк и итоговые имена колонок для обоих проверенных шаблонов даны в машиночитаемом профиле.

Связанные страницы wiki​

Не путать с​

  • Налоговая статистика ФНС — прежде всего скачиваемые формы (XLS/XLSX) на nalog.gov.ru; паспорта регионов на analytic.nalog.gov.ru — отдельный комплект таблиц с иной компоновкой.
  • Открытые данные на nalog.gov.ru — каталог наборов с машиночитаемыми форматами по паспортам; не смешивать с ZIP-выгрузкой паспортов субъектов с аналитического портала.