Как вывести объединённые ячейки в печатной версии?

Как мне реализовать код для вывода расписания олимпиад, учитывая наличие объединённых ячеек?
  • 10 сентября 2024 г. 18:43
Ответы на вопрос 3
Чтобы вывести данные с объединёнными ячейками в печатной версии, обычно используют форматы, поддерживающие таблицы, например, HTML или PDF. Если вы работаете с HTML, вы можете использовать тег `<table>` с атрибутами `rowspan` и `colspan` для объединения ячеек.

Если вы разрабатываете какое-то приложение или используете язык программирования для генерации расписания, вам может пригодиться следующий пример на Python с использованием библиотеки `pandas` для работы с данными и `BeautifulSoup` или `reportlab` для генерации HTML или PDF:

### Пример на Python (используя HTML)

```python
import pandas as pd

# Пример данных
data = {
    'День': ['Понедельник', 'Понедельник', 'Вторник', 'Вторник'],
    'Время': ['09:00 - 11:00', '11:00 - 13:00', '09:00 - 11:00', '11:00 - 13:00'],
    'Олимпиада': ['Математика', 'Физика', 'Химия', 'Биология']
}

df = pd.DataFrame(data)

# Группировка и объединение ячеек
def create_html_table(dataframe):
    html = '<table border="1">\n'
    current_day = None
    for index, row in dataframe.iterrows():
        day = row['День']
        time = row['Время']
        subject = row['Олимпиада']
        
        if day != current_day:
            if current_day is not None:
                html += '        </tr>\n'
            current_day = day
            html += f'    <tr><td rowspan="{len(dataframe[dataframe["День"] == day])}">{current_day}</td>'
            html += f'<td>{time}</td><td>{subject}</td>\n'
        else:
            html += f'        <td>{time}</td><td>{subject}</td>\n'
    
    html += '    </tr>\n</table>'
    return html

html_table = create_html_table(df)
print(html_table)

# Вы можете сохранить его в HTML файл
with open("schedule.html", "w") as file:
    file.write(html_table)
```

### Примечания

1. **Объединение ячеек**: В этом коде объединяются ячейки для дней с помощью `rowspan`.
2. **Печать**: Для печати вы можете открыть HTML файл в браузере и использовать функцию печати.
3. **PDF**: Чтобы сгенерировать PDF, вы можете использовать библиотеку `reportlab` или `WeasyPrint`, которая конвертирует HTML в PDF.

### Пример для PDF

Если вам нужно сгенерировать PDF, вы можете использовать следующий пример с использованием `reportlab`:

```python
from reportlab.lib import colors
from reportlab.lib.pagesizes import letter
from reportlab.platypus import SimpleDocTemplate, Table, TableStyle

data = [['День', 'Время', 'Олимпиада'],
        ['Понедельник', '09:00 - 11:00', 'Математика'],
        ['Понедельник', '11:00 - 13:00', 'Физика'],
        ['Вторник', '09:00 - 11:00', 'Химия'],
        ['Вторник', '11:00 - 13:00', 'Биология']]

pdf = SimpleDocTemplate("schedule.pdf", pagesize=letter)
table = Table(data)
style = TableStyle([('BACKGROUND', (0, 0), (-1, 0), colors.grey),
                    ('TEXTCOLOR', (0, 0), (-1, 0), colors.whitesmoke),
                    ('ALIGN', (0, 0), (-1, -1), 'CENTER'),
                    ('FONTNAME', (0, 0), (-1, 0), 'Helvetica-Bold'),
                    ('BOTTOMPADDING', (0, 0), (-1, 0), 12),
                    ('BACKGROUND', (0, 1), (-1, -1), colors.beige),
                    ('GRID', (0, 0), (-1, -1), 1, colors.black)])

table.setStyle(style)
elements = [table]
pdf.build(elements)
```

Этот код создаёт PDF-файл с таблицей. Объединенные ячейки в PDF можно делать вручную, установив правильные размеры, но это требует больше контроля над позициями значений в ячейках.

### Заключение

Если у вас
Значение объединённой ячейки находится в левой/верхней "оригинальной" ячейке из состава объединённой. 
Так что если у тебя есть столбец с объединённой ячейкой, делай там простую логику типа такой:
last_results_publication_value = ''  # тут храним последнее увиденное значение столбца
for row in schedule_table.find_all('tr')[1:]:  # перебираем строки
    cells = row.find_all('td')
    subject = cells[0].get_text(strip=True)
    grades = cells[1].get_text(strip=True)
    dates = cells[2].get_text(strip=True)
    results_publication = cells[3].get_text(strip=True)
    if results_publication:  # если в столбце есть значение
        last_results_publication_value = results_publication  # запоминаем его как последнее виденное
    else:  # а если нет
        results_publication = last_results_publication_value  # используем вместо него последнее виденное
    ...  # дальше используем значения
Проверить у первой клетки наличие атрибута rowspan 
if cells[0].get('rowspan'):
    ...

и если он есть, то не принтить данные сразу, а сохранить в переменную и в следующей итерации цикла, добавить к ним данные и вывести из в консоль
Похожие вопросы