R, XLConnect: Setting color with RGB code - r

I have come across the following problem. A lot of data is written to an Excel file. Within the written excel table, I want to set the cell color to a non-predefined value (which is a function of the number written to the cell). E.g.: The higher the number in a given cell, the greener the cell.
I know that solutions exist for the package xlsx (See HERE and HERE). But I already use XLConnect throughout the entire project and do not want to convert all of the code that I have so far.
Currently, I use the following code to set the cell color:
# create the excel workbook
wb <- loadWorkbook("FILENAME.xls", create=TRUE)`
# Create a CellStyle with yellow solid foreground
CellColor <- createCellStyle(wb)
setFillPattern(CellColor, fill = XLC$"FILL.SOLID_FOREGROUND")
setFillForegroundColor(CellColor, color = XLC$"COLOR.YELLOW")
# apply the CellStyle to a given cell, here: (10,10)
setCellStyle(wb, sheet=SHEETNAME, row=10, col=10, cellstyle=CellColor)
# save the workbook
saveWorkbook(wb)
Obviously, the problematic part is
color = XLC$"COLOR.YELLOW"
because it does not let me set the rgb code of the color I like. Attempts like
color = rgb(0.2,0.4,0.8)
fail.
The XLConnect documentation on page 91 does only tell that
The color is normally specified via a corresponding color constant from the XLC object.
There is no explanation on how to use RGB code.

Related

Is it possible to adjust position of an inserted image with openxlsx?

I've created an excel template for reporting. In the excel file, there will be some images. I'm able to insert the images by using openxlsx package.
test.fpath <-'Templates/CB.xlsx'
wb <- openxlsx::loadWorkbook(test.fpath)
insertImage(wb, sheet = 1, file = "tm_player_image.png",startRow = 8, startCol = 3, width = 1.1, height = 1.73, units = "in")
saveWorkbook(wb, file = "createWorkbookExample.xlsx", overwrite = TRUE)
openxlsx package allows you to set specific value for starting row and column. When I run the script, excel file is saved like the following image.
First position of the image
However, I don't want the image start row = 8 and col = 3. I should able to drag the image where ever I want and define top-left position values. Is there any way to achieve this?
Adjusted position of the image
I need to define position of the image like this.
Left (Sol): 13,64''
Top (Üst): 0,74''
Thanks for your help.
It is possible, but there is no function to do this and AFAIK Excel positions are always relative to the screen and OS one is using. Therefore you have to use a bit try and error to get the correct positions.
Have a look at wb$drawings[[1]][[1]]. The content is an XML string. You are looking for the xdr:from part (as seen below). You have to adjust xdr:colOff and xdr:rowOff like in the example below. I had to insert a fairly high value to see any impact.
<xdr:from xmlns:xdr="http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing">\n
<xdr:col xmlns:xdr="http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing">2</xdr:col>\n
<xdr:colOff xmlns:xdr="http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing">50000</xdr:colOff>\n
<xdr:row xmlns:xdr="http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing">4</xdr:row>\n
<xdr:rowOff xmlns:xdr="http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing">40000</xdr:rowOff>\n
</xdr:from>

Tagging specific data from an .xlsx file when importing a data frame to R

excel file with marked data
Referencing the picture linked above, I'm looking to import this excel file into R, but I'd like the data that are red and have the strikethrough to be tagged/marked somehow in R - in order to be able to create vectors from them. Is there a way to do that, without having to rearrange the data frame first?
The openxlsx package has the ability to access the workbook style. Among much other information, it reads the following from the worksheets:
Cell formatting
Font name
Font size
Font colour
However, it doesn't have the "strikethrough effect". But you can certainly take advantage of the different font colours.
Suppose you have the following Excel file where I've made two cells red with a strikethrough effect and kept the others as normal:
Load the library and import the data.
library(openxlsx)
wb <- loadWorkbook("filename.xlsx")
data <- read.xlsx(wb, colNames=FALSE)
The styles are contained in the styleObjects object
wb$styleObjects
[[1]]
[[1]]$style
A custom cell style.
Cell formatting: GENERAL
Font name: Calibri
Font size: 11
Font colour: #FF0000
[[1]]$sheet
[1] "Sheet1"
[[1]]$rows
[1] 3 4
[[1]]$cols
[1] 2 3
There may be many other elements of the list depending on the number of custom styles you applied to the cells in your worksheet. Each custom style will be included in this object. Here I've only got 1 custom style corresponding to the red font colour (#FF0000). The $rows and $cols items give the row and column indices of only the cells that have this font colour. You can then use this information to extract the required data values.
red.rows <- wb$styleObjects[[1]]$rows
red.cols <- wb$styleObjects[[1]]$cols
data[cbind(red.rows, red.cols)]
#[1] 43 12

Issue when importing float as string from Excel. Adding precision incorrectly

Using openxlsx read.xlsx to import a dataframe from a multi-class column. The desired result is to import all values as strings, exactly as they're represented in Excel. However, some decimals are represented as very long floats.
Sample data is simply an Excel file with a column containing the following rows:
abc123,
556.1,
556.12,
556.123,
556.1234,
556.12345
require(openxlsx)
df <- read.xlsx('testnumbers.xlsx', )
Using the above R code to read the file results in df containing these string
values:
abc123,
556.1,
556.12,
556.12300000000005,
556.12339999999995,
556.12345000000005
The Excel file provided in production has the column formatted as "General". If I format the column as Text, there is no change unless I explicitly double-click each cell in Excel and hit enter. In that case, the number is correctly displayed as a string. Unfortunately, clicking each cell isn't an option in the production environment. Any solution, Excel, R, or otherwise is appreciated.
*Edit:
I've read through this question and believe I understand the math behind what's going on. At this point, I suppose I'm looking for a workaround. How can I get a float from Excel to an R dataframe as text without changing the representation?
Why Are Floating Point Numbers Inaccurate?
I was able to get the correct formats into a data frame using pandas in python.
import pandas as pd
test = pd.read_excel('testnumbers.xlsx', dtype = str)
This will suffice as a workaround, but I'd like to see a solution built in R.
Here is a workaround in R using openxlsx that I used to solve a similar issue. I think it will solve your question, or at least allow you to format as text in the excel files programmatically.
I will use it to reformat specific cells in a large number of files (I'm converting from general to 'scientific' in my case- as an example of how you might alter this for another format).
This uses functions in the openxlsx package that you reference in the OP
First, load the xlsx file in as a workbook (stored in memory, which preserves all the xlsx formatting/etc; slightly different than the method shown in the question, which pulls in only the data):
testnumbers <- loadWorkbook(here::here("test_data/testnumbers.xlsx"))
Then create a "style" to apply which converts the numbers to "text" and apply it to the virtual worksheet (in memory).
numbersAsText <- createStyle(numFmt = "TEXT")
addStyle(testnumbers, sheet = "Sheet1", style = numbersAsText, cols = 1, rows = 1:10)
finally, save it back to the original file:
saveWorkbook(testnumbers,
file = here::here("test_data/testnumbers_formatted.xlsx"),
overwrite = T)
When you open the excel file, the numbers will be stored as "text"

How do you save Excel file and enable cell protection in R?

I have a basic Excel workbook created with the XLSX package. I want to save it as an .xlsx file but lock all columns except for one to protect them from being edited. I'm able to set cell protection to the selected column with the CellProtection() function, but I don't know how to turn password protection on for the worksheet in order to actually make the columns protected.
library(xlsx)
wb = createWorkbook()
s1 = createSheet(wb, "Sheet 1")
addDataFrame(mtcars, s1) #using mtcars as example dataset
cs = CellStyle(wb, cellProtection = CellProtection(locked=F)) #setting style to unlock cells
rows <- getRows(s1, rowIndex=2:101)
cells <- getCells(rows, colIndex = c(2)) #getting the cells to unlock
lapply(names(cells), function(ii)setCellStyle(cells[[ii]],cs)) #applying unlocking to all columns except the second one (the one i want to leave locked)
saveWorkbook(wb, "file.xlsx")
When I check the Excel file, the properties of the cells in column 2 say they're unlocked, but then I have to click on "Protect Sheet" and manually enter a password in order to actually lock all the cells.
Is there a way to do this in R and enable worksheet protection?
I have been using #AEF 's answer. But today I found out this in fact can be done in the xlsx package:
s1$protectSheet("mypassword").
Of course, before you call saveworkbook
You can do this directly with apache POI (which is used by xlsx). Just call
.jcall(s1, "V", "protectSheet", "mypassword")
before you call saveWorkbook.
If the sheet is not stored as an object, you can summon the sheet with the getSheet() method within the ".jcall" function:
rJava::.jcall(wb$getSheet("Sheet1"),"V","protectSheet", "MyPassword123")
xlsx::saveWorkbook(wb,"C:/myfilepath)
Also, to provide clarity, the ".jcall" function comes from the "rJava" package. This package must be installed and working properly.

Can I apply a cell style from a template workbook to cells in new workbooks using XLConnect?

I am writing some R code that reads in sheets from many Excel workbooks, identifies cells meeting certain criteria, and then saves these very same workbooks with the identified cells of interest in bold font. Because this is an efficiency tool, I do not want to have to go into every workbook that I plan to run my code on and add a custom "bold" cell style.
My plan was to read in the cell style from a template workbook:
bold <- XLConnect::getCellStyle(templateWB, "bold")
Then, I wanted to use the style from the template workbook to create bold cells in the new workbooks:
XLConnect::setCellStyle(wb, sheet = sheetName, row= boldRow, col = boldCol, cellstyle = bold)
Trying to do this, however, results in an error:
"Error: IllegalArgumentException (Java): This Style does not belong to the supplied Workbook Stlyes Source. Are you trying to assign a style from one workbook to the cell of a differnt workbook?"
Clearly I cannot apply the cell style from one workbook to sheets in another workbook. Any suggestions for a workaround in R?
Thank you.
The cellstyle you imported comes from templateWB and therefore this cellstyle is only recognized by that workbook. You cannot apply this cellstyle to another workbook.
I had exactly the same problem and solved it by simply working in that workbook and saving it somewhere else with saveWorkbook(templateWB, "some other path"). Another option that should work is:
wb <- templateWB
bold <- XLConnect::getCellStyle(templateWB, "bold")
XLConnect::setCellStyle(wb, sheet = sheetName, row= boldRow, col = boldCol,
cellstyle = bold)

Resources