You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django项目中用openpyxl实现Excel双表头及内容排版问题

在Django里用openpyxl做符合要求的双表头Excel导出

要实现你要的双表头+组织信息和用户信息对应展示的效果,关键要抓两点:

  • 搭好两层表头:第一层用合并单元格做分组标题,第二层写具体的字段名
  • 处理组织和用户的关联数据:同一个组织的所有用户,对应的组织信息单元格要跨行合并,避免重复显示

调整后的完整代码

假设你的Organisation和User模型是通过外键关联的(比如User里有organisation外键字段),下面是可以直接用的导出代码:

from django.http import HttpResponse
from openpyxl import Workbook
from openpyxl.styles import Font, Alignment
from openpyxl.utils import get_column_letter
from openpyxl.styles.borders import Border, Side
from .models import Organisation, User  # 替换成你项目的模型导入路径

def export_org_users_excel(request):
    # 初始化工作簿和工作表
    wb = Workbook()
    ws = wb.active
    ws.title = "组织用户信息"

    # 定义常用样式:加粗、居中、细边框
    bold_font = Font(bold=True)
    center_align = Alignment(horizontal='center', vertical='center')
    thin_border = Border(
        left=Side(style='thin'),
        right=Side(style='thin'),
        top=Side(style='thin'),
        bottom=Side(style='thin')
    )

    # 第一层表头:分组标题(合并单元格)
    ws.merge_cells('A1:C1')
    org_group_cell = ws['A1']
    org_group_cell.value = "组织信息"
    org_group_cell.font = bold_font
    org_group_cell.alignment = center_align

    ws.merge_cells('D1:F1')
    user_group_cell = ws['D1']
    user_group_cell.value = "用户信息"
    user_group_cell.font = bold_font
    user_group_cell.alignment = center_align

    # 第二层表头:具体字段
    field_headers = [
        "组织名称", "注册日期", "语言",
        "名字", "姓氏", "邮箱"
    ]
    for col_num, header in enumerate(field_headers, 1):
        cell = ws.cell(row=2, column=col_num, value=header)
        cell.font = bold_font
        cell.alignment = center_align
        cell.border = thin_border

    # 填充数据并处理合并单元格
    current_row = 3
    # 获取你要导出的指定组织(替换成你的筛选逻辑,比如按ID取)
    target_orgs = Organisation.objects.all()  # 示例:取所有组织,可改成get(pk=request.GET.get('org_id'))
    for org in target_orgs:
        users = org.user_set.all()  # 关联用户,根据你的外键关系调整
        if not users:
            continue
        # 组织信息需要合并的行数 = 当前组织的用户数量
        merge_count = len(users)

        # 写入组织信息并合并单元格
        # 组织名称
        ws.merge_cells(f'A{current_row}:A{current_row + merge_count - 1}')
        name_cell = ws.cell(row=current_row, column=1, value=org.name)
        name_cell.alignment = center_align
        name_cell.border = thin_border

        # 注册日期(转成易读的字符串格式)
        ws.merge_cells(f'B{current_row}:B{current_row + merge_count - 1}')
        date_cell = ws.cell(row=current_row, column=2, value=org.signup_date.strftime("%Y-%m-%d"))
        date_cell.alignment = center_align
        date_cell.border = thin_border

        # 语言
        ws.merge_cells(f'C{current_row}:C{current_row + merge_count - 1}')
        lang_cell = ws.cell(row=current_row, column=3, value=org.language)
        lang_cell.alignment = center_align
        lang_cell.border = thin_border

        # 逐个写入用户信息
        for user in users:
            # 名字
            ws.cell(row=current_row, column=4, value=user.first_name).border = thin_border
            # 姓氏
            ws.cell(row=current_row, column=5, value=user.last_name).border = thin_border
            # 邮箱
            ws.cell(row=current_row, column=6, value=user.email).border = thin_border

            current_row += 1

    # 调整列宽,避免内容被截断
    for col in range(1, 7):
        ws.column_dimensions[get_column_letter(col)].width = 20

    # 生成响应,返回Excel文件
    response = HttpResponse(content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
    response['Content-Disposition'] = 'attachment; filename="组织用户信息.xlsx"'
    wb.save(response)
    return response

关键调整说明

  1. 双表头结构:第一行用合并单元格区分“组织信息”和“用户信息”两个分组,第二行明确列出每个字段,完全匹配你要的双表头需求
  2. 组织信息合并:同一个组织的所有用户,对应的组织名称、注册日期、语言单元格会自动合并成一个大单元格,不会重复显示相同的组织信息
  3. 样式优化:给表头加粗、内容居中,加上细边框,让表格看起来更清晰易读
  4. 数据对应:每个用户的信息和所属组织的信息在同一行的不同列,完全符合你的预期展示逻辑

要注意的细节

  • 把代码里的模型字段(比如org.name、user.first_name)改成你项目里实际的字段名
  • 如果不需要第一层的分组标题,可以直接删掉第一行合并单元格的代码,从第二行开始写所有字段表头就行
  • 日期格式可以通过strftime的参数调整成你想要的样式(比如"%m/%d/%Y")

内容的提问来源于stack exchange,提问作者Ilian Gion Häsler

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 00:32:52