Excel (XLSX) 导出样式

版本 16 中引入

get_xlsx_styles 模块方法允许你为报表导出定义自定义 Excel 样式。

注意: 此方法仅在将标准脚本报表或查询报表导出为 Excel 格式(非 CSV)时被调用。

基本用法

在报表的 Python 文件中定义一个 get_xlsx_styles 函数:

from frappe.utils.xlsxutils import XLSXMetadata, XLSXStyleBuilder

def get_xlsx_styles(metadata: XLSXMetadata) -> dict:
    builder = XLSXStyleBuilder(metadata)

    # Add your custom styles here...
    return builder.result

注意: 当 XLSXStyleBuilder 初始化时,默认样式(表头、筛选器、字段类型格式、货币)会自动应用。

要禁用此功能,请传入 default_styling=False:

builder = XLSXStyleBuilder(metadata, default_styling=False)

XLSXMetadata

metadata 对象提供对报表数据和辅助方法的访问。

属性

属性 类型 描述
report_name str 报表名称
filters dict 原始筛选值
column_map dict[int, dict] 列索引 → 列定义
row_map dict[int, dict \| list] 行索引 → 行数据
applied_filters_map dict[int, list] 筛选行索引 → [标签, 值]
has_total_row bool 最后一行是否为合计行
has_indentation bool 是否应用缩进样式

注意: 所有索引必须从 0 开始,遵循 XlsxWriter 的索引规则。

XLSXStyleBuilder

该构建器提供注册和应用样式的方法。

注册样式

# Register a style and get its ID
style_id = builder.register_style({"bold": True, "bg_color": "#FFFF00"})

应用样式

# Style an entire column
builder.style_column(col_idx, style_id)

# Style an entire row
builder.style_row(row_idx, style_id)

# Style a specific cell
builder.style_cell(row_idx, col_idx, style_id)

样式属性

字体样式

builder.register_style({
    "bold": True,
    "italic": True,
    "underline": True,
    "font_size": 12,
    "font_color": "#FF0000",
    "font_name": "Arial",
})

背景颜色

builder.register_style({
    "bg_color": "#FFFF00",
})

边框

# Border thickness: 1 = thin, 2 = medium, 3 = thick
builder.register_style({
    "border": 1,
    "border_color": "#000000",
})

# Individual borders
builder.register_style({
    "left": 2,
    "right": 2,
    "top": 1,
    "bottom": 3,
})

对齐方式

builder.register_style({
    "align": "center",           # left, center, right
    "valign": "vcenter",         # top, vcenter, bottom
    "text_wrap": True,
    "indent": 2,

})

数字格式

builder.register_style({
    "num_format": "#,##0.00",    # Custom number format

})

完整示例

from frappe.utils.xlsxutils import XLSXMetadata, XLSXStyleBuilder

def get_xlsx_styles(metadata: XLSXMetadata) -> dict:
    builder = XLSXStyleBuilder(metadata)

    # --- Register Styles (do this once, reuse style_id) --- #
    success_style = builder.register_style({"font_color": "#006100", "bg_color": "#C6EFCE"})
    warning_style = builder.register_style({"font_color": "#9C5700", "bg_color": "#FFEB9C"})
    error_style = builder.register_style({"font_color": "#9C0006", "bg_color": "#FFC7CE"})
    highlight_style = builder.register_style({"bold": True, "bg_color": "#DDEBF7"})
    total_row_border = builder.register_style({"border": 3, "border_color": "#15137e"})
    right_align = builder.register_style({"align": "right"})

    # --- Style entire column --- #
    amount_col_idx = builder.field_index_map.get("net_amount")

    if amount_col_idx is not None:
        builder.style_column(amount_col_idx, right_align)

    # --- Style total row with border --- #
    if metadata.has_total_row:
        builder.style_row(metadata.get_last_row_index(), total_row_border)

    # --- Conditional Cell Styling --- #
    status_col_idx = builder.field_index_map.get("status")

    for row_idx, row_data in metadata.row_map.items():
        if not isinstance(row_data, dict):
            continue

        # Status-based styling
        if status_col_idx is not None:
            status = row_data.get("status")

            if status == "Completed":
                builder.style_cell(row_idx, status_col_idx, success_style)

            elif status == "Pending":
                builder.style_cell(row_idx, status_col_idx, warning_style)

            elif status == "Cancelled":
                builder.style_cell(row_idx, status_col_idx, error_style)

        # High value highlighting
        if amount_col_idx is not None:
            amount = row_data.get("net_amount")

            if amount and amount > 10000:
                builder.style_cell(row_idx, amount_col_idx, highlight_style)

    return builder.result

示例输出


带样式的导出示例

建议

  • 注册一次样式并重复使用 — 在开始时注册样式,并在整个过程中使用返回的 style_id,以避免创建重复样式。

参考

  • 有关所有可用的样式属性,请访问 xlsxwriter 格式文档。