Нужные данные я нашел, но форма их представления для корректного использования оставляла желать лучшего.
Все необходимые данные были в одном файле, однако, его форматирование затрудняло извлечение иерархии. Все названия муниципалитетов, районов и областей располагались в одном столбце и отличались только форматом ячейки и шрифта. Область выделялась жирным шрифтом, район — жирным наклонным, а поселение имело отступ. Также в файле находились несколько ошибок, например один район был выделен как область (или наоборот, уже не помню), а еще в одном месте в середине названия образования встретился переход строки (этот момент выяснился на этапе импорта в 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']
ссылка на оригинал статьи http://habrahabr.ru/post/182548/
Добавить комментарий