2017-03-09 61 views
2

我正在用xlsx軟件包創建一個格式有點複雜的Excel工作表。xlsx R軟件包覆蓋以前的格式

問題是當我已經格式化了一個單元格並且想要在其上添加一些內容時 - 那麼格式化會回到默認值,除了我添加的新東西。

一個解決方案是指定每個不同的情況並將完整的格式應用於它。特定案件的數量可能會隨着大型表單失控。

我猜想必須有一步一步地添加格式,但還沒有在文檔中找到任何關於它的內容。

我目前的做事方式重複的例子:

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

最後,一些先前紅色字體的是回黑色。

enter image description here

詩篇。我已嘗試其他包,但想堅持xlsxXLConnect不允許直接從R中進行某些類型的格式化,並且存在使openxlsx運行的技術困難。

回答

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

輸出:

enter image description here

+0

尼斯。必須學習'減少'。我現在將這樣執行我的工作,但我會等待,看看在接受之前是否有更方便用戶的東西。 – snoram