【问题标题】:xlsx R package overwriting previous formattingxlsx R 包覆盖以前的格式
【发布时间】:2017-03-09 15:43:15
【问题描述】:

我正在使用 xlsx 包创建格式有些复杂的 Excel 工作表。

问题是当我已经格式化了一个单元格并想在其上添加一些内容时——然后格式会恢复为默认值,除了我要添加的新内容。

一种解决方案是指定每种不同的大小写并对其应用完整的格式。一张大单,具体案例的数量可能会失控。

我猜肯定有办法逐步添加格式,但在文档中还没有找到任何关于它的内容。

我当前做事方式的可重现示例:

require(xlsx)

# Some random data
n <- 20L
set.seed(1L)
df <- data.frame(species = sample(c("Cat", "Dog", "Unkown"), n, replace = TRUE),
                 speed   = abs(rnorm(n)) * 20L)

# Create workbook
dfwb <- createWorkbook(type = "xlsx")
sheet <- createSheet(dfwb, sheetName = "ani")
addDataFrame(df, sheet, startRow = 1, startColumn = 1, row.names = FALSE)


# Change text of Cat to "red"
row <- getRows(sheet, rowIndex = which(df[, "species"] == "Cat")  + 1L)
cel <- getCells(row, colIndex = 1)
redh_style <- CellStyle(dfwb) + Font(dfwb, color = "red")

for (i in names(cel)) {
  setCellStyle(cel[[i]], redh_style)
}

# Highlight all rows where speed exceeds 18
row <- getRows(sheet, rowIndex = which(df[, "speed"] > 18)  + 1L)
cel <- getCells(row, colIndex = 1:2)
high_style <- CellStyle(dfwb) + Fill(foregroundColor="#E2E6EB")

for (i in names(cel)) {
  setCellStyle(cel[[i]], high_style)
}

# Save 
setwd("c:/temp/csvm/")
saveWorkbook(dfwb, "so_cat.xlsx")

最后,一些以前的红色字体变回黑色了。

附言。我尝试过其他软件包,但想坚持使用xlsxXLConnect 不允许直接从 R 进行某些类型的格式化,我在运行 openxlsx 时遇到了一些技术困难。

【问题讨论】:

    标签: r excel xlsx


    【解决方案1】:

    这是一种方法。主要思想是为每个单元格构建一个并行的格式列表,其中每个列表元素都是一个单元格。这允许您根据需要附加格式属性。最后,我们将此格式列表应用于每个单元格。

    首先,我们设置一个空白列表:

    # Set up blank list of formats
    fmts <- list()
    

    现在,我们根据第一个条件进行格式化,将字体属性添加到选定单元格的fmts 列表中:

    # Change text of Cat to "red"
    row <- getRows(sheet, rowIndex = which(df[, "species"] == "Cat")  + 1L)
    cel <- getCells(row, colIndex = 1)
    
    for (i in names(cel)) {
      if (i %in% names(fmts)) {
        fmts[[i]] <- c(fmts[[i]], list(Font(dfwb, color = "red")))
      } else {
        fmts[[i]] <- list(CellStyle(dfwb), Font(dfwb, color = "red"))
      }
    }
    

    接下来,做背景:

    # Highlight all rows where speed exceeds 18
    row <- getRows(sheet, rowIndex = which(df[, "speed"] > 18)  + 1L)
    cel <- getCells(row, colIndex = 1:2)
    
    for (i in names(cel)) {
      if (i %in% names(fmts)) {
        fmts[[i]] <- c(fmts[[i]], list(Fill(foregroundColor="#E2E6EB")))
      } else {
        fmts[[i]] <- list(CellStyle(dfwb), Fill(foregroundColor="#E2E6EB"))
      }
    }
    

    当我们检查fmts 时,我们注意到一些元素只有两个项目(基本单元格样式,加上字体或背景),而其他元素有三个(基本单元格样式、字体和背景):

    str(fmts, m = 1)
    # List of 16
    #  $ 2.1 :List of 3
    #  $ 6.1 :List of 3
    #  $ 11.1:List of 2
    #  $ 12.1:List of 3
    #  $ 13.1:List of 2
    #  $ 2.2 :List of 2
    #  $ 5.1 :List of 2
    #  $ 5.2 :List of 2
    #  $ 6.2 :List of 2
    #  $ 9.1 :List of 2
    #  $ 9.2 :List of 2
    #  $ 12.2:List of 2
    #  $ 15.1:List of 2
    #  $ 15.2:List of 2
    #  $ 19.1:List of 2
    #  $ 19.2:List of 2
    

    最后,我们遍历fmts 并应用样式。 Reduce 函数很有用:

    # Apply formatting
    for (i in names(fmts)) {
      idx <- as.numeric(unlist(strsplit(i, "\\.")))
      cel <- getCells(getRows(sheet, rowIndex = idx[1]), colIndex = idx[2])
      setCellStyle(cel[[i]], 
        Reduce(`+.CellStyle`, fmts[[i]])
      )
    }
    

    输出:

    【讨论】:

    • 仍在使用其中的某些部分,在最近的更新中停止工作。不得不将+.CellStyle 更改为简单的+
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-08-31
    • 2023-03-18
    • 1970-01-01
    • 1970-01-01
    • 2017-10-01
    • 1970-01-01
    • 2012-06-19
    相关资源
    最近更新 更多