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

如何在ASP.NET MVC中导出5层级jqGrid的全部数据至Excel?

解决jqGrid多层级数据完整导出到Excel的问题

我明白你现在的痛点——用jqGrid 5.3.0做的5层级嵌套网格,自带的exportToExcel只能导出当前展开的那一层数据,没法一次性把所有层级的子网格数据都导进Excel。结合你给出的2层级实现代码,我给你分享两个最实用的解决方案:


方案一:手动递归收集所有层级数据,后端生成Excel(推荐)

这个方案的核心是先通过前端JavaScript递归遍历主网格和所有子网格,把所有行数据收集到一个统一的数组里,再传给后端用Excel库生成完整的Excel文件。这种方式完全可控,适合复杂的多层级场景。

步骤1:编写前端递归收集数据的函数

你可以基于现有的子网格ID命名规则(比如GR{parentRowID}_table),写一个递归函数遍历所有层级:

// 收集所有层级的网格数据
function collectAllGridData() {
    const allData = [];
    
    // 先收集主网格的所有行
    const mainGridRows = $("#jqGrid").jqGrid('getRowData');
    mainGridRows.forEach(mainRow => {
        // 标记当前行的层级,方便Excel里区分
        mainRow.level = 1;
        allData.push(mainRow);
        // 递归收集当前行的子网格数据
        collectSubGridData(mainRow.ArchiveChecklistMainId_fk, 2, allData);
    });

    return allData;
}

// 递归收集子网格数据
function collectSubGridData(parentId, currentLevel, allData) {
    // 根据父ID找到对应的子网格实例
    const childGridSelector = `#GR${parentId}_table`;
    const childGrid = $(childGridSelector);
    
    if (childGrid.length === 0) return;

    // 获取子网格的所有行数据
    const childRows = childGrid.jqGrid('getRowData');
    childRows.forEach(childRow => {
        childRow.level = currentLevel;
        childRow.parentId = parentId; // 记录父ID,方便关联
        allData.push(childRow);
        
        // 继续递归收集下一级子网格(这里假设第三层级的主键是Coding_Id,根据你的实际结构调整)
        collectSubGridData(childRow.Coding_Id, currentLevel + 1, allData);
    });
}

步骤2:前端触发导出请求

添加一个导出按钮,点击时调用收集函数,把数据传给后端:

// 绑定导出按钮点击事件
$("#exportAllBtn").click(function() {
    const allGridData = collectAllGridData();
    
    $.ajax({
        url: '@Url.Action("ExportAllGridData", "Report")',
        type: 'POST',
        contentType: 'application/json',
        data: JSON.stringify(allGridData),
        xhrFields: {
            responseType: 'blob' // 接收二进制文件
        },
        success: function(blob) {
            // 创建下载链接并触发下载
            const url = window.URL.createObjectURL(blob);
            const a = document.createElement('a');
            a.href = url;
            a.download = `GridFullData_${new Date().toISOString().slice(0,10)}.xlsx`;
            document.body.appendChild(a);
            a.click();
            // 清理资源
            window.URL.revokeObjectURL(url);
            document.body.removeChild(a);
        }
    });
});

步骤3:后端用EPPlus生成Excel

在ASP.NET MVC后端安装EPPlus库(NuGet搜索EPPlus),然后编写导出接口:

using OfficeOpenXml;
using System.IO;
using System.Web.Mvc;

public class ReportController : Controller
{
    [HttpPost]
    public ActionResult ExportAllGridData(dynamic[] gridData)
    {
        // 初始化Excel包
        using var package = new ExcelPackage();
        var worksheet = package.Workbook.Worksheets.Add("Full Grid Data");

        // 设置表头(根据你的网格列名调整,这里合并主/子网格的列)
        var headers = new[] { "层级", "Transmittal No", "主题", "日期", "延迟数", "编码", "版本" };
        for (int i = 0; i < headers.Length; i++)
        {
            worksheet.Cells[1, i + 1].Value = headers[i];
            worksheet.Cells[1, i + 1].Style.Font.Bold = true;
        }

        // 填充数据行
        int rowIndex = 2;
        foreach (var row in gridData)
        {
            worksheet.Cells[rowIndex, 1].Value = row.level;
            // 主网格列
            worksheet.Cells[rowIndex, 2].Value = row.trans_ref_no ?? string.Empty;
            worksheet.Cells[rowIndex, 3].Value = row.ChkMain_Subject ?? string.Empty;
            worksheet.Cells[rowIndex, 4].Value = row.trans_date ?? string.Empty;
            worksheet.Cells[rowIndex, 5].Value = row.sum_delay_count ?? string.Empty;
            // 子网格列
            worksheet.Cells[rowIndex, 6].Value = row.comp_code ?? string.Empty;
            worksheet.Cells[rowIndex, 7].Value = row.revision ?? string.Empty;

            // 给不同层级设置缩进,增强可读性
            if (row.level > 1)
            {
                worksheet.Cells[rowIndex, 2].Style.Indent = row.level - 1;
            }

            rowIndex++;
        }

        // 自动调整列宽
        worksheet.Cells.AutoFitColumns();

        // 生成文件流并返回
        var stream = new MemoryStream();
        package.SaveAs(stream);
        stream.Position = 0;

        return File(stream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "FullGridData.xlsx");
    }
}

方案二:扩展jqGrid的exportToExcel方法

如果你想复用jqGrid自带的导出逻辑,可以修改或扩展exportToExcel方法,让它递归遍历子网格。不过这个方法需要熟悉jqGrid的源码实现,适合有一定源码基础的开发者:

  1. 找到jqGrid中exportToExcel的实现部分(通常在grid.export.js文件里)
  2. 在收集当前网格行数据的代码后,添加递归逻辑,遍历当前行的子网格,收集子行数据并添加到导出列表中
  3. 注意处理子网格列和主网格列的合并,避免表头重复

注意事项

  • 确保所有子网格的数据都已加载:如果你的子网格是动态加载(loadonce: false),需要在收集数据前先展开所有子网格,确保数据已加载到本地
  • 层级标识:在Excel里可以用缩进、背景色或字体样式区分不同层级,提高可读性
  • 列名兼容:如果不同层级的网格列名不同,需要在后端处理列的映射和填充

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:42:27