{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Класс для объединения множества однотипных файлов excel в один набор данных\n",
    "----------\n",
    "\n",
    "Постановка задачи (что наш класс должен уметь):\n",
    "  - собирать файлы:\n",
    "    - из файловой системы по маске;\n",
    "    - с веб-сервера (может быть даже с предварительной авторизацией);\n",
    "    - скачивать и доставать книги из архивов, в т.ч. если в архиве много однотипных файлов;\n",
    "  - объединять таблицы с данными:\n",
    "    - из определённых листов загружаемых книг (например первый лист каждой книги)\n",
    "    - перебирая все рабочие листы всех загружаемых книг\n",
    "  - добавлять в итоговый набор произвольное количество колонок, идентифицирующих источник:\n",
    "    - название файла;\n",
    "    - название рабочего листа;\n",
    "    - произвольные ячейки каждого рабочего листа, например заголовок или подпись ответственного лица, даты и т.д.\n",
    "  - выводить получаемый набор в выбранном формате:\n",
    "    - DataFrame;\n",
    "    - генератор словарей;\n",
    "    - генератор NamedTyple;\n",
    "    - записывать в csv или базу данных."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1. Установка и импорт зависимостей"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Requirement already satisfied: pandas in c:\\dev\\.jupyter\\.venv\\lib\\site-packages (1.0.1)\n",
      "Requirement already satisfied: openpyxl in c:\\dev\\.jupyter\\.venv\\lib\\site-packages (3.0.3)\n",
      "Requirement already satisfied: xlrd in c:\\dev\\.jupyter\\.venv\\lib\\site-packages (1.2.0)\n",
      "Requirement already satisfied: chardet in c:\\dev\\.jupyter\\.venv\\lib\\site-packages (3.0.4)\n",
      "Requirement already satisfied: rarfile in c:\\dev\\.jupyter\\.venv\\lib\\site-packages (3.1)\n",
      "Requirement already satisfied: pytz>=2017.2 in c:\\dev\\.jupyter\\.venv\\lib\\site-packages (from pandas) (2019.3)\n",
      "Requirement already satisfied: python-dateutil>=2.6.1 in c:\\dev\\.jupyter\\.venv\\lib\\site-packages (from pandas) (2.8.1)\n",
      "Requirement already satisfied: numpy>=1.13.3 in c:\\dev\\.jupyter\\.venv\\lib\\site-packages (from pandas) (1.18.1)\n",
      "Requirement already satisfied: jdcal in c:\\dev\\.jupyter\\.venv\\lib\\site-packages (from openpyxl) (1.4.1)\n",
      "Requirement already satisfied: et_xmlfile in c:\\dev\\.jupyter\\.venv\\lib\\site-packages (from openpyxl) (1.0.1)\n",
      "Requirement already satisfied: six>=1.5 in c:\\dev\\.jupyter\\.venv\\lib\\site-packages (from python-dateutil>=2.6.1->pandas) (1.14.0)\n"
     ]
    }
   ],
   "source": [
    "!pip install pandas openpyxl xlrd chardet rarfile"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "import sys\n",
    "import glob\n",
    "import re\n",
    "from itertools import islice\n",
    "from collections.abc import Iterable\n",
    "from urllib.parse import urlparse\n",
    "from urllib.request import urlopen\n",
    "from pathlib import Path\n",
    "\n",
    "import pandas as pd\n",
    "import openpyxl"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Объявление класса"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "class ExcelPreprocessor:\n",
    "    def __init__(self, *wb, append_global_index=False, append_wb_index=False, \n",
    "                 filename_parser=None, append_ws_title_column=False, first_row_number=1,\n",
    "                 iterate_over_worksheet=0, cells=None, headers=None, in_archive_re_mask=None):\n",
    "        '''\n",
    "        параметр iterate_over_worksheet отвечает за то, какой именно рабочий лист в каждой прочитанной\n",
    "        книге будет разобран по умолчанию это лист с индексом 0, т.е. 1 в списке.\n",
    "        Номера листов можно задать списком, например [4, 5] (пятый и шестой соответственно)\n",
    "        также можно указать \"ALL\" или True, тогда будут прочитаны все листы всех книг\n",
    "        и данные из них объединены в один набор\n",
    "        '''\n",
    "        self.wb = []\n",
    "        for w in wb:\n",
    "            if isinstance(w, list):\n",
    "                self.wb += w\n",
    "            elif isinstance(w, str):\n",
    "                self.wb += [w]\n",
    "            else:\n",
    "                raise Exception(f'the \"{w}\" is of type {type(w)}, need list or str')\n",
    "\n",
    "        self.global_index = append_global_index\n",
    "        self.wb_index = append_wb_index\n",
    "        self.filename_parser = filename_parser\n",
    "        self.append_ws_title_column = append_ws_title_column\n",
    "        self.first_row_number = first_row_number\n",
    "        self.iterate_over_worksheet = iterate_over_worksheet\n",
    "        self.cells = cells\n",
    "        self.headers = headers\n",
    "        self.in_archive_re_mask = in_archive_re_mask\n",
    "\n",
    "    def __repr__(self):\n",
    "        return f'''{ExcelPreprocessor.__name__}{self.wb}:\n",
    "          add global index: {self.global_index}\n",
    "          add workbook index: {self.wb_index}\n",
    "          filename parser: {self.filename_parser}\n",
    "          append worksheet title: {self.append_ws_title_column}\n",
    "          first row number in worksheet: {self.first_row_number}\n",
    "          worksheets in all wb to iterate: {self.iterate_over_worksheet}\n",
    "          cells: {self.cells}\n",
    "          headers: {self.headers}'''\n",
    "\n",
    "    @property\n",
    "    def _process_files(self):\n",
    "        '''\n",
    "        обрабатывает файлы в списке\n",
    "        принимает обычные файлы, zip-архивы и http - пути\n",
    "        '''\n",
    "        for filename in self.wb:\n",
    "            rf = filename\n",
    "            if filename.startswith('http'):\n",
    "                import io\n",
    "                with urlopen(filename) as resp:\n",
    "                    rf = io.BytesIO(resp.read())\n",
    "                    if filename.endswith('.xlsx'):\n",
    "                        yield filename, rf\n",
    "            elif filename.endswith('xlsx'):\n",
    "                yield filename, open(filename, 'rb')\n",
    "\n",
    "            if filename.endswith('.zip'):\n",
    "                from zipfile import ZipFile\n",
    "                import chardet\n",
    "                ZIP_FILENAME_UTF8_FLAG = 0x800\n",
    "                zf = ZipFile(rf , 'r')\n",
    "                print(filename)\n",
    "                for info in zf.filelist:\n",
    "                    zfilename = info.filename\n",
    "                    if not zfilename.endswith('.xlsx'):\n",
    "                        continue\n",
    "                    if info.flag_bits & ZIP_FILENAME_UTF8_FLAG == 0:\n",
    "                        filename_bytes = zfilename.encode('437')\n",
    "                        guessed_encoding = chardet.detect(filename_bytes)['encoding'] or 'cp1252'\n",
    "                        zfilename = filename_bytes.decode(guessed_encoding, 'replace')\n",
    "                        if self.in_archive_re_mask:\n",
    "                            if not re.match(self.in_archive_re_mask, zfilename):\n",
    "                                continue\n",
    "                        yield str(Path(filename) / Path(zfilename)), zf.open(info.filename, 'r')\n",
    "\n",
    "            if filename.endswith('.rar'):\n",
    "                from rarfile import RarFile\n",
    "                rf = rarfile.RarFile(rar_fn, 'r')\n",
    "                for f in rf.infolist():\n",
    "                    print(f.filename, f.file_size)\n",
    "                    if f.filename == 'README':\n",
    "                        print(rf.read(f))\n",
    "\n",
    "    @property\n",
    "    def _columns(self):\n",
    "        columns = []\n",
    "        if self.global_index:\n",
    "            columns.append('global_index')\n",
    "        if self.wb_index:\n",
    "            columns.append('ws_index')\n",
    "        if self.filename_parser:\n",
    "            columns += self.filename_parser(self.wb[0]).keys()\n",
    "        if self.append_ws_title_column:\n",
    "            columns.append('ws_title')\n",
    "        if self.cells:\n",
    "            columns += self.cells.keys()\n",
    "        if self.headers:\n",
    "            columns += self.headers\n",
    "        return columns\n",
    "\n",
    "    def _iter_over_rows(self):\n",
    "        'итерация по общей последовательности строк в итоговом наборе'\n",
    "\n",
    "        row_counter = 0\n",
    "\n",
    "        for fn, excel_file in self._process_files:\n",
    "            wb = openpyxl.load_workbook(excel_file, read_only=True, data_only=False, keep_links=False)\n",
    "\n",
    "            if isinstance(self.iterate_over_worksheet, int):\n",
    "                iter_sheet = [self.iterate_over_worksheet]\n",
    "            elif isinstance(self.iterate_over_worksheet, list) or isinstance(self.iterate_over_worksheet, tuple):\n",
    "                iter_sheet = self.iterate_over_worksheet\n",
    "            else:\n",
    "                iter_sheet = [i for i, ws in enumerate(wb.worksheets) if not ws.title.startswith('hidden')]\n",
    "\n",
    "            for ws_index in iter_sheet:\n",
    "                ws = wb.worksheets[ws_index]\n",
    "                result = ((cell.value for cell in row) for row in ws.rows)\n",
    "\n",
    "                if self.first_row_number:\n",
    "                    result = islice(result, self.first_row_number - 1, None)\n",
    "                if self.cells:\n",
    "                    retry_cols_values = [ws[c].value for c in self.cells.values()]\n",
    "                    result = ((*retry_cols_values, *row) for row in result)\n",
    "                if self.append_ws_title_column:\n",
    "                    result = ((ws.title, *row) for row in result)\n",
    "                if self.filename_parser:\n",
    "                    fncols = self.filename_parser(fn)\n",
    "                    result = ((*fncols.values(), *row) for row in result)\n",
    "                if self.wb_index:\n",
    "                    result = ((i, *row) for i, row in enumerate(result))\n",
    "                if self.global_index:\n",
    "                    result = ((row_counter, *row) for i, row in enumerate(result))\n",
    "                for row in result:\n",
    "                    yield row\n",
    "                    row_counter += 1\n",
    "\n",
    "    def get_dataframe(self):\n",
    "        'возвращает набор данных в виде pandas DataFrame'\n",
    "        data = ([val for col, val in zip(self._columns, row)] for row in self._iter_over_rows())\n",
    "        return pd.DataFrame(data, columns=self._columns)\n",
    "\n",
    "    def write_csv(self, csv_filename, write_header=True, dialect='excel', **fmtparams):\n",
    "        '''\n",
    "        записывает набор данных в файл csv, входные параметры такие же как у метода csv.writer\n",
    "        https://docs.python.org/3/library/csv.html\n",
    "        '''\n",
    "        import csv\n",
    "        with open(csv_filename, 'w', encoding='utf8') as wf:\n",
    "            writer = csv.writer(wf, dialect, **fmtparams)\n",
    "            writer.writerow(self._columns)\n",
    "            writer.writerows(self._iter_over_rows())\n",
    "\n",
    "    def write_excel(self, excel_filename):\n",
    "        'записывает набор данных в файл excel'\n",
    "        from openpyxl import Workbook\n",
    "        wb = Workbook(write_only=True)\n",
    "        ws = wb.create_sheet()\n",
    "        ws.append(self._columns)\n",
    "        for row in self._iter_over_rows():\n",
    "            ws.append(row)\n",
    "        wb.save(excel_filename)\n",
    "\n",
    "    def get_iter_dict(self):\n",
    "        'возвращает набор данных в виде итератора словарей'\n",
    "        cols = self._columns\n",
    "        for row in self._iter_over_rows():\n",
    "            yield {k:v for k, v in zip(cols, row)}\n",
    "\n",
    "    def get_iter_nt(self):\n",
    "        'возвращает набор данных в виде итерируемого набора NamedTyple'\n",
    "        from collections import namedtuple\n",
    "        cols = self._columns\n",
    "        nt = namedtuple(\"Row\", [re.sub(r\"[\\. \\(\\)]\", \"_\", c).lower() for c in cols])\n",
    "        for row in self._iter_over_rows():\n",
    "            yield nt(*row)\n",
    "\n",
    "    def get_sample(self, start, stop):\n",
    "        'возвращает сэмпл итогового набора (можно проверить правильность обработки данных)'\n",
    "        return [list(row) for row in islice(self._iter_over_rows(), start, stop)]\n",
    "    \n",
    "    def get_sample_dataframe(self, start, stop) -> pd.DataFrame:\n",
    "        'возвращает сэмпл итогового набора в виде DataFrame'\n",
    "        data = ([val for col, val in zip(self._columns, row)] for row in islice(self._iter_over_rows(), start, stop))\n",
    "        return pd.DataFrame(data, columns=self._columns)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "ExcelPreprocessor['data\\\\2009\\\\4nm010618.xlsx', 'data\\\\2008\\\\4nm011118.xlsx']:\n",
       "          add global index: False\n",
       "          add workbook index: False\n",
       "          filename parser: None\n",
       "          append worksheet title: False\n",
       "          first row number in worksheet: 1\n",
       "          worksheets in all wb to iterate: 0\n",
       "          cells: None\n",
       "          headers: None"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# создаем экземпляр класса и смотрим что получается\n",
    "processor = ExcelPreprocessor('data\\\\2009\\\\4nm010618.xlsx', 'data\\\\2008\\\\4nm011118.xlsx')\n",
    "processor"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[None, 'Код стро-ки', 'Всего ', 'из графы 1 по :', None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None]\n",
      "[None, None, None, 'федеральным налогам и сборам', None, None, None, None, None, None, None, 'региональным налогам и сборам', 'местным налогам и сборам', 'налогам со специальным налоговым режимом', 'Единому социальному налогу', 'Из графы 13 единый социальный налог в федеральный бюджет', 'Платежам в государственные внебюджетные фонды', 'ВСЕГО задолженность по страховым взносам', None, None, None, None, None, None]\n",
      "[None, None, None, 'Всего ', 'из них', None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None]\n",
      "[None, None, None, None, 'налог на прибыль организаций', None, 'налог на добавленную стоимость ', 'из графы 5 налог на добавленную стоимость по товарам (работам, услугам), реализуемым на территории РФ', 'платежи за пользование природными ресурсами ', 'из графы 7\\n налог на добычу полезных ископаемых', 'остальные федеральные налоги и сборы', None, None, None, None, None, None, None, None, None, None, None, None, None]\n",
      "[None, None, None, None, 'Всего ', 'в том числе в федеральный бюджет', None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None]\n",
      "['А', 'Б', 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, None, None, None, None, None, None]\n"
     ]
    }
   ],
   "source": [
    "# попробуем получить кусочек данных например с 5 по 8 строку и посмотреть что получается\n",
    "for row in processor.get_sample(5, 11):\n",
    "    print(row)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['Уточненные данные по состоянию на 16.07.2018\\n', 'ЗАДОЛЖЕННОСТЬ - ВСЕГО (стр.1010+стр.1045+стр.1093)', 1005, 1235462116, 613079956, 137068882, 16509931, 378521695, 377407864, 7475610, 7001696, 90013769, 152239095, 76851905, 52246651, 4059156, 2911250, 892339, 336093014, None, None, None, None, None, None]\n",
      "['Уточненные данные по состоянию на 16.07.2018\\n', 'ЗАДОЛЖЕННОСТЬ ПЕРЕД БЮДЖЕТОМ ПО НАЛОГАМ, СБОРАМ, ПЕНЯМ, НАЛОГОВЫМ САНКЦИЯМ ВСЕГО В ТОМ ЧИСЛЕ:', 1010, 966783423, 470685208, 102647180, 12435295, 293731518, 292643494, 6239798, 6015450, 68066712, 122048711, 66194027, 50606745, 2990596, 2027362, 838342, 253419794, None, None, None, None, None, None]\n",
      "['Уточненные данные по состоянию на 16.07.2018\\n', 'из нее\\nзадолженность, невозможная к взысканию в связи с отложением подачи заявления в арбитражный суд о признании должника банкротом', 1011, 59789575, 45827009, 6993023, 772092, 33088224, 32865309, 70488, 41193, 5675274, 369196, 357281, 3524787, 92613, 75241, 41612, 9577077, None, None, None, None, None, None]\n",
      "['Уточненные данные по состоянию на 16.07.2018\\n', 'НЕДОИМКА', 1020, 738863445, 350780985, 76405303, 9214666, 221615329, 220703752, 5920609, 5756088, 46839744, 98789604, 54482333, 37990418, 896167, 605705, 190163, 195733775, None, None, None, None, None, None]\n"
     ]
    }
   ],
   "source": [
    "# Видим что данные начинаются только с 12 строки, к тому же нам надо добавить\n",
    "# в каждую строку информацию из ячейки \"A1\", назовём её \"date_ot\"\n",
    "processor.cells = {'date_ot': 'A1'}\n",
    "processor.first_row_number = 12\n",
    "for row in processor.get_sample(0, 4):\n",
    "    print(row)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['2009', '4nm010618', 'xlsx', 'Уточненные данные по состоянию на 16.07.2018\\n', 'ЗАДОЛЖЕННОСТЬ - ВСЕГО (стр.1010+стр.1045+стр.1093)', 1005, 1235462116, 613079956, 137068882, 16509931, 378521695, 377407864, 7475610, 7001696, 90013769, 152239095, 76851905, 52246651, 4059156, 2911250, 892339, 336093014, None, None, None, None, None, None]\n",
      "['2009', '4nm010618', 'xlsx', 'Уточненные данные по состоянию на 16.07.2018\\n', 'ЗАДОЛЖЕННОСТЬ ПЕРЕД БЮДЖЕТОМ ПО НАЛОГАМ, СБОРАМ, ПЕНЯМ, НАЛОГОВЫМ САНКЦИЯМ ВСЕГО В ТОМ ЧИСЛЕ:', 1010, 966783423, 470685208, 102647180, 12435295, 293731518, 292643494, 6239798, 6015450, 68066712, 122048711, 66194027, 50606745, 2990596, 2027362, 838342, 253419794, None, None, None, None, None, None]\n",
      "['2009', '4nm010618', 'xlsx', 'Уточненные данные по состоянию на 16.07.2018\\n', 'из нее\\nзадолженность, невозможная к взысканию в связи с отложением подачи заявления в арбитражный суд о признании должника банкротом', 1011, 59789575, 45827009, 6993023, 772092, 33088224, 32865309, 70488, 41193, 5675274, 369196, 357281, 3524787, 92613, 75241, 41612, 9577077, None, None, None, None, None, None]\n",
      "['2009', '4nm010618', 'xlsx', 'Уточненные данные по состоянию на 16.07.2018\\n', 'НЕДОИМКА', 1020, 738863445, 350780985, 76405303, 9214666, 221615329, 220703752, 5920609, 5756088, 46839744, 98789604, 54482333, 37990418, 896167, 605705, 190163, 195733775, None, None, None, None, None, None]\n"
     ]
    }
   ],
   "source": [
    "# добавим функцию для того чтобы извлечь из имён файлов полезную информацию и потом добавить её в наш набор данных\n",
    "# один файл выглядит так: 'data\\\\2009\\\\4nm010618.xlsx'\n",
    "# сделаем функцию, которая принимает название файла в таком формате и регулярным выражением возвращает год, название файла и его расширение\n",
    "\n",
    "def parse_filename(filename):\n",
    "    rstring = r'data\\\\(?P<year>\\w+)\\\\(?P<filename>\\w+)\\.(?P<extension>\\w+)'\n",
    "    r = re.match(rstring, filename)\n",
    "    return r.groupdict()\n",
    "\n",
    "processor.filename_parser = parse_filename\n",
    "for row in processor.get_sample(0, 4):\n",
    "    print(row)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[0, 0, '2009', '4nm010618', 'xlsx', 'P1', 'Уточненные данные по состоянию на 16.07.2018\\n', 'ЗАДОЛЖЕННОСТЬ - ВСЕГО (стр.1010+стр.1045+стр.1093)', 1005, 1235462116, 613079956, 137068882, 16509931, 378521695, 377407864, 7475610, 7001696, 90013769, 152239095, 76851905, 52246651, 4059156, 2911250, 892339, 336093014, None, None, None, None, None, None]\n",
      "[1, 1, '2009', '4nm010618', 'xlsx', 'P1', 'Уточненные данные по состоянию на 16.07.2018\\n', 'ЗАДОЛЖЕННОСТЬ ПЕРЕД БЮДЖЕТОМ ПО НАЛОГАМ, СБОРАМ, ПЕНЯМ, НАЛОГОВЫМ САНКЦИЯМ ВСЕГО В ТОМ ЧИСЛЕ:', 1010, 966783423, 470685208, 102647180, 12435295, 293731518, 292643494, 6239798, 6015450, 68066712, 122048711, 66194027, 50606745, 2990596, 2027362, 838342, 253419794, None, None, None, None, None, None]\n",
      "[2, 2, '2009', '4nm010618', 'xlsx', 'P1', 'Уточненные данные по состоянию на 16.07.2018\\n', 'из нее\\nзадолженность, невозможная к взысканию в связи с отложением подачи заявления в арбитражный суд о признании должника банкротом', 1011, 59789575, 45827009, 6993023, 772092, 33088224, 32865309, 70488, 41193, 5675274, 369196, 357281, 3524787, 92613, 75241, 41612, 9577077, None, None, None, None, None, None]\n",
      "[3, 3, '2009', '4nm010618', 'xlsx', 'P1', 'Уточненные данные по состоянию на 16.07.2018\\n', 'НЕДОИМКА', 1020, 738863445, 350780985, 76405303, 9214666, 221615329, 220703752, 5920609, 5756088, 46839744, 98789604, 54482333, 37990418, 896167, 605705, 190163, 195733775, None, None, None, None, None, None]\n"
     ]
    }
   ],
   "source": [
    "# теперь добавим в наш результируюший набор поле сквозного индекса\n",
    "# и отдельный индекс по каждому рабочему листу, что нам попадётся\n",
    "processor.global_index = True\n",
    "processor.wb_index = True\n",
    "# также нелишним будет добавить и колонку с заголовком рабочего листа с которого получены данные\n",
    "processor.append_ws_title_column = True\n",
    "for row in processor.get_sample(0, 4):\n",
    "    print(row)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'global_index': 0, 'ws_index': 0, 'year': '2009', 'filename': '4nm010618', 'extension': 'xlsx', 'ws_title': 'P1', 'date_ot': 'Уточненные данные по состоянию на 16.07.2018\\n'}\n",
      "{'global_index': 1, 'ws_index': 1, 'year': '2009', 'filename': '4nm010618', 'extension': 'xlsx', 'ws_title': 'P1', 'date_ot': 'Уточненные данные по состоянию на 16.07.2018\\n'}\n",
      "{'global_index': 2, 'ws_index': 2, 'year': '2009', 'filename': '4nm010618', 'extension': 'xlsx', 'ws_title': 'P1', 'date_ot': 'Уточненные данные по состоянию на 16.07.2018\\n'}\n",
      "{'global_index': 3, 'ws_index': 3, 'year': '2009', 'filename': '4nm010618', 'extension': 'xlsx', 'ws_title': 'P1', 'date_ot': 'Уточненные данные по состоянию на 16.07.2018\\n'}\n",
      "{'global_index': 4, 'ws_index': 4, 'year': '2009', 'filename': '4nm010618', 'extension': 'xlsx', 'ws_title': 'P1', 'date_ot': 'Уточненные данные по состоянию на 16.07.2018\\n'}\n"
     ]
    }
   ],
   "source": [
    "# посмотрим то же самое в формате набора словарей:\n",
    "for row in islice(processor.get_iter_dict(), 0, 5):\n",
    "    print(row)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'global_index': 0, 'ws_index': 0, 'year': '2009', 'filename': '4nm010618', 'extension': 'xlsx', 'ws_title': 'P1', 'date_ot': 'Уточненные данные по состоянию на 16.07.2018\\n', 'поле': 'ЗАДОЛЖЕННОСТЬ - ВСЕГО (стр.1010+стр.1045+стр.1093)', 'код строки': 1005, 'кол. налогоплательщиков': 1235462116, 'всего': 613079956, 'по налогу (сбору)': 137068882, 'по пени': 16509931, 'по штрафам': 378521695, 'проценты': 377407864, 'по ЕСН': 7475610, 'по страховым взносам': 7001696}\n",
      "{'global_index': 1, 'ws_index': 1, 'year': '2009', 'filename': '4nm010618', 'extension': 'xlsx', 'ws_title': 'P1', 'date_ot': 'Уточненные данные по состоянию на 16.07.2018\\n', 'поле': 'ЗАДОЛЖЕННОСТЬ ПЕРЕД БЮДЖЕТОМ ПО НАЛОГАМ, СБОРАМ, ПЕНЯМ, НАЛОГОВЫМ САНКЦИЯМ ВСЕГО В ТОМ ЧИСЛЕ:', 'код строки': 1010, 'кол. налогоплательщиков': 966783423, 'всего': 470685208, 'по налогу (сбору)': 102647180, 'по пени': 12435295, 'по штрафам': 293731518, 'проценты': 292643494, 'по ЕСН': 6239798, 'по страховым взносам': 6015450}\n",
      "{'global_index': 2, 'ws_index': 2, 'year': '2009', 'filename': '4nm010618', 'extension': 'xlsx', 'ws_title': 'P1', 'date_ot': 'Уточненные данные по состоянию на 16.07.2018\\n', 'поле': 'из нее\\nзадолженность, невозможная к взысканию в связи с отложением подачи заявления в арбитражный суд о признании должника банкротом', 'код строки': 1011, 'кол. налогоплательщиков': 59789575, 'всего': 45827009, 'по налогу (сбору)': 6993023, 'по пени': 772092, 'по штрафам': 33088224, 'проценты': 32865309, 'по ЕСН': 70488, 'по страховым взносам': 41193}\n",
      "{'global_index': 3, 'ws_index': 3, 'year': '2009', 'filename': '4nm010618', 'extension': 'xlsx', 'ws_title': 'P1', 'date_ot': 'Уточненные данные по состоянию на 16.07.2018\\n', 'поле': 'НЕДОИМКА', 'код строки': 1020, 'кол. налогоплательщиков': 738863445, 'всего': 350780985, 'по налогу (сбору)': 76405303, 'по пени': 9214666, 'по штрафам': 221615329, 'проценты': 220703752, 'по ЕСН': 5920609, 'по страховым взносам': 5756088}\n",
      "{'global_index': 4, 'ws_index': 4, 'year': '2009', 'filename': '4nm010618', 'extension': 'xlsx', 'ws_title': 'P1', 'date_ot': 'Уточненные данные по состоянию на 16.07.2018\\n', 'поле': '\\nИз строки 1020\\nНЕДОИМКА ОРГАНИЗАЦИЙ И ИНДИВИДУАЛЬНЫХ ПРЕДПРИНИМАТЕЛЕЙ, НЕ ПРЕДСТАВЛЯЮЩИХ ОТЧЕТНОСТЬ', 'код строки': 1030, 'кол. налогоплательщиков': 105337216, 'всего': 68231581, 'по налогу (сбору)': 16344932, 'по пени': 1759494, 'по штрафам': 47161217, 'проценты': 47056987, 'по ЕСН': 36418, 'по страховым взносам': 27229}\n"
     ]
    }
   ],
   "source": [
    "# видно что не хватает колонок, т.к. не задан параметр \"headers\". исправим это\n",
    "processor.headers = [\n",
    "    'поле', 'код строки', 'кол. налогоплательщиков', 'всего', 'по налогу (сбору)',\n",
    "    'по пени', 'по штрафам', 'проценты', 'по ЕСН', 'по страховым взносам'\n",
    "]\n",
    "for row in islice(processor.get_iter_dict(), 0, 5):\n",
    "    print(row)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>global_index</th>\n",
       "      <th>ws_index</th>\n",
       "      <th>year</th>\n",
       "      <th>filename</th>\n",
       "      <th>extension</th>\n",
       "      <th>ws_title</th>\n",
       "      <th>date_ot</th>\n",
       "      <th>поле</th>\n",
       "      <th>код строки</th>\n",
       "      <th>кол. налогоплательщиков</th>\n",
       "      <th>всего</th>\n",
       "      <th>по налогу (сбору)</th>\n",
       "      <th>по пени</th>\n",
       "      <th>по штрафам</th>\n",
       "      <th>проценты</th>\n",
       "      <th>по ЕСН</th>\n",
       "      <th>по страховым взносам</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>2009</td>\n",
       "      <td>4nm010618</td>\n",
       "      <td>xlsx</td>\n",
       "      <td>P1</td>\n",
       "      <td>Уточненные данные по состоянию на 16.07.2018\\n</td>\n",
       "      <td>ЗАДОЛЖЕННОСТЬ - ВСЕГО (стр.1010+стр.1045+стр.1...</td>\n",
       "      <td>1005</td>\n",
       "      <td>1235462116</td>\n",
       "      <td>613079956</td>\n",
       "      <td>137068882</td>\n",
       "      <td>16509931</td>\n",
       "      <td>378521695</td>\n",
       "      <td>377407864</td>\n",
       "      <td>7475610</td>\n",
       "      <td>7001696</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>2009</td>\n",
       "      <td>4nm010618</td>\n",
       "      <td>xlsx</td>\n",
       "      <td>P1</td>\n",
       "      <td>Уточненные данные по состоянию на 16.07.2018\\n</td>\n",
       "      <td>ЗАДОЛЖЕННОСТЬ ПЕРЕД БЮДЖЕТОМ ПО НАЛОГАМ, СБОРА...</td>\n",
       "      <td>1010</td>\n",
       "      <td>966783423</td>\n",
       "      <td>470685208</td>\n",
       "      <td>102647180</td>\n",
       "      <td>12435295</td>\n",
       "      <td>293731518</td>\n",
       "      <td>292643494</td>\n",
       "      <td>6239798</td>\n",
       "      <td>6015450</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>2</td>\n",
       "      <td>2</td>\n",
       "      <td>2009</td>\n",
       "      <td>4nm010618</td>\n",
       "      <td>xlsx</td>\n",
       "      <td>P1</td>\n",
       "      <td>Уточненные данные по состоянию на 16.07.2018\\n</td>\n",
       "      <td>из нее\\nзадолженность, невозможная к взысканию...</td>\n",
       "      <td>1011</td>\n",
       "      <td>59789575</td>\n",
       "      <td>45827009</td>\n",
       "      <td>6993023</td>\n",
       "      <td>772092</td>\n",
       "      <td>33088224</td>\n",
       "      <td>32865309</td>\n",
       "      <td>70488</td>\n",
       "      <td>41193</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>3</td>\n",
       "      <td>3</td>\n",
       "      <td>2009</td>\n",
       "      <td>4nm010618</td>\n",
       "      <td>xlsx</td>\n",
       "      <td>P1</td>\n",
       "      <td>Уточненные данные по состоянию на 16.07.2018\\n</td>\n",
       "      <td>НЕДОИМКА</td>\n",
       "      <td>1020</td>\n",
       "      <td>738863445</td>\n",
       "      <td>350780985</td>\n",
       "      <td>76405303</td>\n",
       "      <td>9214666</td>\n",
       "      <td>221615329</td>\n",
       "      <td>220703752</td>\n",
       "      <td>5920609</td>\n",
       "      <td>5756088</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>4</td>\n",
       "      <td>4</td>\n",
       "      <td>2009</td>\n",
       "      <td>4nm010618</td>\n",
       "      <td>xlsx</td>\n",
       "      <td>P1</td>\n",
       "      <td>Уточненные данные по состоянию на 16.07.2018\\n</td>\n",
       "      <td>\\nИз строки 1020\\nНЕДОИМКА ОРГАНИЗАЦИЙ И ИНДИВ...</td>\n",
       "      <td>1030</td>\n",
       "      <td>105337216</td>\n",
       "      <td>68231581</td>\n",
       "      <td>16344932</td>\n",
       "      <td>1759494</td>\n",
       "      <td>47161217</td>\n",
       "      <td>47056987</td>\n",
       "      <td>36418</td>\n",
       "      <td>27229</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   global_index  ws_index  year   filename extension ws_title  \\\n",
       "0             0         0  2009  4nm010618      xlsx       P1   \n",
       "1             1         1  2009  4nm010618      xlsx       P1   \n",
       "2             2         2  2009  4nm010618      xlsx       P1   \n",
       "3             3         3  2009  4nm010618      xlsx       P1   \n",
       "4             4         4  2009  4nm010618      xlsx       P1   \n",
       "\n",
       "                                          date_ot  \\\n",
       "0  Уточненные данные по состоянию на 16.07.2018\\n   \n",
       "1  Уточненные данные по состоянию на 16.07.2018\\n   \n",
       "2  Уточненные данные по состоянию на 16.07.2018\\n   \n",
       "3  Уточненные данные по состоянию на 16.07.2018\\n   \n",
       "4  Уточненные данные по состоянию на 16.07.2018\\n   \n",
       "\n",
       "                                                поле  код строки  \\\n",
       "0  ЗАДОЛЖЕННОСТЬ - ВСЕГО (стр.1010+стр.1045+стр.1...        1005   \n",
       "1  ЗАДОЛЖЕННОСТЬ ПЕРЕД БЮДЖЕТОМ ПО НАЛОГАМ, СБОРА...        1010   \n",
       "2  из нее\\nзадолженность, невозможная к взысканию...        1011   \n",
       "3                                           НЕДОИМКА        1020   \n",
       "4  \\nИз строки 1020\\nНЕДОИМКА ОРГАНИЗАЦИЙ И ИНДИВ...        1030   \n",
       "\n",
       "   кол. налогоплательщиков      всего  по налогу (сбору)   по пени  \\\n",
       "0               1235462116  613079956          137068882  16509931   \n",
       "1                966783423  470685208          102647180  12435295   \n",
       "2                 59789575   45827009            6993023    772092   \n",
       "3                738863445  350780985           76405303   9214666   \n",
       "4                105337216   68231581           16344932   1759494   \n",
       "\n",
       "   по штрафам   проценты   по ЕСН  по страховым взносам  \n",
       "0   378521695  377407864  7475610               7001696  \n",
       "1   293731518  292643494  6239798               6015450  \n",
       "2    33088224   32865309    70488                 41193  \n",
       "3   221615329  220703752  5920609               5756088  \n",
       "4    47161217   47056987    36418                 27229  "
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# попробуем то же самое в виде DataFrame\n",
    "processor.get_sample_dataframe(0, 5)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>global_index</th>\n",
       "      <th>ws_index</th>\n",
       "      <th>year</th>\n",
       "      <th>filename</th>\n",
       "      <th>extension</th>\n",
       "      <th>ws_title</th>\n",
       "      <th>form_name</th>\n",
       "      <th>description</th>\n",
       "      <th>form_dt</th>\n",
       "      <th>unit_name</th>\n",
       "      <th>поле</th>\n",
       "      <th>код строки</th>\n",
       "      <th>кол. налогоплательщиков</th>\n",
       "      <th>всего</th>\n",
       "      <th>по налогу (сбору)</th>\n",
       "      <th>по пени</th>\n",
       "      <th>по штрафам</th>\n",
       "      <th>проценты</th>\n",
       "      <th>по ЕСН</th>\n",
       "      <th>по страховым взносам</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>2009</td>\n",
       "      <td>4nm010618</td>\n",
       "      <td>xlsx</td>\n",
       "      <td>Р. Справочно1_Списание</td>\n",
       "      <td>Форма № 4-НМ</td>\n",
       "      <td>Справочно к Разделам I, II:      1_Списано зад...</td>\n",
       "      <td>по состоянию на 01.06.2018 г.</td>\n",
       "      <td>тыс. рублей</td>\n",
       "      <td>Сумма списанной задолженности организаций, лик...</td>\n",
       "      <td>2400</td>\n",
       "      <td>23632</td>\n",
       "      <td>30705385</td>\n",
       "      <td>18388429</td>\n",
       "      <td>4699527</td>\n",
       "      <td>1439452</td>\n",
       "      <td>184237</td>\n",
       "      <td>596724</td>\n",
       "      <td>5397016</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "      <td>2009</td>\n",
       "      <td>4nm010618</td>\n",
       "      <td>xlsx</td>\n",
       "      <td>Р. Справочно1_Списание</td>\n",
       "      <td>Форма № 4-НМ</td>\n",
       "      <td>Справочно к Разделам I, II:      1_Списано зад...</td>\n",
       "      <td>по состоянию на 01.06.2018 г.</td>\n",
       "      <td>тыс. рублей</td>\n",
       "      <td>Сумма списанной задолженности индивидуальных п...</td>\n",
       "      <td>2405</td>\n",
       "      <td>9109</td>\n",
       "      <td>3013574</td>\n",
       "      <td>1661920</td>\n",
       "      <td>881213</td>\n",
       "      <td>242978</td>\n",
       "      <td>628</td>\n",
       "      <td>51928</td>\n",
       "      <td>174907</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>2</td>\n",
       "      <td>2</td>\n",
       "      <td>2009</td>\n",
       "      <td>4nm010618</td>\n",
       "      <td>xlsx</td>\n",
       "      <td>Р. Справочно1_Списание</td>\n",
       "      <td>Форма № 4-НМ</td>\n",
       "      <td>Справочно к Разделам I, II:      1_Списано зад...</td>\n",
       "      <td>по состоянию на 01.06.2018 г.</td>\n",
       "      <td>тыс. рублей</td>\n",
       "      <td>Сумма списанной задолженности умерших или объя...</td>\n",
       "      <td>2410</td>\n",
       "      <td>39920</td>\n",
       "      <td>677495</td>\n",
       "      <td>115346</td>\n",
       "      <td>44047</td>\n",
       "      <td>11984</td>\n",
       "      <td>0</td>\n",
       "      <td>5203</td>\n",
       "      <td>500915</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>3</td>\n",
       "      <td>3</td>\n",
       "      <td>2009</td>\n",
       "      <td>4nm010618</td>\n",
       "      <td>xlsx</td>\n",
       "      <td>Р. Справочно1_Списание</td>\n",
       "      <td>Форма № 4-НМ</td>\n",
       "      <td>Справочно к Разделам I, II:      1_Списано зад...</td>\n",
       "      <td>по состоянию на 01.06.2018 г.</td>\n",
       "      <td>тыс. рублей</td>\n",
       "      <td>Сумма списанной задолженности в случаях принят...</td>\n",
       "      <td>2415</td>\n",
       "      <td>58635</td>\n",
       "      <td>2161183</td>\n",
       "      <td>773472</td>\n",
       "      <td>556271</td>\n",
       "      <td>70216</td>\n",
       "      <td>5769</td>\n",
       "      <td>154600</td>\n",
       "      <td>600855</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>4</td>\n",
       "      <td>4</td>\n",
       "      <td>2009</td>\n",
       "      <td>4nm010618</td>\n",
       "      <td>xlsx</td>\n",
       "      <td>Р. Справочно1_Списание</td>\n",
       "      <td>Форма № 4-НМ</td>\n",
       "      <td>Справочно к Разделам I, II:      1_Списано зад...</td>\n",
       "      <td>по состоянию на 01.06.2018 г.</td>\n",
       "      <td>тыс. рублей</td>\n",
       "      <td>Сумма списанной задолженности по \"зависшим\" пл...</td>\n",
       "      <td>2420</td>\n",
       "      <td>93</td>\n",
       "      <td>43115</td>\n",
       "      <td>31946</td>\n",
       "      <td>752</td>\n",
       "      <td>76</td>\n",
       "      <td>0</td>\n",
       "      <td>5527</td>\n",
       "      <td>4814</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>5</td>\n",
       "      <td>5</td>\n",
       "      <td>2009</td>\n",
       "      <td>4nm010618</td>\n",
       "      <td>xlsx</td>\n",
       "      <td>Р. Справочно1_Списание</td>\n",
       "      <td>Форма № 4-НМ</td>\n",
       "      <td>Справочно к Разделам I, II:      1_Списано зад...</td>\n",
       "      <td>по состоянию на 01.06.2018 г.</td>\n",
       "      <td>тыс. рублей</td>\n",
       "      <td>Сумма списанной задолженности организаций, отв...</td>\n",
       "      <td>2425</td>\n",
       "      <td>25104</td>\n",
       "      <td>4038755</td>\n",
       "      <td>2487632</td>\n",
       "      <td>1003525</td>\n",
       "      <td>215253</td>\n",
       "      <td>х</td>\n",
       "      <td>29516</td>\n",
       "      <td>302829</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>6</td>\n",
       "      <td>6</td>\n",
       "      <td>2009</td>\n",
       "      <td>4nm010618</td>\n",
       "      <td>xlsx</td>\n",
       "      <td>Р. Справочно1_Списание</td>\n",
       "      <td>Форма № 4-НМ</td>\n",
       "      <td>Справочно к Разделам I, II:      1_Списано зад...</td>\n",
       "      <td>по состоянию на 01.06.2018 г.</td>\n",
       "      <td>тыс. рублей</td>\n",
       "      <td>Сумма списанной задолженности по решениям нало...</td>\n",
       "      <td>2430</td>\n",
       "      <td>16841363</td>\n",
       "      <td>60557919</td>\n",
       "      <td>41458668</td>\n",
       "      <td>19050086</td>\n",
       "      <td>325</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>48839</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>7</td>\n",
       "      <td>7</td>\n",
       "      <td>2009</td>\n",
       "      <td>4nm010618</td>\n",
       "      <td>xlsx</td>\n",
       "      <td>Р. Справочно1_Списание</td>\n",
       "      <td>Форма № 4-НМ</td>\n",
       "      <td>Справочно к Разделам I, II:      1_Списано зад...</td>\n",
       "      <td>по состоянию на 01.06.2018 г.</td>\n",
       "      <td>тыс. рублей</td>\n",
       "      <td>Сумма задолженности, списанной на  основании з...</td>\n",
       "      <td>2435</td>\n",
       "      <td>1799585</td>\n",
       "      <td>133435115</td>\n",
       "      <td>36498879</td>\n",
       "      <td>19197715</td>\n",
       "      <td>5102099</td>\n",
       "      <td>12731</td>\n",
       "      <td>2055653</td>\n",
       "      <td>70568038</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>8</td>\n",
       "      <td>0</td>\n",
       "      <td>2008</td>\n",
       "      <td>4nm011118</td>\n",
       "      <td>xlsx</td>\n",
       "      <td>Р. Справочно1_Списание</td>\n",
       "      <td>Форма № 4-НМ</td>\n",
       "      <td>Справочно к Разделам I, II:      1_Списано зад...</td>\n",
       "      <td>по состоянию на 01.11.2018 г.</td>\n",
       "      <td>тыс. рублей</td>\n",
       "      <td>Сумма списанной задолженности организаций, лик...</td>\n",
       "      <td>2400</td>\n",
       "      <td>40157</td>\n",
       "      <td>71402906</td>\n",
       "      <td>40477282</td>\n",
       "      <td>12510111</td>\n",
       "      <td>3381043</td>\n",
       "      <td>838205</td>\n",
       "      <td>1228143</td>\n",
       "      <td>12968122</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>9</td>\n",
       "      <td>1</td>\n",
       "      <td>2008</td>\n",
       "      <td>4nm011118</td>\n",
       "      <td>xlsx</td>\n",
       "      <td>Р. Справочно1_Списание</td>\n",
       "      <td>Форма № 4-НМ</td>\n",
       "      <td>Справочно к Разделам I, II:      1_Списано зад...</td>\n",
       "      <td>по состоянию на 01.11.2018 г.</td>\n",
       "      <td>тыс. рублей</td>\n",
       "      <td>Сумма списанной задолженности индивидуальных п...</td>\n",
       "      <td>2405</td>\n",
       "      <td>19496</td>\n",
       "      <td>4481612</td>\n",
       "      <td>2347431</td>\n",
       "      <td>1261980</td>\n",
       "      <td>345253</td>\n",
       "      <td>628</td>\n",
       "      <td>72728</td>\n",
       "      <td>453592</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>10</th>\n",
       "      <td>10</td>\n",
       "      <td>2</td>\n",
       "      <td>2008</td>\n",
       "      <td>4nm011118</td>\n",
       "      <td>xlsx</td>\n",
       "      <td>Р. Справочно1_Списание</td>\n",
       "      <td>Форма № 4-НМ</td>\n",
       "      <td>Справочно к Разделам I, II:      1_Списано зад...</td>\n",
       "      <td>по состоянию на 01.11.2018 г.</td>\n",
       "      <td>тыс. рублей</td>\n",
       "      <td>Сумма списанной задолженности умерших или объя...</td>\n",
       "      <td>2410</td>\n",
       "      <td>107516</td>\n",
       "      <td>1397855</td>\n",
       "      <td>318751</td>\n",
       "      <td>93790</td>\n",
       "      <td>17866</td>\n",
       "      <td>0</td>\n",
       "      <td>8821</td>\n",
       "      <td>958627</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>11</th>\n",
       "      <td>11</td>\n",
       "      <td>3</td>\n",
       "      <td>2008</td>\n",
       "      <td>4nm011118</td>\n",
       "      <td>xlsx</td>\n",
       "      <td>Р. Справочно1_Списание</td>\n",
       "      <td>Форма № 4-НМ</td>\n",
       "      <td>Справочно к Разделам I, II:      1_Списано зад...</td>\n",
       "      <td>по состоянию на 01.11.2018 г.</td>\n",
       "      <td>тыс. рублей</td>\n",
       "      <td>Сумма списанной задолженности в случаях принят...</td>\n",
       "      <td>2415</td>\n",
       "      <td>152898</td>\n",
       "      <td>5175662</td>\n",
       "      <td>1879757</td>\n",
       "      <td>1448942</td>\n",
       "      <td>185201</td>\n",
       "      <td>6911</td>\n",
       "      <td>255959</td>\n",
       "      <td>1398892</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>12</th>\n",
       "      <td>12</td>\n",
       "      <td>4</td>\n",
       "      <td>2008</td>\n",
       "      <td>4nm011118</td>\n",
       "      <td>xlsx</td>\n",
       "      <td>Р. Справочно1_Списание</td>\n",
       "      <td>Форма № 4-НМ</td>\n",
       "      <td>Справочно к Разделам I, II:      1_Списано зад...</td>\n",
       "      <td>по состоянию на 01.11.2018 г.</td>\n",
       "      <td>тыс. рублей</td>\n",
       "      <td>Сумма списанной задолженности по \"зависшим\" пл...</td>\n",
       "      <td>2420</td>\n",
       "      <td>165</td>\n",
       "      <td>79701</td>\n",
       "      <td>64933</td>\n",
       "      <td>1515</td>\n",
       "      <td>70</td>\n",
       "      <td>0</td>\n",
       "      <td>5565</td>\n",
       "      <td>7618</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>13</th>\n",
       "      <td>13</td>\n",
       "      <td>5</td>\n",
       "      <td>2008</td>\n",
       "      <td>4nm011118</td>\n",
       "      <td>xlsx</td>\n",
       "      <td>Р. Справочно1_Списание</td>\n",
       "      <td>Форма № 4-НМ</td>\n",
       "      <td>Справочно к Разделам I, II:      1_Списано зад...</td>\n",
       "      <td>по состоянию на 01.11.2018 г.</td>\n",
       "      <td>тыс. рублей</td>\n",
       "      <td>Сумма списанной задолженности организаций, отв...</td>\n",
       "      <td>2425</td>\n",
       "      <td>40759</td>\n",
       "      <td>7379705</td>\n",
       "      <td>4476555</td>\n",
       "      <td>1843784</td>\n",
       "      <td>437216</td>\n",
       "      <td>х</td>\n",
       "      <td>73047</td>\n",
       "      <td>549103</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>14</th>\n",
       "      <td>14</td>\n",
       "      <td>6</td>\n",
       "      <td>2008</td>\n",
       "      <td>4nm011118</td>\n",
       "      <td>xlsx</td>\n",
       "      <td>Р. Справочно1_Списание</td>\n",
       "      <td>Форма № 4-НМ</td>\n",
       "      <td>Справочно к Разделам I, II:      1_Списано зад...</td>\n",
       "      <td>по состоянию на 01.11.2018 г.</td>\n",
       "      <td>тыс. рублей</td>\n",
       "      <td>Сумма списанной задолженности по решениям нало...</td>\n",
       "      <td>2430</td>\n",
       "      <td>16980357</td>\n",
       "      <td>61711637</td>\n",
       "      <td>42232603</td>\n",
       "      <td>19477495</td>\n",
       "      <td>676</td>\n",
       "      <td>725</td>\n",
       "      <td>0</td>\n",
       "      <td>138</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>15</th>\n",
       "      <td>15</td>\n",
       "      <td>7</td>\n",
       "      <td>2008</td>\n",
       "      <td>4nm011118</td>\n",
       "      <td>xlsx</td>\n",
       "      <td>Р. Справочно1_Списание</td>\n",
       "      <td>Форма № 4-НМ</td>\n",
       "      <td>Справочно к Разделам I, II:      1_Списано зад...</td>\n",
       "      <td>по состоянию на 01.11.2018 г.</td>\n",
       "      <td>тыс. рублей</td>\n",
       "      <td>Сумма задолженности, списанной на  основании з...</td>\n",
       "      <td>2435</td>\n",
       "      <td>3737334</td>\n",
       "      <td>340440384</td>\n",
       "      <td>62488024</td>\n",
       "      <td>31036806</td>\n",
       "      <td>7336091</td>\n",
       "      <td>34915</td>\n",
       "      <td>2494914</td>\n",
       "      <td>237049634</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "    global_index  ws_index  year   filename extension                ws_title  \\\n",
       "0              0         0  2009  4nm010618      xlsx  Р. Справочно1_Списание   \n",
       "1              1         1  2009  4nm010618      xlsx  Р. Справочно1_Списание   \n",
       "2              2         2  2009  4nm010618      xlsx  Р. Справочно1_Списание   \n",
       "3              3         3  2009  4nm010618      xlsx  Р. Справочно1_Списание   \n",
       "4              4         4  2009  4nm010618      xlsx  Р. Справочно1_Списание   \n",
       "5              5         5  2009  4nm010618      xlsx  Р. Справочно1_Списание   \n",
       "6              6         6  2009  4nm010618      xlsx  Р. Справочно1_Списание   \n",
       "7              7         7  2009  4nm010618      xlsx  Р. Справочно1_Списание   \n",
       "8              8         0  2008  4nm011118      xlsx  Р. Справочно1_Списание   \n",
       "9              9         1  2008  4nm011118      xlsx  Р. Справочно1_Списание   \n",
       "10            10         2  2008  4nm011118      xlsx  Р. Справочно1_Списание   \n",
       "11            11         3  2008  4nm011118      xlsx  Р. Справочно1_Списание   \n",
       "12            12         4  2008  4nm011118      xlsx  Р. Справочно1_Списание   \n",
       "13            13         5  2008  4nm011118      xlsx  Р. Справочно1_Списание   \n",
       "14            14         6  2008  4nm011118      xlsx  Р. Справочно1_Списание   \n",
       "15            15         7  2008  4nm011118      xlsx  Р. Справочно1_Списание   \n",
       "\n",
       "       form_name                                        description  \\\n",
       "0   Форма № 4-НМ  Справочно к Разделам I, II:      1_Списано зад...   \n",
       "1   Форма № 4-НМ  Справочно к Разделам I, II:      1_Списано зад...   \n",
       "2   Форма № 4-НМ  Справочно к Разделам I, II:      1_Списано зад...   \n",
       "3   Форма № 4-НМ  Справочно к Разделам I, II:      1_Списано зад...   \n",
       "4   Форма № 4-НМ  Справочно к Разделам I, II:      1_Списано зад...   \n",
       "5   Форма № 4-НМ  Справочно к Разделам I, II:      1_Списано зад...   \n",
       "6   Форма № 4-НМ  Справочно к Разделам I, II:      1_Списано зад...   \n",
       "7   Форма № 4-НМ  Справочно к Разделам I, II:      1_Списано зад...   \n",
       "8   Форма № 4-НМ  Справочно к Разделам I, II:      1_Списано зад...   \n",
       "9   Форма № 4-НМ  Справочно к Разделам I, II:      1_Списано зад...   \n",
       "10  Форма № 4-НМ  Справочно к Разделам I, II:      1_Списано зад...   \n",
       "11  Форма № 4-НМ  Справочно к Разделам I, II:      1_Списано зад...   \n",
       "12  Форма № 4-НМ  Справочно к Разделам I, II:      1_Списано зад...   \n",
       "13  Форма № 4-НМ  Справочно к Разделам I, II:      1_Списано зад...   \n",
       "14  Форма № 4-НМ  Справочно к Разделам I, II:      1_Списано зад...   \n",
       "15  Форма № 4-НМ  Справочно к Разделам I, II:      1_Списано зад...   \n",
       "\n",
       "                          form_dt    unit_name  \\\n",
       "0   по состоянию на 01.06.2018 г.  тыс. рублей   \n",
       "1   по состоянию на 01.06.2018 г.  тыс. рублей   \n",
       "2   по состоянию на 01.06.2018 г.  тыс. рублей   \n",
       "3   по состоянию на 01.06.2018 г.  тыс. рублей   \n",
       "4   по состоянию на 01.06.2018 г.  тыс. рублей   \n",
       "5   по состоянию на 01.06.2018 г.  тыс. рублей   \n",
       "6   по состоянию на 01.06.2018 г.  тыс. рублей   \n",
       "7   по состоянию на 01.06.2018 г.  тыс. рублей   \n",
       "8   по состоянию на 01.11.2018 г.  тыс. рублей   \n",
       "9   по состоянию на 01.11.2018 г.  тыс. рублей   \n",
       "10  по состоянию на 01.11.2018 г.  тыс. рублей   \n",
       "11  по состоянию на 01.11.2018 г.  тыс. рублей   \n",
       "12  по состоянию на 01.11.2018 г.  тыс. рублей   \n",
       "13  по состоянию на 01.11.2018 г.  тыс. рублей   \n",
       "14  по состоянию на 01.11.2018 г.  тыс. рублей   \n",
       "15  по состоянию на 01.11.2018 г.  тыс. рублей   \n",
       "\n",
       "                                                 поле  код строки  \\\n",
       "0   Сумма списанной задолженности организаций, лик...        2400   \n",
       "1   Сумма списанной задолженности индивидуальных п...        2405   \n",
       "2   Сумма списанной задолженности умерших или объя...        2410   \n",
       "3   Сумма списанной задолженности в случаях принят...        2415   \n",
       "4   Сумма списанной задолженности по \"зависшим\" пл...        2420   \n",
       "5   Сумма списанной задолженности организаций, отв...        2425   \n",
       "6   Сумма списанной задолженности по решениям нало...        2430   \n",
       "7   Сумма задолженности, списанной на  основании з...        2435   \n",
       "8   Сумма списанной задолженности организаций, лик...        2400   \n",
       "9   Сумма списанной задолженности индивидуальных п...        2405   \n",
       "10  Сумма списанной задолженности умерших или объя...        2410   \n",
       "11  Сумма списанной задолженности в случаях принят...        2415   \n",
       "12  Сумма списанной задолженности по \"зависшим\" пл...        2420   \n",
       "13  Сумма списанной задолженности организаций, отв...        2425   \n",
       "14  Сумма списанной задолженности по решениям нало...        2430   \n",
       "15  Сумма задолженности, списанной на  основании з...        2435   \n",
       "\n",
       "    кол. налогоплательщиков      всего  по налогу (сбору)   по пени  \\\n",
       "0                     23632   30705385           18388429   4699527   \n",
       "1                      9109    3013574            1661920    881213   \n",
       "2                     39920     677495             115346     44047   \n",
       "3                     58635    2161183             773472    556271   \n",
       "4                        93      43115              31946       752   \n",
       "5                     25104    4038755            2487632   1003525   \n",
       "6                  16841363   60557919           41458668  19050086   \n",
       "7                   1799585  133435115           36498879  19197715   \n",
       "8                     40157   71402906           40477282  12510111   \n",
       "9                     19496    4481612            2347431   1261980   \n",
       "10                   107516    1397855             318751     93790   \n",
       "11                   152898    5175662            1879757   1448942   \n",
       "12                      165      79701              64933      1515   \n",
       "13                    40759    7379705            4476555   1843784   \n",
       "14                 16980357   61711637           42232603  19477495   \n",
       "15                  3737334  340440384           62488024  31036806   \n",
       "\n",
       "    по штрафам проценты   по ЕСН  по страховым взносам  \n",
       "0      1439452   184237   596724               5397016  \n",
       "1       242978      628    51928                174907  \n",
       "2        11984        0     5203                500915  \n",
       "3        70216     5769   154600                600855  \n",
       "4           76        0     5527                  4814  \n",
       "5       215253        х    29516                302829  \n",
       "6          325        1        0                 48839  \n",
       "7      5102099    12731  2055653              70568038  \n",
       "8      3381043   838205  1228143              12968122  \n",
       "9       345253      628    72728                453592  \n",
       "10       17866        0     8821                958627  \n",
       "11      185201     6911   255959               1398892  \n",
       "12          70        0     5565                  7618  \n",
       "13      437216        х    73047                549103  \n",
       "14         676      725        0                   138  \n",
       "15     7336091    34915  2494914             237049634  "
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# пример как полностью настроить класс сразу при создании\n",
    "proc = ExcelPreprocessor('data\\\\2009\\\\4nm010618.xlsx', 'data\\\\2008\\\\4nm011118.xlsx',\n",
    "    filename_parser=lambda filename: re.match(r'data\\\\(?P<year>\\w+)\\\\(?P<filename>\\w+)\\.(?P<extension>\\w+)', filename).groupdict(),\n",
    "    append_global_index=True, append_wb_index=True,\n",
    "    cells = {'form_name': 'J1', 'description': 'A2', 'form_dt': 'A3', 'unit_name': 'J4'},\n",
    "    headers = ['поле', 'код строки', 'кол. налогоплательщиков', 'всего', 'по налогу (сбору)', 'по пени', 'по штрафам', 'проценты', 'по ЕСН', 'по страховым взносам'],\n",
    "    first_row_number=7, append_ws_title_column=True, iterate_over_worksheet=2\n",
    ")\n",
    "proc.get_dataframe()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}