XLConnect hyperlinks - r

I am creating a program that will generate a sample of a dataset for quality review. The actual data will be available on our intranet. This sample is output in an excel with a very specific user-friendly format. I am wanting to use XLconnect to add hyperlinks to the excel document based on the sample. I have been unable to find answers using several searches. I am hoping this is possible using XLconnect or similar package that will keep the format in excel. My code below adds just text, but not hyperlinks...
library(XLConnect)
Full_data_set = read.csv(paste(my.file.location, my.set, sep= "/"))
my.sample <- sample(Full_data_set$groupid, 50)
my.link <- paste("ourwebsite.org/group/" my.sample, sep = "")
wb <- loadWorkbook(filename = "my.file.location/Template2.xlsx",
create = TRUE)
writeWorksheet(wb, my.links, sheet= 1,
startRow=3, startCol=3,
header=FALSE)
saveWorkbook(wb)

You have to use
setCellFormula()
library("XLConnect")
df <- data.frame(
v1 = c("wiki", "google", "so"),
v2 = c("https://www.wikipedia.org/",
"https://www.google.com/",
"http://stackoverflow.com/"),
link = NA ,
stringsAsFactors = F)
# Load workbook (create if not existing)
wb <- loadWorkbook("hlink_example.xlsx", create = TRUE)
# Create a sheet
createSheet(wb, name = "Sheet1")
# Create a named region on sheet
createName(wb, name = "Sheet1", formula = "Sheet1!$A$1")
# Write data set to the above defined named region
writeNamedRegion(wb, df, name = "Sheet1")
# Create an excel column ref. for formula and links in data frame
excelCol <- letters[which(names(df) == "v2")]
# Construct the input range & formula
formula <- paste("HYPERLINK(",excelCol, 2:(nrow(df)+1),")", sep = "")
# Create the link column in data frame
df$link <- formula
# Set the cell formulas using index for rows/col
setCellFormula(wb, "Sheet1", 2:(nrow(df)+1), which(names(df) == "link"),
formula)
# Save workbook
saveWorkbook(wb)

Related

Read in single xlsx file, perform conditional formatting and export as as multiple xlsx files in R

initial dataset:
df = data.frame(Division=c("ASIA","ASIA","ASIA","ASIA","ASIA","EUROPE","EUROPE","EUROPE"),
Country=c("India","China","Japan","Nepal","Laos","France","Italy","Norway"),
improvement=c(1,3,7,5,9,8,2,7))
I am able to read this xlsx file into R, and I want to be able to fo the following:
Highlight any row where the Improvement value is lesser than 5.
Export the data into different xlsx files based on the Division names. Example, the first xlsx file exported will have only the first 5 rows of the data in df, with India and china highlighted and the other file exported will have 3 rows from Europe with Italy highlighted.
Any pointers will be appreciated!!
You could first create a function using openxlsx to create the workbook.
Then you could split the dataset by division and use map to call the workbook creation over the divisions:
library(openxlsx)
library(purrr)
library(dplyr)
threshold <- 6
create.workbook <- function(df,threshold) {
wb <- createWorkbook()
highlight.Style <- createStyle(fontColour = "red", fgFill = "yellow")
addWorksheet(wb, "data")
writeData(wb, sheet = "data", x = df)
highlight.rows <- which(df$improvement < threshold)+1
addStyle(wb, "data", cols = 1:ncol(df), rows = highlight.rows,
style = highlight.Style, gridExpand = TRUE)
wb.name <- df$Division[1]
saveWorkbook(wb,paste0(wb.name,'.xlsx'),overwrite = T)
}
df %>% split(.$Division) %>% map(~create.workbook(.x,threshold))
$ASIA
[1] 1
$EUROPE
[1] 1

Change cell value in openxlsx workbook

I want to use openxlsx to change an individual cell in a workbook sheet and write it back out as the same .xlsx without losing the styling, validation, etc of the original .xlsx file. I stipulate openxlsx because it doesn't have a rJava dependency.
Here's a dummy workbook:
library(openxlsx)
## Make a dummy workbook to read in
write.xlsx(list(iris = iris, mtcars = mtcars), file = 'test.xlsx')
wb <- loadWorkbook('test.xlsx')
isS4(wb)
How can I change the value of cell [2,1] so that it essentially is identical to the original .xlsx file but with on cell altered?
I can of course read in the workbook but I don't know what good that does me.
m <- readWorkbook(wb)
m[2, 1] <- 20
m[1:5,]
writeData can help you with this.
test.fpath <- 'test.xlsx'
openxlsx::write.xlsx(list(iris = iris, mtcars = mtcars), file = test.fpath)
.wb <- openxlsx::loadWorkbook(test.fpath)
openxlsx::writeData(
wb = .wb,
sheet = 1,
x = 20,
xy = c(2,1)
)
openxlsx::saveWorkbook(
.wb,
test.fpath,
overwrite = TRUE
)

