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

如何将文件夹树中多个xlsx文件导入R?遇unzip错误求助

批量导入嵌套文件夹中XLSX文件的问题与解决

问题场景

路径C:/Users/XXX/Individual reports/下包含各州子文件夹,每个州文件夹内有2014-2023年的XLSX文件,文件名格式示例:(AK) FFY 2014 - Survey Results v1.xlsx。

尝试用以下代码批量读取文件:

library(tidyverse)
library(readxl)

file_path = ":/Users/XXX/Individual reports/"

df <- list.files(file_path,full.names = TRUE,pattern = ".xlsx",recursive = TRUE) %>%
  set_names(basename(.)) %>%
  map_df(.x = .,
         .f = read_xlsx,
         .id = "filename",
         sheet = "Table 5")

但触发错误:

> df <- list.files(file_path,full.names = TRUE,pattern = ".xlsx",recursive = TRUE) %>%
+   set_names(basename(.)) %>%
+   map_df(.x = .,
+          .f = read_xlsx,
+          .id = "filename",
+          sheet = 5)
Error in `map()`:
ℹ In index: 1.
ℹ With name: (AK) FFY 2014 - Synar Survey Results v1.xlsx.
Caused by error in `utils::unzip()`:
! zip file 'C:\Users\XXX\Individual reports\AK\(AK) FFY 2014 - Survey Results v1.xlsx' cannot be opened
Run `rlang::last_trace()` to see where the error occurred.

单独读取文件时也出现相同错误:

> df1 = read_xlsx(path = "C:/Users/XXX/Individual reports/AK/(AK) FFY 2014 - Survey Results v1.xlsx",
+                  sheet = 5)
Error in utils::unzip(zip_path, list = TRUE) : 
  zip file 'C:\Users\XXX\Individual reports\AK\(AK) FFY 2014 - Survey Results v1.xlsx' cannot be opened

错误原因

XLSX本质是ZIP压缩格式,readxl依赖utils::unzip解析,报错并非因为文件夹/文件被手动压缩,而是以下任一原因:

  • 文件本身损坏(比如下载/保存时出错)
  • 文件名包含特殊字符(如括号())导致解析异常
  • 文件被Excel或其他程序锁定
  • readxl版本与文件格式不兼容

解决方案

1. 先排查单个文件的可用性

  • 关闭所有打开目标XLSX文件的Excel窗口
  • 手动打开文件,确认能正常加载,无损坏提示
  • 尝试重命名文件,去掉括号等特殊字符(比如改为AK_FFY2014_Survey_Results_v1.xlsx),再用read_xlsx测试读取

2. 修正批量读取代码(带错误处理)

如果单个文件测试正常,用以下代码批量读取,同时跳过无法读取的文件,并提取文件名、州信息:

library(tidyverse)
library(readxl)

file_path <- "C:/Users/XXX/Individual reports/"

# 获取所有XLSX文件的完整路径(正则匹配.xlsx需加转义符\\)
all_files <- list.files(file_path, full.names = TRUE, pattern = "\\.xlsx$", recursive = TRUE)

# 定义带错误捕获的读取函数
read_safe_xlsx <- function(file) {
  tryCatch(
    read_xlsx(file, sheet = "Table 5"),
    error = function(e) {
      message(paste("跳过无法读取的文件:", file))
      return(NULL)
    }
  )
}

# 批量读取并合并数据,同时添加文件元信息
df <- map_df(all_files, ~{
  # 从文件名提取州代码(比如从(AK)中提取AK)
  state_code <- str_extract(basename(.x), "\\(([A-Z]{2})\\)") %>% str_remove_all("\\(|\\)")
  # 读取文件并绑定元信息
  read_safe_xlsx(.x) %>%
    bind_cols(
      filename = basename(.x),
      state = state_code
    )
})

3. 备选方案:改用openxlsx包

如果readxl仍有兼容性问题,换用openxlsx包,它对特殊字符和部分损坏文件的兼容性更好:

library(tidyverse)
library(openxlsx)

file_path <- "C:/Users/XXX/Individual reports/"
all_files <- list.files(file_path, full.names = TRUE, pattern = "\\.xlsx$", recursive = TRUE)

read_safe_openxlsx <- function(file) {
  tryCatch(
    read.xlsx(file, sheet = 5),
    error = function(e) {
      message(paste("跳过文件:", file))
      return(NULL)
    }
  )
}

df <- map_df(all_files, ~{
  state_code <- str_extract(basename(.x), "\\(([A-Z]{2})\\)") %>% str_remove_all("\\(|\\)")
  read_safe_openxlsx(.x) %>%
    as_tibble() %>%  # 转换为tidyverse风格的数据框
    bind_cols(
      filename = basename(.x),
      state = state_code
    )
})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 23:50:55