0

0

JavaScript 递归提取嵌套表格数据并导出为标准 CSV 教程

霞舞

霞舞

发布时间:2026-03-12 20:57:22

|

986人浏览过

|

来源于php中文网

原创

JavaScript 递归提取嵌套表格数据并导出为标准 CSV 教程

本文详解如何正确遍历含嵌套 <table> 的 HTML 表格结构,递归提取所有有效数据行(跳过 colspan 占位行和空嵌套容器),生成格式规范、行列对齐的 CSV 文件。

本文详解如何正确遍历含嵌套 `

` 的 html 表格结构,递归提取所有有效数据行(跳过 `colspan` 占位行和空嵌套容器),生成格式规范、行列对齐的 csv 文件。

在实际前端开发中,动态渲染的层级化数据常通过嵌套 <table> 实现(如“主用户 + 关联子用户”结构)。但直接使用 querySelectorAll('tbody tr') 会将包裹嵌套表的 <tr>(如含 colspan="3" 的占位行)误判为有效数据行,导致 CSV 输出错乱——例如把整个嵌套表内容拼接成单个单元格,或遗漏深层嵌套行。

根本问题在于:必须区分“展示占位行”与“真实数据行”。理想策略是:
✅ 仅提取具有完整列数(如 3 列)的 <tr>;
✅ 对含嵌套 <table> 的 <td>,递归进入其 <tbody> 提取子行;
❌ 跳过 colspan > 1 的 <td> 所在行(它们本身不承载数据,仅作容器);
❌ 忽略无 <td> 或 <td> 数量不匹配的无效行。

以下为健壮、可复用的实现方案:

/**
 * 从 DOM 表格中提取所有扁平化数据行(支持嵌套 table)
 * @param {HTMLTableElement} table - 根表格元素
 * @returns {string[][]} 二维数组,每项为一行的字符串值数组
 */
function extractTableData(table) {
  const headers = Array.from(table.querySelectorAll('thead th'))
    .map(th => th.textContent.trim());

  const rows = [];

  // 递归处理指定节点下的所有 tbody > tr
  function collectRows(context) {
    const tbodyElements = context.querySelectorAll('tbody');
    tbodyElements.forEach(tbody => {
      tbody.querySelectorAll('tr').forEach(tr => {
        // 跳过包含 colspan 占位单元格的行(它们不是数据行)
        const hasColspanCell = tr.querySelector('td[colspan], th[colspan]');
        if (hasColspanCell) {
          // 递归提取该单元格内嵌套的 table 数据
          const nestedTables = tr.querySelectorAll('td table, th table');
          nestedTables.forEach(nestedTable => {
            collectRows(nestedTable);
          });
          return;
        }

        // 提取当前行的有效 td/th 文本
        const cells = Array.from(tr.querySelectorAll('td, th'))
          .map(cell => cell.textContent.trim());

        // 仅保留列数与 header 匹配的行(确保结构一致)
        if (cells.length === headers.length && cells.some(cell => cell !== '')) {
          rows.push(cells);
        }
      });
    });
  }

  collectRows(table);
  return [headers, ...rows];
}

/**
 * 将二维数组转换为 CSV 字符串(自动转义含逗号/换行/引号的字段)
 * @param {string[][]} data - 行数据二维数组
 * @returns {string} CSV 格式字符串
 */
function arrayToCsv(data) {
  return data.map(row => 
    row.map(cell => {
      // 若字段含逗号、双引号或换行符,用双引号包裹,并将内部双引号转义为两个双引号
      if (/[,\"\n\r]/.test(cell)) {
        return `"${cell.replace(/"/g, '""')}"`;
      }
      return cell;
    }).join(',')
  ).join('\n');
}

/**
 * 触发 CSV 文件下载
 * @param {string} csvContent - CSV 字符串
 * @param {string} filename - 下载文件名(默认 GfG.csv)
 */
function downloadCsv(csvContent, filename = 'GfG.csv') {
  const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
  const url = URL.createObjectURL(blob);
  const link = document.createElement('a');
  link.href = url;
  link.download = filename;
  link.style.display = 'none';
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);
  URL.revokeObjectURL(url); // 清理内存
}