Openxlsx hyperlink output display in Excel

I am trying to take in a data frame an excel sheet that has two columns,
Column A contains names of stores
Column B contains the URL of those stores.
I would like to take Column A and make it a clickable hyperlink so instead of plain text, it is a hyperlink to the store website.
I have attempted to use openxlsx package to generate the correct output.
I have attempted to use the following code snip.
x <- c("https://www.google.com", "https://www.google.com.au")
names(x) <- c("google", "google Aus")
class(x) <- "hyperlink"
writeData(wb, sheet = 1, x = x, startCol = 10)
which comes from this post of a similar nature.
https://stackoverflow.com/a/48973469/11958444
My problem however is when I replace the appropriate parts of the code e.g.:
x <- df$b
names(x) <- df$a
class(x) <- "hyperlink"
writeData(wb, sheet = 1, x = x, startCol = 10)
instead of giving me a column of hyperlinks that has the store name as the output, it gives me the entire URL as the output. Is there something I am missing from my code?
I get an output that has a clickable link, but instead of the URL appearing with the name, it instead just prints out the URL.
An approach using openxlsx:
library(openxlsx)
library(dplyr)
# create sample data
df <- data.frame(
site_name = c("Zero Hedge", "Free Software Foundation"),
site_url = c("https://www.zerohedge.com", "https://www.fsf.org")
)
# add new column that manually constructs Excel hyperlink formula
# note backslash is required for quotes to appear in Excel
df <- df %>%
mutate(
excel_link = paste0(
"HYPERLINK(\"",
site_url,
"\", \"",
site_name,
"\")"
)
)
# specify column as formula per openxlsx::writeFormula option #2
class(df$excel_link) <- "formula"
# create and write workbook
wb <- createWorkbook()
addWorksheet(wb, "df_sheet")
writeData(wb, "df_sheet", df)
saveWorkbook(wb, "wb.xlsx", overwrite = TRUE)
I like the current answer but for me it leaves the hyperlink as black. Here are three alternative solutions that I came up with...
1. mark the url column as a hyperlink
library(openxlsx)
# create sample data
df <- data.frame(
site_name = c("Zero Hedge", "Free Software Foundation"),
site_url = c("https://www.zerohedge.com", "https://www.fsf.org")
)
# create and write workbook
wb <- createWorkbook()
addWorksheet(wb, "df_sheet")
class(df$site_url)<-"hyperlink" # mark as a hyperlink
writeData(wb,"df_sheet",df$site_url,startCol = which(colnames(df)=="site_url"), startRow = 2)
writeData(wb, "df_sheet", df) # overwrite the sheet
saveWorkbook(wb, "wb.xlsx", overwrite = TRUE)
2. apply the hyperlink to the site_name column
library(openxlsx)
# create sample data
df <- data.frame(
site_name = c("Zero Hedge", "Free Software Foundation"),
site_url = c("https://www.zerohedge.com", "https://www.fsf.org")
)
# create and write workbook
wb <- createWorkbook()
addWorksheet(wb, "df_sheet")
class(df$site_url)<-"hyperlink" # mark as a hyperlink
writeData(wb,"df_sheet",df$site_url,startCol = which(colnames(df)=="site_name"), startRow = 2)
class(df$site_url)<-"character" # change back to a character which is optional
writeData(wb, "df_sheet", df) # overwrite the sheet to get the new pretty name overlaying the hyperlink
saveWorkbook(wb, "wb.xlsx", overwrite = TRUE)
3. new column with the link applied to the names from site_name
library(openxlsx)
# create sample data
df <- data.frame(
site_name = c("Zero Hedge", "Free Software Foundation"),
site_url = c("https://www.zerohedge.com", "https://www.fsf.org")
)
df$pretty_link<-df$site_name #new column for pretty link
# create and write workbook
wb <- createWorkbook()
addWorksheet(wb, "df_sheet")
class(df$site_url)<-"hyperlink" # mark as a hyperlink
writeData(wb,"df_sheet",df$site_url,startCol = which(colnames(df)=="pretty_link"), startRow = 2)
class(df$site_url)<-"character" # change back to a character which is optional
writeData(wb, "df_sheet", df) # overwrite the sheet to get the new pretty name overlaying the hyperlink
saveWorkbook(wb, "wb.xlsx", overwrite = TRUE)

Export data into specific cells in Excel sheet

