【问题标题】:XLConnect sheet names too longXLConnect 工作表名称太长
【发布时间】:2019-02-21 21:54:53
【问题描述】:

下面的代码要求用户提供 .csv 文件的路径,列出 .csv 文件名,然后将每个 .csv 文件的内容写入一个工作表中的一个 .xlsx 文件。每个工作表都以 .csv 文件的原始名称命名。

我的问题是我的一些 .csv 文件名长度超过 31 个字符,这是 Excel 中工作表名称的限制。

我想将工作表名称放在单元格 A1 中,在其下方写入文件内容并为工作表命名(例如 1、2、3...),但我无法理解围绕我将如何实现这一点。任何建议将不胜感激。

library(data.table)  ## for fast fread() function
library(XLConnect)
library(svDialogs)

# Ask user for path to csv files
folder <- dlgInput(title = "Merge csv", "Enter path to csv files (use '/' instead of '\\': ", Sys.info()["user"])$res

setwd(folder)

# Create and load Excel file
wb <- loadWorkbook("Output.xlsx", create=TRUE)

# Get list of csv files
pattern.ext <- "\\.csv$"
files <- dir(folder, full=TRUE, pattern=pattern.ext)

# Use file names for sheet names
files.nms <- basename(files)
files.nms <- gsub(pattern.ext, "", files.nms)

# Set the names to make them easier to grab
names(files) <- files.nms

# Iterate over each csv and output to sheet in Excel with its name
for (nm in files.nms) {

  # Ingest csv file
  temp_DT <- fread(files[[nm]])

  # Create the sheet with the name  
  createSheet(wb, name=nm)

  # Output the contents of the csv 
  writeWorksheet(object=wb, data=temp_DT, sheet=nm, header=TRUE, rownames=NULL)
}

# Remove default sheets
removeSheet(wb, sheet = "Sheet1")
removeSheet(wb, sheet = "Sheet2")
removeSheet(wb, sheet = "Sheet3")

saveWorkbook(wb)

# Check to see if file exists
if (file.exists("Output.xlsx")) {
  dlg_message("Your Excel file has been created.")$res
} else {
  dlg_message("Error: Your file was not created. Please try again.")$res
}

编辑 - 替代解决方案:

修改代码以最初采用文件名的子字符串...

# Use substring of file names for sheet names (Excel sheet name limit is 31)
files.nms <- substr(basename(files),1,31)
files.nms <- gsub(pattern.ext, "", files.nms)

最终编辑:添加了欢迎消息和功能询问用户路径,它检查路径是否存在。如果没有,它将不断询问用户,直到他们取消或进入现有目录。

library(data.table)  # fread() function
library(XLConnect)   # Excel and csv files
library(svDialogs)   # Dialog boxes

# Welcome message
dlg_message("This program will merge one or more .csv files into one Excel file. When prompted, enter the path 
            where the .csv files are located. Sheet names in the Excel file will consist of a substring of the original filename.")$res

# Function to get user path
getPath <- function() { 
  # Ask for path
  path <- dlgInput("Enter path to .csv files: ", Sys.info()["user"])$res
  if (dir.exists(path)) {
    # If it is, set the path as the working directory
    setwd(path)
  } else {
    # If not, issue an error and recall the getPath function
    dlg_message("Error: The path you entered is not a valid directory. Please try again.")$res
    getPath()
  }
}

# Call getPath function
folder <- getPath()

# Create and load Excel file
wb <- loadWorkbook("Combined.xlsx", create=TRUE)

# Get list of csv files in directory
pattern.ext <- "\\.csv$"
files <- dir(folder, full=TRUE, pattern=pattern.ext)

# Use substring of file names for sheet names (Excel limit) and remove extension 
files.nms <- substr(basename(files),9,39)
files.nms <- gsub(pattern.ext, "", files.nms)

# Set the names 
names(files) <- files.nms

# Iterate over each .csv and output to Excel sheet
for (nm in files.nms) {

  # Read in .csv files 
  df <- fread(files[nm])

  # Create the sheet and name as substr of file name  
  createSheet(object = wb, name = nm)

  # Writes contents of the .csv To Excel
  writeWorksheet(object = wb, data = df, sheet = nm, header = TRUE, rownames = NULL)

  # Create a custom anonymous cell style
  cs <- createCellStyle(wb)

  # Wrap text
  setWrapText(object = cs, wrap = TRUE)

  # Set column width
  setColumnWidth(object = wb, sheet = nm, column = 1:50, width = -1)
}

saveWorkbook(wb)

# Check to see if Excel file exists and is greater than default file size
if (file.exists("Combined.xlsx") & file.size("Combined.xlsx") > 8731) {
  dlg_message("Your Excel file has been created.")$res
} else {
  dlg_message("Error: Your file may not have been created or compelted properly. Please verify and try again if necessary.")$res
}

【问题讨论】:

    标签: r xlconnect


    【解决方案1】:

    你考虑过使用 openxlsx 吗?

    它不依赖于 java,而且功能齐全。

    # Load package
    library(openxlsx)
    
    # Create workbook
    wb <- createWorkbook()
    
    # Define data.frames you want to write (adapt to your scenario)    
    df <- c("mtcars", "iris")
    
    # Loop over the length of the dataframes defined above
    for(i in 1:length(df)){
        # Create a work sheet and call it the numeric value
        addWorksheet(wb, as.character(i))
        # In the first row, first column, specify the df name
        writeData(wb, i, df[i], startRow = 1, startCol = 1)
        # Write the data.frame to the second row, first column
        writeData(wb, i, eval(parse(text=df[i])), startRow = 2, startCol = 1)
    }
    
    # Save workbook
    saveWorkbook(wb, "eg.xlsx", overwrite = TRUE)
    

    【讨论】:

    • 谢谢@Khaynes!这正是我想要的。我会将它集成到我现有的代码中。
    • 作为对此的跟进,我可以使用 XLConnect 来 createSheet 并使用文件名列表的子字符串吗?它似乎对我有用一次,但后来我收到了一个错误。我正在尝试createSheet(wb, name=substr(names(files),1,31)) 并收到以下错误:Error: IllegalArgumentException (Java): Sheet index (-1) is out of range (0..17)
    • 你能提供 dput(name) 吗?无法从代码中真正看出你在做什么。
    • 我实际上不在我的电脑旁,但我会尽快发送完整的代码。感谢您的帮助@Khaynes!
    • 我只是加倍检查,我对原始实现的唯一更改如下:createSheet(wb, name=substr(names(files), 1, 4)) 和错误:Error: IllegalArgumentException (Java): Sheet index (-1) is out of range (0..0)。我确实使用了不同的结尾元素,但其他一切都是一样的。
    猜你喜欢
    • 1970-01-01
    • 2015-04-23
    • 1970-01-01
    • 2019-02-14
    • 1970-01-01
    • 2012-09-21
    • 1970-01-01
    • 2017-11-05
    • 2019-06-01
    相关资源
    最近更新 更多