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

如何调整Dash Ag-Grid列宽使其填充可用空间?

Dash Ag-Grid 列自动填充容器宽度失效问题解决

问题现象

使用Dash Ag-Grid构建表格时,设置columnSize="autoSize"或columnSize="sizeToFit"后,表格右侧仍留有大量空余空间,列无法自动填满整个容器宽度。即使在columnDefs中设置了width、minWidth、maxWidth等参数,问题依然存在。

核心原因

你的代码中通过回调延迟2秒加载columnDefs和rowData,但columnSize的自动调整逻辑是在AgGrid组件初始化时执行的。此时列定义和数据尚未加载完成,自动 sizing 无法基于实际内容计算宽度,导致失效。

另外,autoSize的作用是让列宽度适配内容的最小需求(不会主动填满容器),而sizeToFit才是让所有列的总宽度填满表格容器,但同样需要在列和数据都加载完成后执行才能生效。

解决方案

方案1:直接初始化列和数据(推荐)

移除延迟加载的回调,直接在AgGrid组件中设置columnDefs和rowData,让自动 sizing 在组件初始化时就能获取到完整的列和数据:

# 修改后的AgGrid核心配置
AgGrid(
    id="inventory_ag_grid",
    className="ag-theme-quartz",
    dashGridOptions={
        "skipHeaderOnAutoSize": False,
    },
    style={
        "height": "80vh",
        "width": "100%",
    },
    columnSize="sizeToFit",  # 使用sizeToFit让列填满容器
    columnDefs=get_inventory_columns(),  # 直接传入列定义
    rowData=df.to_dict("records"),  # 直接传入行数据
    defaultColDef={"resizable": True},
    getRowStyle={
        "styleConditions": [
            {
                "condition": "params.rowIndex % 2 === 0",
                "style": {
                    "backgroundColor": "rgba(0, 0, 0, 0.05)",
                },
            },
        ]
    },
)

同时删除原来的两个延迟加载回调函数,无需通过time.sleep等待。

方案2:动态加载时触发自动 sizing

如果必须动态加载列或数据,可通过回调调用AgGrid的sizeColumnsToFit方法,确保在数据/列加载完成后执行宽度调整:

# 新增触发自动调整的回调
@app.callback(
    Output("inventory_ag_grid", "columnSize"),
    Input("inventory_ag_grid", "rowData"),
    Input("inventory_ag_grid", "columnDefs"),
    prevent_initial_call=True
)
def trigger_size_to_fit(row_data, column_defs):
    return "sizeToFit"

优化列宽度分配

对于带换行的列(如description),可以在columnDefs中添加flex属性,让该列自动占据剩余空间,同时保留wrapText和autoHeight:

{
    "field": "description",
    "headerName": "Description",
    "cellDataType": "text",
    "wrapText": True,
    "autoHeight": True,
    "sortable": True,
    "resizable": True,
    "filter": True,
    "maxWidth": 600,
    "flex": 2,  # 数值越大,分配的剩余空间占比越高
},

修改后的完整代码

import pandas as pd
from dash import html, dash
from dash_ag_grid import AgGrid
import dash_bootstrap_components as dbc

rows = [
    {'warehouse_name': 'Stettler', 'part_name': 'part1', 'description': 'Piston Packing and Head O-Rings and lots more text so we can see what it\'s like when the column wraps and we have a really really long description that can\'t fit on one line', 'cost_cad': 5000.0, 'cost_usd': 3521.0, 'msrp_cad': 15001.0, 'msrp_usd': 12008.0, 'warehouse_quantity': 0.1, 'sold_quantity': 0.2, 'calc_quantity': 2.0, 'actual_quantity': None},
    {'warehouse_name': 'Stettler', 'part_name': 'part2', 'description': 'Rod Packing, ONE END ONLY', 'cost_cad': 545.0, 'cost_usd': 384.0, 'msrp_cad': 1636.0, 'msrp_usd': 1309.0, 'warehouse_quantity': 0.0, 'sold_quantity': 0.4, 'calc_quantity': 2.0, 'actual_quantity': None},
    {'warehouse_name': 'Stettler', 'part_name': 'part3', 'description': 'Hydraulic Piston Seals & O-Rings, ONE END ONLY', 'cost_cad': 272.0, 'cost_usd': 192.0, 'msrp_cad': 816.0, 'msrp_usd': 653.0, 'warehouse_quantity': 1.6, 'sold_quantity': 0.4, 'calc_quantity': 2.0, 'actual_quantity': None}
]
df = pd.DataFrame(rows)

def get_inventory_columns() -> list:
    price_col = "cost_cad"
    header_name = "Part Cost CAD"

    columns = [
        {
            "field": "warehouse_name",
            "headerName": "Warehouse Name",
            "sortable": True,
            "resizable": True,
            "filter": True,
            "flex": 1,
        },
        {
            "field": "part_name",
            "headerName": "Part Number",
            "cellDataType": "text",
            "wrapText": True,
            "sortable": True,
            "resizable": True,
            "filter": True,
            "flex": 1,
        },
        {
            "field": "description",
            "headerName": "Description",
            "cellDataType": "text",
            "wrapText": True,
            "autoHeight": True,
            "sortable": True,
            "resizable": True,
            "filter": True,
            "maxWidth": 600,
            "flex": 2,
        },
        {
            "field": price_col,
            "headerName": header_name,
            "sortable": True,
            "resizable": True,
            "filter": True,
            "flex": 1,
        },
        {
            "field": "warehouse_quantity",
            "headerName": "Warehouse Quantity from BoM",
            "sortable": True,
            "resizable": True,
            "filter": True,
            "flex": 1,
        },
        {
            "field": "sold_quantity",
            "headerName": "Sold Quantity",
            "sortable": True,
            "resizable": True,
            "filter": True,
            "flex": 1,
        },
        {
            "field": "calc_quantity",
            "headerName": "Calculated Avg Quantity",
            "sortable": True,
            "resizable": True,
            "filter": True,
            "flex": 1,
        },
        {
            "field": "actual_quantity",
            "headerName": "Actual Quantity",
            "sortable": True,
            "resizable": True,
            "filter": True,
            "editable": True,
            "flex": 1,
        },
    ]
    return columns

app = dash.Dash(__name__)

app.layout = html.Div(
    [
        html.H1("Ag-Grid Example"),
        dbc.Spinner(
            id="inventory_col",
            color="success",
            children=AgGrid(
                id="inventory_ag_grid",
                className="ag-theme-quartz",
                dashGridOptions={
                    "skipHeaderOnAutoSize": False,
                },
                style={
                    "height": "80vh",
                    "width": "100%",
                },
                columnSize="sizeToFit",
                columnDefs=get_inventory_columns(),
                rowData=df.to_dict("records"),
                defaultColDef={"resizable": True},
                getRowStyle={
                    "styleConditions": [
                        {
                            "condition": "params.rowIndex % 2 === 0",
                            "style": {
                                "backgroundColor": "rgba(0, 0, 0, 0.05)",
                            },
                        },
                    ]
                },
            ),
        ),
    ]
)

if __name__ == "__main__":
    app.run_server(debug=True)

内容的提问来源于stack exchange,提问作者Sean McCarthy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 15:45:57