from io import BytesIO from openpyxl import Workbook from openpyxl.utils import get_column_letter from openpyxl.styles import Font, PatternFill def build_report_workbook(title, columns, rows): workbook = Workbook() worksheet = workbook.active worksheet.title = "Report" headers = [column["label"] for column in columns] worksheet.append([title]) worksheet.merge_cells( start_row=1, start_column=1, end_row=1, end_column=max(len(columns), 1), ) worksheet["A1"].font = Font(bold=True, size=14) if columns: worksheet.append(headers) for cell in worksheet[2]: cell.font = Font(bold=True) cell.fill = PatternFill("solid", fgColor="D9EAF7") for row in rows: worksheet.append([row.get(column["key"], "") for column in columns]) else: worksheet.append(["No data"]) for column_index, column_cells in enumerate(worksheet.columns, start=1): max_length = max(len(str(cell.value or "")) for cell in column_cells) worksheet.column_dimensions[get_column_letter(column_index)].width = min( max(max_length + 2, 12), 60, ) output = BytesIO() workbook.save(output) return output.getvalue()