Для одного общественного проекта (визуализация бюджетов поселений и районов) мне потребовались данные об иерархии муниципальных образований и их численности.
Нужные данные я нашел, но форма их представления для корректного использования оставляла желать лучшего.
Все необходимые данные были в одном файле, однако, его форматирование затрудняло извлечение иерархии. Все названия муниципалитетов, районов и областей располагались в одном столбце и отличались только форматом ячейки и шрифта. Область выделялась жирным шрифтом, район — жирным наклонным, а поселение имело отступ. Также в файле находились несколько ошибок, например один район был выделен как область (или наоборот, уже не помню), а еще в одном месте в середине названия образования встретился переход строки (этот момент выяснился на этапе импорта в Google App Engine, когда db.StringProperty() ругнулся на multiline), исходный файл в этих местах пришлось исправить.
В поисках решения, как лучше это сделать, я набрел на библиотеку xlrd, возможностей которой хватает для этой задачи с лихвой. Подробнее о ней можно почитать тут, я же приведу код программы импорта и доступные параметры при работе с форматированием.
Форматирование ячейки и тип шрифта позволяют получить следующую информацию:
hor_align: 0
indent_level: 0
rotation: 0
shrink_to_fit: 0
text_direction: 0
text_wrapped: 0
vert_align: 2
background (XFBackground object):
background_colour_index: 65
fill_pattern: 0
pattern_colour_index: 64
border (XFBorder object):
bottom_colour_index: 64
bottom_line_style: 7
diag_colour_index: 0
diag_down: 0
diag_line_style: 0
diag_up: 0
left_colour_index: 64
left_line_style: 1
right_colour_index: 64
right_line_style: 1
top_colour_index: 64
top_line_style: 1
font_index: 7
format_key: 0
is_style: 0
lotus_123_prefix: 0
parent_style_index: 0
protection (XFProtection object):
cell_locked: 1
formula_hidden: 0
xf_index: 556
underline_type: 0
underlined: 0
weight: 400
bold: 1
character_set: 204
colour_index: 32767
escapement_type: 0
family: 0
font_index: 10
height: 200
italic: 1
name: u'Arial Cyr'
outline: 0
shadow: 0
Со всеми параметрами я не разбирался, мне для данной задачи хватило типа шрифта и отступа (ident) в ячейке. Но видно, что возможности большие, вплоть до цвета конкретной границы ячейки или типа линии.
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import xlrd
import json
rb = xlrd.open_workbook('Tabl-35-12.xls', formatting_info=True)
font_list = rb.font_list # list of all fonts in excel table
sheet = rb.sheet_by_index(1)
rows_number = sheet.nrows
peoples_dict = {} # main dict
for rownum in range(7, rows_number): # data starts with line 7
cell = sheet.cell(rownum, 0)
value = cell.value.strip().replace('n', ' ') # delete spaces at start and end
peoples_count = sheet.cell(rownum, 1).value
if peoples_count == 0 or peoples_count == '': # empty row - continue
continue
peoples_count = int(peoples_count) # from 12313.0 to integer
cell_format = rb.xf_list[cell.xf_index]
current_font = font_list[cell_format.font_index]
bold = bool(current_font.bold)
italic = bool(current_font.italic)
indent = cell_format.alignment.indent_level
is_region = bold and not italic
is_raion = bold and italic
is_municipal = (indent == 2)
if is_region:
region = value
peoples_dict[region] = {'count': peoples_count}
elif is_raion:
raion = value
peoples_dict[region][raion] = {'count': peoples_count}
elif is_municipal:
municipal = value
peoples_dict[region][raion][municipal] = {'count': peoples_count}
print peoples_dict['Московская область']['Истринский муниципальный район']['Городское поселение Истра']['count']
with open('peoples.json', 'w') as outfile:
json.dump(peoples_dict, outfile)
В качестве бонуса — получившийся выходной файл, в формате json. Структура — вложенные словари, где каждый элемент содержит ключ 'count', где записана численность образования, и ключи его потомков.
То есть численность Московской области можно получить так:
peoples_dict['Московская область']['count']
а численность города Истры Истринского муниципального района — так:
peoples_dict['Московская область']['Истринский муниципальный район']['Городское поселение Истра']['count']
Автор: KulikovPavel