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

R脚本实现Excel转CSV:保留列类型、校验扩展名等需求求助

Excel转多CSV脚本:解决类型保留、扩展名校验与依赖精简问题

仅依赖readxl的基础R版本(无purrr)

# 获取用户输入的文件名
input_file <- readline("请输入Excel文件名(可带/不带扩展名):")

# 文件扩展名校验与补全函数
check_extension <- function(file) {
  # 提取并转为小写扩展名
  ext <- tolower(tools::file_ext(file))
  # 判断是否为合法Excel扩展名
  if (ext %in% c("xls", "xlsx")) {
    return(file)
  } else {
    # 无合法扩展名时自动补全.xlsx
    return(paste0(file, ".xlsx"))
  }
}

file_path <- check_extension(input_file)

# 检查文件是否存在
if (!file.exists(file_path)) {
  stop("错误:文件不存在,请检查路径或文件名!")
}

# 获取所有工作表名称
sheet_names <- readxl::excel_sheets(file_path)

# 遍历每个工作表,转换为CSV
for (sheet in sheet_names) {
  # 读取工作表,自动识别列类型
  df <- readxl::read_excel(file_path, sheet = sheet, col_types = "guess")
  
  # 处理日期列:转为字符串避免被转为Excel数值序列号
  date_cols <- sapply(df, function(x) inherits(x, c("Date", "POSIXct", "POSIXlt")))
  df[date_cols] <- lapply(df[date_cols], as.character)
  
  # 处理数值列:强制关闭科学计数法,保留原始精度
  num_cols <- sapply(df, is.numeric)
  df[num_cols] <- lapply(df[num_cols], function(x) format(x, scientific = FALSE, trim = TRUE))
  
  # 生成输出文件名(原文件名-工作表名.csv)
  output_name <- paste0(tools::file_path_sans_ext(input_file), "-", sheet, ".csv")
  
  # 写入CSV:禁用行名,空值留空,保留引号
  write.table(df, output_name, sep = ",", row.names = FALSE, na = "", quote = TRUE)
}

cat("转换完成!所有工作表已保存为独立CSV文件。\n")

针对你的三个问题的具体解答

1. 确保转换过程中列类型与值完全一致

  • 日期处理:readxl读取的日期会转为Date/POSIXct类型,直接用基础write.csv会把日期转成Excel内部的数值序列号,因此需要提前将日期列转为字符串格式,保留可读的日期文本。
  • 数值精度:基础write.csv对大数值默认用科学计数法,通过format(x, scientific = FALSE)强制保留原始数值格式,避免精度丢失。
  • 空值匹配:写入时指定na = "",让CSV中的空值与Excel显示一致,不会出现NA字符串。
  • 类型识别:用read_excel(col_types = "guess")自动识别列类型,再通过sapply判断列类型后针对性处理,适配不同结构的Excel文件。

2. 文件扩展名校验函数

上述代码中的check_extension函数基于基础R的tools::file_ext实现:

  • 自动提取输入文件名的扩展名并转为小写,避免大小写差异导致的判断错误;
  • 若输入已带xls/xlsx扩展名,直接返回原路径;
  • 若输入无扩展名或扩展名非法,自动补全.xlsx(可根据需求修改为让用户选择扩展名);
  • 额外增加file.exists检查,避免用户输入不存在的文件。

3. 用基础包替代purrr

直接使用基础R的for循环遍历工作表名称,完全替代purrr的map和walk2功能,整个脚本仅依赖readxl(tools是R基础包的一部分,无需额外安装)。


可选:tidyverse优化版本(更简洁)

如果允许使用tidyverse(含readr、purrr),代码更简洁且类型处理更省心,readr::write_csv会自动处理日期和数值格式:

library(tidyverse)
library(readxl)

input_file <- readline("请输入Excel文件名(可带/不带扩展名):")

# 扩展名处理
check_extension <- function(file) {
  ext <- tolower(tools::file_ext(file))
  if (ext %in% c("xls", "xlsx")) file else paste0(file, ".xlsx")
}

file_path <- check_extension(input_file)
if (!file.exists(file_path)) stop("错误:文件不存在!")

sheet_names <- excel_sheets(file_path)

# 遍历转换
walk(sheet_names, function(sheet) {
  df <- read_excel(file_path, sheet = sheet)
  output_name <- str_glue("{tools::file_path_sans_ext(input_file)}-{sheet}.csv")
  write_csv(df, output_name, na = "")
})

cat("转换完成!\n")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 18:02:51