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

如何在JavaScript中读取两个独立CSV文件并实现数据关联?

解决两个CSV文件读取后关联合并的问题

原代码的核心问题

  • project 和 participants 变量在for循环内部声明,每次循环都会重置,异步读取完成后无法保留有效数据
  • FileReader 是异步操作,循环执行完毕时文件可能还没读取完成,此时调用合并逻辑会拿到空值

修改后的完整实现

HTML部分(保持不变)

<form id="categoryform">
  <input type="file" id="projectCsvFileInput" multiple><br><br>
  <input type="submit">
</form>

JavaScript部分(修复异步问题+添加合并逻辑)

// 全局存储两个文件的数据,避免循环内变量重置
let projectData = [];
let participantsData = [];
// 计数器:统计已读取完成的文件数量
let loadedFileCount = 0;

categoryform.addEventListener("submit", function (e) {
  e.preventDefault();
  // 每次提交重置数据和计数器
  projectData = [];
  participantsData = [];
  loadedFileCount = 0;

  const uploadedFiles = projectCsvFileInput.files;
  // 先校验是否上传了两个文件
  if (uploadedFiles.length !== 2) {
    alert("请上传两个CSV文件");
    return;
  }

  // 遍历处理每个文件
  for (let i = 0; i < uploadedFiles.length; i++) {
    const file = uploadedFiles[i];
    const reader = new FileReader();

    reader.onload = function(event) {
      const fileContent = event.target.result;
      // 根据表头区分文件类型
      if (fileContent.includes('Project Name')) {
        projectData = csvToArr(fileContent, ",");
      } else {
        participantsData = csvToArr(fileContent, ",");
      }

      loadedFileCount++;
      // 两个文件都读取完成后,执行合并逻辑
      if (loadedFileCount === 2) {
        // 这里传入关联字段,比如用"Project Name"作为匹配键
        const mergedResult = mergeCsvByKey(projectData, participantsData, "Project Name");
        console.log("合并后的数据:", mergedResult);
        // 可在这里添加后续处理,比如渲染到页面、导出等
      }
    };

    reader.readAsText(file);
  }
});

// CSV转数组对象的工具函数(优化了字符清理逻辑)
function csvToArr(stringVal, splitter) {
  const [headerKeys, ...rows] = stringVal
    .trim()
    .split("\n")
    .map(item => item.split(splitter));

  return rows.map(row => {
    const rowObj = {};
    headerKeys.forEach((key, index) => {
      // 清理多余的换行符、引号和无效字符
      const cleanKey = key.replace('\r', '').trim();
      const cleanValue = row[index]?.replace('\r', '').replace('"', '').replace('/S', '').trim() || "";
      rowObj[cleanKey] = cleanValue;
    });
    return rowObj;
  });
}

// 基于指定字段关联合并两个CSV数据的函数
function mergeCsvByKey(projectList, participantList, joinKey) {
  // 将项目数据转为Map,提升匹配效率
  const projectMap = new Map();
  projectList.forEach(project => {
    const keyValue = project[joinKey];
    if (keyValue) projectMap.set(keyValue, project);
  });

  // 遍历参与者数据,匹配对应项目信息并合并
  return participantList.map(participant => {
    const matchedProject = projectMap.get(participant[joinKey]) || {};
    // 合并对象,参与者字段会覆盖项目中同名字段(如有)
    return { ...matchedProject, ...participant };
  });
}

关键优化点

  1. 新增文件数量校验,避免用户上传数量不符
  2. 用计数器等待所有异步读取完成后再执行合并,解决异步时序问题
  3. 使用Map存储项目数据,比嵌套循环匹配效率更高
  4. 优化CSV解析的字符清理逻辑,减少无效数据干扰

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 17:56:31