// 使用示例
function exportToCsv() {
  const table = document.querySelector('table');
  if (!table) return;

  try {
    const data = extractTableData(table);
    const csv = arrayToCsv(data);
    console.log('Generated CSV:\n', csv);
    downloadCsv(csv);
  } catch (err) {
    console.error('CSV export failed:', err);
  }
}

关键设计说明

  • extractTableData() 采用深度优先递归,精准跳过 colspan 占位行,只从真正承载数据的 <tr> 中提取单元格;
  • arrayToCsv() 实现 RFC 4180 兼容的 CSV 转义逻辑(处理逗号、换行、引号),避免 Excel 解析错误;
  • 所有 DOM 查询均使用现代 Array.from() 和箭头函数,简洁且兼容主流浏览器(IE11+ 需加 polyfill);
  • 错误边界已封装在 try/catch 中,保障生产环境鲁棒性。

调用 exportToCsv() 即可一键导出如下标准 CSV(以题干示例结构为准):

绘蛙
绘蛙

电商场景的AI创作平台,无需高薪聘请商拍和文案团队,使用绘蛙即可低成本、批量创作优质的商拍图、种草文案

下载

立即学习Java免费学习笔记(深入)”;

Name,Age,Town
Tom,20,London
Jack,30,Glasgow
Sam,40,Belfast
Alex,50,Hull
Josh,20,Cardiff

⚠️ 注意事项

  • 确保目标 <table> 具有明确的 <thead> 和 <tbody> 结构,否则需调整选择器;
  • 若嵌套表存在多级(如表中套表再套表),本方案仍适用,因 collectRows() 会持续递归;
  • 如需支持中文 Excel 正确显示,请在 downloadCsv 中将 Blob 类型改为 'text/csv;charset=utf-8;'(已内置);
  • 对超大表格(>10,000 行),建议添加节流或 Web Worker 优化性能。

此方案兼顾可读性、健壮性与工业级可用性,可直接集成至管理后台、报表系统等需要动态导出场景。

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
DOM是什么意思
DOM是什么意思

dom的英文全称是documentobjectmodel,表示文件对象模型,是w3c组织推荐的处理可扩展置标语言的标准编程接口;dom是html文档的内存中对象表示,它提供了使用javascript与网页交互的方式。想了解更多的相关内容,可以阅读本专题下面的文章。

4336

2024.08.14

excel对比两列数据异同
excel对比两列数据异同

Excel作为数据的小型载体,在日常工作中经常会遇到需要核对两列数据的情况,本专题为大家提供excel对比两列数据异同相关的文章,大家可以免费体验。

1454

2023.07.25

excel重复项筛选标色
excel重复项筛选标色

excel的重复项筛选标色功能使我们能够快速找到和处理数据中的重复值。本专题为大家提供excel重复项筛选标色的相关的文章、下载、课程内容,供大家免费下载体验。

428

2023.07.31

excel复制表格怎么复制出来和原来一样大
excel复制表格怎么复制出来和原来一样大

本专题为大家带来excel复制表格怎么复制出来和原来一样大相关文章,帮助大家解决问题。

572

2023.08.02

excel表格斜线一分为二
excel表格斜线一分为二

在Excel表格中,我们可以使用斜线将单元格一分为二。本专题为大家带来excel表格斜线一分为二怎么弄的相关文章,希望可以帮到大家。

1264

2023.08.02

excel斜线表头一分为二
excel斜线表头一分为二

excel斜线表头一分为二的方法有使用合并单元格功能方法、使用文本框功能方法、使用自定义格式方法。本专题为大家提供excel斜线表头一分为二相关的各种文章、以及下载和课程。

376

2023.08.02

绝对引用的输入方法
绝对引用的输入方法

绝对引用允许在公式中引用一个固定的单元格,而不会随着公式的复制和粘贴而改变引用的单元格。本专题为大家提供绝对引用相关内容的文章,大家可以免费体验。

4562

2023.08.09

java导出excel
java导出excel

在Java中,我们可以使用Apache POI库来导出Excel文件。本专题提供java导出excel的相关文章,大家可以免费体验。

464

2023.08.18

C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

76

2026.03.11

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号