I need to export a data frame in R to an Excel sheet, which can be done via:
require("xlsx")
write.xlsx(x, file, sheetName="Sheet1", col.names=TRUE,
row.names=TRUE, append=FALSE, showNA=TRUE)
My exported data will then be pasted beginning in cell "A1" of the Excel sheet. I can also set append=TRUE so the data will be added at the end of the sheet.
Is there a possibility to put it into a specific cell? I need to export the data frame to a range beginning at cell C10. Is this possible?
Update:
The sheet contains data in rows 1-9 as well as columns A-B. Therefore it is not possible to just add empty cells to the data frame and paste it into the excel sheet, because those empty cells would erase the data.
You can do it with the package XLConnect.
library(XLConnect)
wb <- loadWorkbook("File_result.xlsx"), create = TRUE)
createSheet(wb, name = "Sheet1")
# here, you can set the startRow and startCol. Col A = 1, B = 2,...
writeWorksheet(wb,x,"Sheet1",startRow = 10, startCol = 3, header = TRUE)
# automatically adjust column width
setColumnWidth(wb, sheet = "Sheet1", column = 3:4, width = -1)
saveWorkbook(wb)
You can fill the empty cells with empty data:
data <- matrix(1:100, ncol=5)
col.offset <- 2
row.offset <- 9
emptycols <- matrix("", ncol=col.offset, nrow=nrow(data))
data <- cbind(emptycols, data)
emptyrows <- matrix("", nrow=row.offset, ncol=ncol(data))
data <- rbind(emptyrows, data)
write.table(data, "test.csv", row.names=FALSE, col.names=FALSE)
Or, if you want to keep the original data:
data <- matrix(1:100, ncol=5)
col.offset <- 2
row.offset <- 9
orig.data <- as.matrix(read.csv("test.csv", header=FALSE, stringsAsFactors=FALSE))
orig.cols <- orig.data[1:nrow(data), 1:col.offset]
data <- cbind(orig.cols, data)
orig.rows <- orig.data[1:row.offset, 1:ncol(data)]
data <- rbind(orig.rows, data)

editing particular cells of an Excel sheet

I have an Excel workbook of which I want to edit/fill some particular cells using R, without changing any of the formatting.
So far I've tried XLConnect package and it seems it could do what I'm looking for, I just didn't find a way to do it.
My straightforward approach to the problem:
wb <- loadWorkbook("file1.xls")
data1 <- readWorksheet(wb, "Sheet1", header=TRUE)
## adding a value to a particular cell:
data1[11,12] <- 3.2
## rewriting old data:
writeWorksheet(wb, data1, "Sheet1")
saveWorkbook(wb, "new_file1.xls")
However, this way the new workbook loses all of the previous formatting (merged cells, formulas, etc).
Is there a way to change values in some of the cells without losing any of the formatting of the remaining sheet?
Here is an example using R to automate Excel.
library(RDCOMClient)
xlApp <- COMCreate("Excel.Application")
wb <- xlApp[["Workbooks"]]$Open("file.1.xls")
sheet <- wb$Worksheets("Sheet1")
# change the value of a single cell
cell <- sheet$Cells(11,12)
cell[["Value"]] <- 3.1
# change the value of a range
range <- sheet$Range("A1:F1")
range[["Value"]] <- paste("Col",1:6,sep="-")
wb$Save() # save the workbook
wb$SaveAS("new.file.xls") # save as a new workbook
xlApp$Quit() # close Excel
If you dont need to use formula, you have 2 possible solutions.
You can use the {xlsx} package :
library(xlsx)
xlsx::write.xlsx(x = head(iris),file = "source3.xlsx",sheetName = "A")
hop3 <- xlsx::loadWorkbook(file = "source3.xlsx")
sheets <- getSheets(hop3)
rows <- getRows(sheets$A,rowIndex = 2) # get all the rows
cc <- getCells(rows,colIndex = 3)
xlsx::setCellValue(cc[[1]],value = "54321")
hop3$setForceFormulaRecalculation(TRUE)
xlsx::saveWorkbook(hop3,file = "output3.xlsx")
You also can use {XLconnect}
library(XLConnect)
XLConnect::writeWorksheetToFile(file = "source2.xlsx",data = head(iris),sheet="A")
hop2 <- XLConnect::loadWorkbook(file = "source2.xlsx")
createName(hop2, name = "plop", formula = "A!C2")
writeNamedRegion(hop2, 12345, name = "plop", header = FALSE)
Regards
Using the XLC$STYLE_ACTION.NONE style action should add your data without changing any formatting:
data1 <- readWorksheetFromFile("file1.xls", "Sheet1")
## adding a value to a particular cell:
data1[11,12] <- 3.2
## rewriting old data:
writeWorksheetToFile("file1.xls", data1, "Sheet1", styleAction = XLC$STYLE_ACTION.NONE)
Thanks to Martin for the suggestion to look into this in the comments.

Resources