Время на прочтение
Сразу оговорюсь, что это лишь мой опыт, поэтому все будет объяснять на понятном МНЕ языке, но критику приветствую и всегда буду рада комментариям 🙂
- Что такое эти ваши json и xml?
- Знакомство в python
- Мой опыт, заключение
- Структура файлов
- Разбор файла _rels/. rels
- Разбор docProps/app. xml
- Разбор docProps/core. xml
- Разбор xl/_rels/workbook. xml. rels
- Разбор xl/printerSettings/printerSettings1. bin
- Разбор xl/theme/theme1. xml
- Разбор xl/worksheets/_rels/sheet1. xml. rels
- Разбор xl/worksheets/sheet1. xml
- Разбор xl/caclChain. xml
- Разбор xl/sharedStrings. xml
- Разбор xl/styles. xml
- Разбор xl/workbook. xml
- Разбор [Content_Types]. xml
- Завершение
Что такое эти ваши json и xml?
По сути два этих формата используются для передачи и хранения информации. Разница в том, что json можно преобразовать в объект JavaScript и обратно.
А вот с xml так не получится, потому что он используется в основном для кодирования файлов в читаемом формате.
В этом json есть атрибут «Персонал», в котором хранится информация о всех сотрудниках, с краткой информацией ФИО и возраст.
В нашем примере есть пары: «Имя»-«Саша», «Фамилия»-«Петров» и тд. Они находятся внутри общего json-объекта, и принадлежать паре «Персонал» и словарь json-объектов с описанием сотрудников.
Аналогичный набор xml будет выглядеть так:
Согласитесь: с виду, все вполне понятно, есть небольшие отличия в синтаксисе и все? Я тоже так думаю и даже скажу, что json можно легко преобразовать в xml.
Xml имеет свою кодировку, которую важно учитывать при создания файлов. ( Учитесь на моих ошибках). Также есть xsd или xml-схема, которая создается для проверки правильности xml и в каком-то смысле упрощения ее создания.
Думаю, основной информации достаточно, так что можем приступить к работе с этими форматами в Python. Собственно для это мы с вами сегодня и собрались.
Знакомство в python
Для начала возьмем на обработку json, точнее попробуем его создать
Теперь, когда у нас получилось создать json мы можем выгрузить определённый элемент или же поменять значение.
Но проще всего менять значения в самом словаре и загружать его в json-файл.
Здесь у нас идет обращения к объектам сначала первый объект «personal». Потом мы выбираем первого сотрудника, поэтому индекс 0 и название значения «Age».
Соответственно далее все уже зависит от ваших задач и желаний. Теперь познакомимся и с xml.
import xml.etree. ElementTree as ET # Загружаем библиотеку
# Создаем основной элемент, в который будем добавлять последующие
data_xml = ET. Element(‘personal’)
# Добавляем первого сотрудника
employee = ET. SubElement(data_xml, ’employee’)
# Добавляем вложенные элементы в созданый employee
employee_n = ET. SubElement(employee, ‘Name’)
employee_n.text = «Саша»
employee_l = ET. SubElement(employee, ‘LastName’)
employee_l.text = «Петров»
employee_a = ET. SubElement(employee, ‘Age’)
employee_a.text = «34»
# Добавляем второго сотрудника
employee = ET. SubElement(data_xml, ’employee’)
# Добавляем вложенные элементы в созданый employee
employee_n = ET. SubElement(employee, ‘Name’)
employee_n.text = ‘Вася’
employee_l = ET. SubElement(employee, ‘LastName’)
employee_l.text = ‘Иванов’
employee_a = ET. SubElement(employee, ‘Age’)
employee_a.text = ’37’
# Посмотрим получившийся xml
print(ET.dump(data_xml))
Тут мы создаем вложенный элемент методом SubElement, в котором указываем элемент, куда добавляем, и название. То есть в элемент data_xml добавляем вложенный элемент employee, а в него уже Name, LastName, Age. И с помощью метода text добавляем сами значения.
Соответсвенно, как и в прошлом случае мы можем обратиться к элементам и изменить их.
Все выглядит достаточно просто. Мы научились создавать, изменять, выгружать в файл json и xml. В следующем разделе, я опишу свой пример создания xml-файла с json внутри.
Мой опыт, заключение
Я взяла готовый xml, загрузила его и не поняла. Во-первых, получилось не с первого раза.
Во-вторых, был только один тег.
С этого момента все стало еще запутаннее и непонятно. Выглядело все примерно так:
Естественно, на просторах сети, я такого не встречала и пришлось придумывать что-то самой.
Поэтому я работала сначала с внутренним json, который меняла, добавляла новые объекты, а потом уже добавляла его в тег xml файла. Не хочу здесь писать более подробно про конкретный случай, поэтому описала вкратце.
В заключении: Очень надеюсь, что кому-то это поможет разобраться в непонятной теме. Готова к замечаниям и критики, большое спасибо за потраченное время 🙂
Недавно мне понадобилось встроить в CRM возможность создания отчетов в Excel посредством PHP, но готовые решения были сильно громоздкими. Поэтому я решил написать собственную библиотеку для работы с Excel файлами через PHP. Но информации о внутренности Excel было очень мало и мне пришлось собирать ее по крупинкам, иногда методами тыка, проб и ошибок разбирал работу некоторых элементов.
Но дополнять ее в комментариях — очень громоздко и неудобно. Поэтому я решил поделиться всеми свои знаниями в новой статье, и если это поможет кому-то, то мои старания будут более, чем не напрасны.
Структура файлов
Дерево файлов и подкаталогов
В папках xl/worksheets, xl/printerSettings и xl/worksheets/_rels могут быть по несколько файлов.
Давайте разберёмся, для чего все эти файлы, начнём по порядку:
_rels/.rels — описание связей файлов, касаемых самой работы Excel;
docProps/app.xml — описание и настройки приложения Excel;
docProps/core.xml — здесь записывается имя создателя файла, время создания и последнего редактирования файла;
xl/_rels/workbook.xml.rels — перечень и описание зависимостей файлов, используемых в книге;
xl/printerSettings/printerSettings1.bin — описание настроек для печати листа;
xl/theme/theme1.xml — описание стилей приложения;
xl/worksheets/_rels/sheet1.xml.rels — описание связей листа xl/worksheets/sheet1.xml с другими документами;
xl/worksheets/sheet1.xml — описание всего происходящего на листе, который находится на первой позиции в списке листов книги. Название листа и название файла никак не связаны, файл всегда называется sheet1, sheet2 и т.д. На каждый лист приходится один такой файл;
xl/caclChain.xml — цепочка вычислений. Конструкция, указывающая порядок вычислений ячеек в книге в последний раз;
xl/styles.xml — описание стилей, используемых во всей книге;
xl/workbook.xml — описание настроек книги и перечень используемых листов;
Разбор файла _rels/. rels
В первой строке у нас объявляется тип документа — xml с его версией, кодировкой и автономности.
standalone (автономность) — Это объявление указывает, содержит ли внешнее подмножество DTD (Document Type Definition — определение типа документа) какие-либо объявления, которые могут повлиять на текущее содержимое документа.
Вторая строчка — открывающий тег для описания связей документов. Атрибут xmlns — означает, что используется пространство имен, от сюда и название самого атрибута — xml NameSpace.
Далее идут 3 строки связей с документами. У каждого есть атрибуты: Id — уникальное имя для связи, Type — ссылка на стандарт, описывающий нужный нам тип документа, Target — путь к исполняемому файлу.
Разбор docProps/app. xml
Содержимое данного файла примерно такая (не все элементы могут присутствовать и иметь тот же вид, что и у меня):
Первая строка нам уже знакома.
Во второй строке открывающий тег properties и эта строка похожа на рассмотренную нами ранее.
Третья строка содержит название приложения. В данном случае — Microsoft Excel (что не удивительно). Данную строку лучше не изменять, ибо приложение упадет.
Означает безопасность документа и в зависимости от числа имеет следующий посыл:
0 — Документ не защищен
1 — Документ защищен паролем.
2 — Рекомендуется открывать документ только для чтения.
4 — Документ принудительно открыт только для чтения.
8 — Документ заблокирован для заметок.
указывает режим отображения эскиза документа. Установите для этого элемента значение TRUE, чтобы включить масштабирование эскиза документа на экране. Установите для этого элемента значение FALSE, чтобы включить обрезку эскиза документа, чтобы отображались только те разделы, которые соответствуют отображаемому значению (из документации microsoft).
Далее открывается тег HeadingPairs, внутри которого описаны группы частей документа и количество частей в каждой группе. Эти части являются не частями документа, а концептуальными представлениями разделов документа.
Внутри HeadingPairs мы имеем 1 векторный контент, в котором имеются 2 его части (подробнее о векторах и baseType можно почитать в документации microsoft).
Первая часть означает, что мы описываем листы в книге, а во второй части указываем количество этих листов.
Следующий тег — TitlesOfParts. Он описывает наименования частей документа. в данном случае — названия листов в книге. Здесь также указывается количество частей векторного контента.
В теге Company можно записать название компании.
Следующий элемент — LinksUpToDate — указывает, актуальны ли гиперссылки в документе. Установите для этого элемента значение TRUE, чтобы показать, что гиперссылки обновлены. Установите для этого элемента значение FALSE, чтобы указать, что гиперссылки устарели (из документации microsoft).
HyperlinksChanged указывает, что одна или несколько гиперссылок в этой части были обновлены исключительно в этой части производителем. Следующий производитель, который откроет этот документ, обновит отношения гиперссылок новыми гиперссылками, указанными в этой части.
Тег AppVersion указывает версию используемого приложения Excel при создании файла
Разбор docProps/core. xml
Содержимое файла примерно таково:
Во второй строке открывающий тег cp:coreProperties и эта строка похожа на рассмотренную нами ранее. Внутри него описываются свойства приложения:
dc:creator — Имя создателя документа;
dcterms:created — дата и время создания файла;
dcterms:modified — дата и время последнего изменения файла;
Разбор xl/_rels/workbook. xml. rels
Примерное содержимое файла:
Этот файл похож на раннее рассмотренный нами, только здесь уже описываются зависимости для файлов, которые используются непосредственно в книге.
Здесь записаны зависимости всех листов в книге, файла со строковыми значениями, цепочками вычислений и прочих файлов (мы разберем эти файлы дальше)
Разбор xl/printerSettings/printerSettings1. bin
Это файл, содержащий код в бинарном виде. Чтобы разобрать этот файл нужно описать много вещей про бинарники, а, чтобы научить писать правильно такой файл, потребуется много сил, времени и много текста. Да и в целом не вижу смысла вам работать с этим файлом. (честно говоря, я сам поверхностно знаком с этой темой).
Разбор xl/theme/theme1. xml
У меня не было надобностей разбирать этот файл, поэтому пока не буду описывать его работу. Но если кому-то понадобится (не знаю зачем) подробный разбор этого файла — я постараюсь сделать это.
Разбор xl/worksheets/_rels/sheet1. xml. rels
Содержимое этого файла может быть следующим:
Здесь описана одна зависимость с файлом xl/printerSettings/printerSettings1.bin — настройками для печати.
Разбор xl/worksheets/sheet1. xml
Начинается самое интересное и большое в этой статье.
Начинается такой файл с обычного объявления типа документа xml и некоторых настроек:
Строка третья означает размер экспортируемого диапазона (с какой по какую ячейку находятся данные).
В теге sheetView — selection описывается выделенная клетка (или диапазон клеток).
Атрибут activeCell — активная ячейка, sqref — выделенная ячейка или диапазон ячеек.
такая строка может выглядеть и вот так:
Здесь уже вместо атрибута activeCell стоит activeCellId, потому что в атрибуте sqref мы видим несколько диапазонов. исходя из этого выясняем, что активный диапазон является A1:C3. на изображении ниже показано, как выглядит такой вариант выделения ячеек.
ySplit — показывает количество закрепленных строк. Для закрепления столбцов есть аналогичный атрибут xSplit;
topLeftCell — указание левой верхней ячейки, видимой по умолчанию НЕзакрепленной области;
activePane — указание местонахождения НЕзакрепленной области. В руководствах сказано, что этот атрибут регулирует, с какой стороны будет НЕзакрепленная область. Правда, попробовав разные значения, я почему-то получил одинаковый результат. Как вариант «by default» я для себя выбрал bottomRight;
state — указатель состояния закрепленной области. Для простого закрепления строки используется значение frozen
Интересен нам здесь в основном атрибут defaultRowHeight, то есть высота столбца по умолчанию. Стандартный, привычный нам вариант — 15 у.е. Если назначить его, скажем, 30 у.е., то строки, для которых высота не указана отдельно, станут в 2 раза выше. Однако, для того чтоб применить значение, отличное от дефолтного, необходимо указать атрибут customHeight со значением «true». Выглядит это примерно так:
Атрибут min — первый столбец группы;
Атрибут max — последний столбец группы;
Атрибут width — ширина столбца из группы;
Атрибут customWidth — флаг применения кастомной ширины, без него ширина все равно будет дефолтной;
Тег sheetData — описание содержимого ячеек и их настроек.
здесь структура такова:
В Excel это будет выглядеть вот так:
Ячейки с данными
Давайте разбираться, что же все-таки в коде происходит.
Мы видим два тега row — это наши строки. У каждой есть атрибут r — это номер строки. Атрибут spans означает сколько столбцов задействовано, dyDescent — вертикальное расстояние в пикселях между ячейками. Атрибут ht устанавливает высоту всей строки в пунктах, а тег customHeight говорит, что мы используем нестандартную высоту строки.
В теге row есть теги c — это ячейки в строке. у каждого тега есть атрибут r — означающий позицию ячейки. Но атрибут t — присутствует не у всех, потому что запись t=»s» — означает, что у ячейки установлен тип строки, а у кого этого атрибута нет — тип устанавливается стандартный — числовой. Еще у тегов c может присутствовать атрибут s, в котором записывается номер применяемого к ячейке стиля из файла xl/styles.xml (мы доберемся до него позже).
Но мы можем заметить, что одна ячейка имеет помимо тега v еще тег f. Это тег с формулой, в данном случае формула означает: сумма ячеек от A1 до E1. А в теге v записан уже посчитанный ответ. Делать это не обязательно, но если не записать — то при открытии документа excel предложит сохранить изменения, т.к. он сам автоматически посчитал и записал этот результат.
С тегом sheetData разобрались, идем дальше.
Как мы знаем, в Excel есть возможность объединения ячеек. Все объединенные ячейки на листе перечислены здесь. В заполненном виде тег выглядит примерно так:
Нетрудно понять, что атрибут ref задает зону, занимаемую активными ячейками фильтров.
Тег printOptions — параметры печати. Атрибут headings — означает, что будут печататься заголовки, а атрибут gridLines — что будут печататься линии сетки.
Тег pageMargins задает поля сверху, снизу, справа, слева, у заголовков и у подвала для печатаемой страницы.
Тег pageSetup предпочтительные настройки бумаги, опять же, для печати.
Атрибут paperSize — устанавливает размер бумаги.
Атрибут pageOrder — направление печати. Если значение «overThenDown» — то будет печататься слева направо, потом нижняя часть снова слева направо и т.д. Если такого атрибута нет — то печататься будет сначала вся левая сторона сверху-вниз, потом та часть, что справа и т.д.
Атрибут orientation — задает ориентацию листов. «portrait» — портретная (вертикальная) ориентация, «landscape» — альбомная (горизонтальная) ориентация.
Атрибут blackAndWhite — если установлена 1 ил true — лист будет напечатан в черно-белом варианте.
Атрибут draft — если установлена 1 ил true — лист будет напечатан без графики.
Атрибут cellComments — печать комментариев к ячейкам. Используемые значения:
Атрибут errors — Печать обработки ошибок.
Атрибут r:id — идентификатор настроек.
Разбор xl/caclChain. xml
По традиции, начнем с содержимого файла:
Здесь нам важна строка 3. видим тег c — наша ячейка, у нее есть атрибут r — адрес ячейки. Индексный атрибут i указывает индекс листа, с которым связана ячейка.
Разбор xl/sharedStrings. xml
В этом примере строковое значение содержит 3 пробега. Чтобы было удобнее их рассматривать, я, пожалуй, вынесу их отдельными сорсами.
А здесь у нас есть и блок настроек шрифта, и сохранение концевых пробелов.
Ну и еще коротенькая ремарка. Если есть необходимость сделать многострочную запись в ячейке, то здесь в строке просто будет обычный символ переноса, chr
. Сам атрибут многострочности ячейки расположен в файле разметки листа. В однострочной ячейке символ переноса будет проигнорирован. Excel просто сделает вид, что его нет.
Добавлю: каждый тег si имеет порядковый номер, начиная с 0. Он нигде не записывается. Этот номер и записывается в файле xl/worksheets/sheet1.xml в теге sheetData, который мы рассматривали ранее.
Разбор xl/styles. xml
Как нетрудно догадаться, здесь хранится информация об оформлении ячеек. Причем в угоду оптимизации, хранится она в достаточно интересном виде. Файл состоит из следующих секций:
либо сочетание нескольких тегов.
Если хотите установить цвет шрифта какой-нибудь свой (возьмем #123456), то в теге color вместо атрибута theme пишем rgb и вставляем hex-код цвета, должно получиться вот так:
2. Заливка ячеек:
Как видно, первый вариант — без заливки вообще, а второй — сплошная заливка библиотечного цвета «gray125».
Здесь тот же принцип с установкой своего цвета, только немного по-другому записывается:
Тег fgcolor — отвечает за цвет переднего плана, а bgcolor — за цвет заднего плана (indexed=»64″ — черный цвет).
У тега patternFill атрибут patternType может иметь следующие значения:
Можно еще заливку сделать градиентом:
Как видно, одно наименование здесь состоит из пяти элементов, 4 основных границы и диагональная, то есть все то, что можно настроить через GUI самого Excel.
Атрибут style означает стиль границы и может иметь следующие значения:
Для установки цвета границы используйте уже известную нам запись:
Чтобы установить диагональную границу, нужно в тег diagonal записать атрибуты:
Ну и не забудьте внутри тега diagonal записать цвет для границы — тег color.
4. Стили ячеек:
— fontId, fillId, borderId — ссылка на шрифт/заливку/границы (см. секцию 1, 2 и 3 соответственно). Нумерация начинается с 0.
— applyFont, applyFill, applyBorder — указание на то, что при оформлении этой ячейки вообще используется кастомный шрифт/заливка/границы. По умолчанию 0, так что можно не указывать вообще, как видно на примере в элементе #0.
В теге alignment могут быть атрибуты:
Разбор xl/workbook. xml
Основное его назначение — манифест, то есть перечень листов, из которых наша книга Excel, собственно, и состоит. Выглядит этот перечень, к примеру, так:
Это значит, что в книге 4 листа, и их имена указаны в атрибутах name. Каждому тегу должен соответствовать файл в папке %file%/xl/worksheets. Excel сам знает, как должны называться эти файлы и при попытке их переименовать, сочтет всю книгу поврежденной.
Разбор [Content_Types]. xml
Содержимое файла может быть следующим:
В этом файле прописываются определения типов всех файлов и их расположения.
Как видно, здесь записываются все файлы листов, стилей, строковых значений, формул и т.д.
Если в документе вы не используете, к примеру, формул, то строки 13 не будет записано.
Завершение
Я разобрал основные моменты содержания файла excel. Если вам будет интересно узнать про диаграммы и другие возможности excel — пишите в комментариях, я постараюсь сделать дополнение к этой статье из ваших просьб.
Каждому человеку свойственно ошибаться. Если я чего-любо не раскрыл или раскрыл не полностью, либо с ошибками — поправьте меня.
Если вам также будет интересно — напишу статью, как манипулировать с файлами excel посредством PHP/Java/Ruby.
Спасибо за внимание и уделенное время этой статье.





