15

如何使用自动调整列宽openxlsx

我的一列有一个日期变量(例如21-08-2017),如果使用ctrl+c从 Excel 复制并正常粘贴到其他地方,它会显示为#######(如果增加列宽以显示 Excel 中的内容,它会正常粘贴)。我想将该重复性任务集成到我的代码中。这是我现在使用的:

WB <- loadWorkbook(File)
addWorksheet(WB, Sheet)
writeDataTable(WB, Sheet, DF, withFilter=F, bandedRows=F, firstColumn=T)
saveWorkbook(WB, File,  overwrite =TRUE)

我在这里附上了整个相关代码,我也在根据表格值进行条件格式化。请在此处提出一种集成自动调整列宽的方法。

编辑:默认情况下,R 的 XLSX 输出具有默认的 8.43 列宽,我想根据单元格内容将其设置为自动调整,或者为每一列手动设置。

致 Mod:这是我试图在 R 中使用 openxlsx 解决的问题。无论如何,感谢您的关注。

4

4 回答 4

20

好的,我在文档中进行了另一次广泛搜索后得到了它。由于缺乏在线解决方案,似乎很少有人真正使用它......

setColWidths(WB, Sheet, cols = 1:ncol(DF), widths = "auto")

但是,这仍然没有给出预期的结果,日期列仍然有点短并显示########;而列标题也不合适(因为它们的格式为粗体)。

编辑:

最后,选择添加c(7.5, 10, "auto", ...)替换只是"auto",它不是完全动态的,但现在解决了这个问题。希望看到更好的答案。

于 2017-08-24T11:17:09.330 回答
13

鉴于这widths = "auto"没有像您希望的那样工作,一个更通用的答案是根据最长的值 + 2 分配宽度(以处理加粗):

width_vec <- apply(DF, 2, function(x) max(nchar(as.character(x)) + 2, na.rm = TRUE)) setColWidths(WB, Sheet, cols = 1:ncol(DF), widths = width_vec)

并根据列标题分配宽度:

width_vec_header <- nchar(colnames(DF)) + 2
setColWidths(WB, Sheet, cols = 1:ncol(DF), widths = width_vec_header)

并且要根据每列最长的字符串分配宽度,无论是标题还是正文中的单元格,请使用“并行”最大值函数(如矢量化最大值函数):
width_vec <- apply(DF, 2, function(x) max(nchar(as.character(x)) + 2, na.rm = TRUE))
width_vec_header <- nchar(colnames(DF)) + 2
max_vec_header <- pmax(width_vec, width_vec_header)
setColWidths(WB, Sheet, cols = 1:ncol(DF), widths = max_vec_header )

于 2018-04-24T16:42:49.493 回答
2

使用 XLConnect...

setColumnWidths(WB, Sheet, column = 1:ncol(DF), width = -1)

参考: https ://cran.r-project.org/web/packages/XLConnect/XLConnect.pdf

于 2018-08-28T21:11:42.240 回答
2

我遇到了与上述相同的问题,但正在使用数据框列表。使用 tidyverse,我修改了 Rick 的答案来解释这一点。我也不希望列宽超过 75。这仍然没有解决上述日期问题。我不希望时间戳与我的日期一起显示,我发现您可以设置 Excel 中日期格式的选项。所以为此我使用了选项(“openxlsx.datetimeFormat”=“mm/dd/yyyy”)。有关格式化的更多信息在这里

myList <- list(A = data.frame(ID = c("AAA", "AAA"), 
                          Test = c(1, 1), 
                          Value = 1:2), 
           B = data.frame(ID = c("BBB", "BBB", "BBB"), 
                          Test = c(1, 3, 5), 
                          Value = 1:3),
           C = data.frame(Test = c(1, 3, 5), 
                          Value = 1:3))

data_cols <- myList %>%
  map(~ 1:ncol(.), .depth = 2)

width_vec <- myList %>% 
  map(~ summarise_all(., funs(max(nchar(as.character(.)))), na.rm = TRUE), .depth = 2) %>% 
  map(~ unlist(., use.names = FALSE), .depth = 2) %>% 
  map(~ . + 2, .depth = 2)
width_vec_header <- map(myList, ~ nchar(names(.)) + 2, .depth = 2) 
max_vec <- map2(width_vec, width_vec_header, ~ pmin(75, pmax(.x, .y, 0)), .depth = 2)
pwalk(list(names(myList), data_cols, max_vec), ~ setColWidths(wb, ..1, ..2, widths = ..3))
于 2019-04-10T04:36:11.930 回答