Метка: Эксель

Пишем файл Excel из Python

Если вдруг вам потребуется, к примеру, выгружать отчеты из вашей программы, почему бы не воспользоваться общепринятым офисным форматом – Excel? В этом нет ничего сложного, потому что есть прекрасная библиотека XlsxWriter. Приведу для вас немного примеров из документации с собственными дополнениями. Итак, поехали с установки:

pip install XlsxWriter

Простейший пример, думаю, не вызовет вопросов, если вы знакомы с Excel: открыли файл, добавили лист, записали по адресу ячейки текст:

import xlsxwriter

# открываем новый файл на запись
workbook = xlsxwriter.Workbook('hello.xlsx')

# создаем там "лист"
worksheet = workbook.add_worksheet()

# в ячейку A1 пишем текст
worksheet.write('A1', 'Hello world')

# сохраняем и закрываем
workbook.close()

Сразу отмечу, что можно адресовать ячейки не только по строке типа А1 или C15, а непосредственно по индексам колонки и строки, но нумерация начинается в таком случае с нуля (0).

worksheet.write(0, 0, 'Это A1!')
worksheet.write(4, 3, 'Колонка D, стока 5')

Формулы

Естественно, мы можем добавить в ячейки формулы, как мы делаем это руками в Excel – нужно начать выражение со знака равно (=). Пример: в конце таблицы трат введем подсчет суммы:

import xlsxwriter

workbook = xlsxwriter.Workbook('formula.xlsx')
worksheet = workbook.add_worksheet()

# данные
expenses = (
    ['Аренда', 1000],
    ['Комуналка', 100],
    ['Еда', 300],
    ['Качалка', 50],
)

for i, (item, cost) in enumerate(expenses, start=1):
    worksheet.write(f'A{i}', item)
    worksheet.write(f'B{i}', cost)

# колонкой ниже добавить подсчет суммы
worksheet.write('A5', 'Итого:')
worksheet.write('B5', '=SUM(B1:B4)')

# сохраняем и закрываем
workbook.close()

Я пользуюсь программой Numbers на macOS, в MS Office будет более привычный вид. Вот что получилось у меня:

Таблица с формулой итого

Формат

Таблица получилась немного скучновата и невыразительна. Давайте добавим форматы ячейкам, а именно ячейки столбца B сделаем в формате денег, а графу «Итого:» и заголовки – жирными. Формат создается как отдельная переменная, и его передают третьим аргументом после аргумента-содержимого ячейки.

# формат для денег
money = workbook.add_format({'num_format': '#,##0"₽"'})
# формат жирности шрифта
bold = workbook.add_format({'bold': True})

worksheet.write('A1', 'Наименование', bold)
worksheet.write('B1', 'Потрачено', bold)

for i, (item, cost) in enumerate(expenses, start=2):
    worksheet.write(f'A{i}', item)
    worksheet.write(f'B{i}', cost, money)

# колонкой ниже добавить подсчет суммы
worksheet.write('A6', 'Итого:', bold)
worksheet.write('B6', '=SUM(B2:B5)', money)

Результат:

Таблица с формтами

Все подробности о форматах ищите тут. Там рассказано о размере и стиле шрифта, цвете и многом другом. На английском, но думаю, с базовым уровнем даже разберетесь при помощи картинок.

Вот, что там не написано, а хотелось бы улучшить – задать ширину столбца (колонки), чтобы влезал весь текст. Делается это так:

# для каждой колонки отдельно (первый и второй аргументы совпадают)
worksheet.set_column(0, 0, 15)
worksheet.set_column(1, 1, 20)

# или

# задать колонкам в диапазоне от 0 до 1 каждой – ширину 15
worksheet.set_column(0, 1, 15)

# или по названиям:
worksheet.set_column('A:B', 15)
worksheet.set_column('C:C', 20)

В каких единицах измеряется ширина? Черт его знает, это не сказано в документации, может, в сантидюймах? Подбирайте на глазок. Мой итог:

Увеличена ширина колонки

Графики

Они есть! Давайте построим график.

Шаг 1: зададим данные. Можно писать массив прямо в колонку, а не по каждой ячейке отдельно:

data = [
    [1, 2, 3, 4, 5],
    [2, 4, 6, 8, 10],
    [3, 6, 9, 12, 15],
]

# можно писать сразу колонками!
worksheet.write_column('A1', data[0])
worksheet.write_column('B1', data[1])
worksheet.write_column('C1', data[2])

Шаг 2. Создадим график, задав его тип – в данном случае: диаграмма-столбики. Потом зададим серии данных.

chart = workbook.add_chart({'type': 'column'})

# добавим три последовательности данных
chart.add_series({'values': '=Sheet1!$A$1:$A$5'})
chart.add_series({'values': '=Sheet1!$B$1:$B$5'})
chart.add_series({'values': '=Sheet1!$C$1:$C$5'})

Так, стоп! Что значит эта страшная строка? Она говорит, что нужно взять ячейки с листа «Sheet1» и так далее. А можно попроще? Да – задать данные через числовые координаты списком. А еще за одно в цикл завернем:

worksheet.name = 'Первый лист'
for col, series in enumerate(data):
    chart.add_series({
        # имя листа, строка начала, колонка начала, строка конца, колонка конца
        'values': [worksheet.name, 0, col, 4, col],
        'name': f'Серия {col + 1}'
    })

Шаг 3: вставить наш график в нужную ячейку:

# и вставим его в ячейку A7
worksheet.insert_chart('A7', chart)

Вот, как это выглядит:

Нарисовали график

Вообще, библиотека очень богатая. Доступно множество форматов и видов графиков и диаграмм. А еще можно объединять и разделять ячейки и даже включать макросы и скрипты!

Специально для канала @pyway. Подписывайтесь на мой канал в Телеграм @pyway 👈