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

批量读取2000+Excel文件到DataFrame时触发rId1 not found报错

报错产生原因

read_excel(readxl包)读取xlsx格式文件时,本质是将文件作为压缩包解压后读取内部存储关系映射的XML配置,rId1 not found报错的核心触发原因是解析时找不到对应关系ID指向的文件组件,并非只有过旧Excel格式才会触发,批量读取大量文件时常见触发场景如下:

  • 文件匹配规则存在漏洞:代码里用的pattern = "*xls"是模糊匹配,会把后缀带xls字符的所有文件都纳入读取范围,最常见的是Excel打开文件时自动生成的~$xxx.xlsx隐藏临时锁文件,这类文件不是合法的完整Excel文件,没有完整的内部结构,解析时必然触发该报错。文件量小时文件夹内无残留临时文件/未打开任何Excel文件就不会触发,文件量上升后,操作过程中打开过Excel、或是之前异常退出残留的锁文件都会被匹配到。
  • 异常文件混入:2000个文件的样本量下,很容易混入后缀被手动改成.xls/.xlsx的非Excel文件(比如改了后缀的csv、html表格、损坏的半截文件),这类文件同样不满足Excel内部结构要求,会触发报错。之前读取100个文件时未混入这类异常文件,因此运行正常。
  • 代码本身存在逻辑缺陷:原for循环每次读取都会直接覆盖data变量,即便不报错最终也只会留存最后一个文件的内容;第一版purrr写法中先取全路径又调用basename()裁掉路径,再重新拼接路径时如果工作路径设置不对,也可能出现路径匹配偏差。
解决方案
  • 第一步:修正文件匹配规则,过滤无效文件
    不要用模糊匹配规则,改用正则精准匹配.xls/.xlsx后缀,同时过滤掉Excel自动生成的临时锁文件,注意R中路径写正斜杠,不要用Windows默认的反斜杠:
library(tidyverse)
library(readxl)
# 设置文件存储路径
target_path <- "C:/your_file_path/"
# 精准匹配合法Excel文件
valid_files <- list.files(
  path = target_path,
  pattern = "\\.(xls|xlsx)$",
  full.names = TRUE
)
# 过滤~$开头的临时锁文件
valid_files <- valid_files[!grepl("~\\$", basename(valid_files))]
  • 第二步:加容错机制,定位异常文件
    给读取逻辑加错误捕获,不会因为单个坏文件中断整个批量流程,同时可以直接定位到出问题的具体文件,不用挨个排查:
# 构造安全读取函数,读取失败时返回错误信息不中断流程
safe_read <- safely(~read_excel(.x, col_types = "text"))

read_res <- tibble(file = valid_files) %>%
  mutate(
    res = map(file, safe_read),
    content = map(res, "result"),
    err = map(res, "error")
  )

# 提取读取失败的文件及对应报错
failed_files <- read_res %>%
  filter(!map_lgl(err, is.null)) %>%
  mutate(err_msg = map_chr(err, as.character)) %>%
  select(file, err_msg)
  • 第三步:处理异常文件+合并有效数据
    查看failed_files里的异常文件:如果是残留临时文件直接删除即可;如果是后缀错误/格式损坏的文件,手动打开后另存为标准.xlsx格式再重新读取。最后把所有读取成功的文件合并成一个DataFrame即可:
# 合并所有读取成功的文件,加来源文件列方便溯源
final_data <- read_res %>%
  filter(map_lgl(err, is.null)) %>%
  transmute(file, content) %>%
  unnest(content)
  • 如果习惯用for循环实现,修正原来的覆盖变量bug即可:
# 先创建和文件数量等长的列表存结果,避免每次循环覆盖变量
data_list <- vector("list", length(valid_files))
for (i in seq_along(valid_files)) {
  data_list[[i]] <- read_excel(valid_files[i], col_types = "text")
  # 可选加进度提示,每读100个文件输出一次进度
  if (i %% 100 == 0) message("已完成", i, "个文件读取")
}
# 最后合并所有数据
final_data_loop <- bind_rows(data_list, .id = "file_seq")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 02:36:10