xlsx R包覆盖以前的格式 [英] xlsx R package overwriting previous formatting

查看:231
本文介绍了xlsx R包覆盖以前的格式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



问题是当我已经格式化了一个单元格,并希望添加一些单元格,然后格式化可以恢复为默认值,除了我新的东西添加。



一种解决方案是指定每种不同的情况,并将完整的格式应用于它。具体案例的数量可能会因大幅面而失去控制。



我猜想,一定要有一个添加格式的步骤,但没有找到任何东西关于它在文件中。



我现在的做事方式的一个可重复的例子:

  require(xlsx)

#一些随机数据
n < - 20L
set.seed(1L)
df< - data .frame(species = sample(c(Cat,Dog,Unkown),n,replace = TRUE),
speed = abs(rnorm(n))* 20L)

#创建工作簿
dfwb< - createWorkbook(type =xlsx)
sheet< - createSheet(dfwb,sheetName =ani)
addDataFrame(df, startRow = 1,startColumn = 1,row.names = FALSE)


#将Cat的文本更改为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)
}

#突出显示速度超过18
的所有行行< - 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)
}

#保存
setwd( c:/ temp / csvm /)
saveWorkbook(dfwb,so_cat.xlsx)

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





Ps。我已经尝试过其他软件包,但是想坚持使用 xlsx
XLConnect 不允许直接从R中进行某些格式化,并且具有使 openxlsx 运行的技术难题。 / p>

解决方案

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



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

 #设置空白的列表格式
fmts< - list()

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

$更改Cat的文本为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))
}
}

接下来,做背景:

 #突出显示速度超过18的所有行
row< - getRows(sheet,rowIndex = which(df [,speed]> 18)+ 1L)
cel < {
$ b if(i%in%names(fmts)){
fmts [ [i]]< - c(fmts [[i]],list(Fill(foregroundColor =#E2E6EB)))
} else {
fmts [[i]] (CellStyle(dfwb),Fill(foregroundColor =#E2E6EB))
}
}

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

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

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

 #应用格式
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]])

}

输出:




I am creating an Excel sheet with somewhat complex formatting with the xlsx package.

The problem is when I have already formatted one cell and want to add something on top of that---then the formatting goes back to default except the new thing I am adding.

One solution would be to specify each different case and apply the complete formatting to it. The number of specific cases might grow out of control with a big sheet.

I would guess there must be a away to add formatting step by step but haven't found anything about it in the documentation yet.

A reproducible example of my current way of doing things:

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")

In the end, some of the previously red font is back to black.

Ps. I have tried other packages but would like to stick with xlsx. XLConnect does not allow some kinds of formatting directly from R and has technical difficulties making openxlsx run.

解决方案

Here's one approach. The main idea is to build a parallel list of formats for each cell, where each list element is a cell. This allows you to append formatting attributes as desired. At the very end, we apply this list of formats to each cell.

First, we set up a blank list:

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

Now, we format according to the first criteria, adding the font attribute to the fmts list for selected cells:

# 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"))
  }
}

Next, do the background:

# 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"))
  }
}

When we inspect fmts, we note that some elements only have two items (the base cell style, plus the font or the background) while others have three (the base cell style, the font, and the background):

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

Finally, we iterate through fmts and apply the styles. The Reduce function comes in useful:

# 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]])
  )
}

Output:

这篇关于xlsx R包覆盖以前的格式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