Has anyone tried using the download handler in R Shiny to download a freshly created Excel file with XLConnect?
In the ui.R there is the unremarkable line:
downloadButton('downloadData', 'Download')
In the server.R there is the handler:
output$downloadData <- downloadHandler(
filename = function() { "output.xlsx" },
content = function(file){
wb <- loadWorkbook(file, create = TRUE)
createSheet(wb, name = "Sheet1")
writeWorksheet(wb, c(1:3), sheet = "Sheet1") # writes numbers 1:3 in file
saveWorkbook(wb)
}
)
I have no problem downloading a .csv and no problem creating the excel file with XLConnect. But when I run the code as above I get the following error in my Chrome browser:
IllegalArgumentException (Java): File extension "file1b683b9323bc" not
supported! Only *.xls and *.xlsx are allowed!
As far as I can see, XLConnect cannot write to a temporary file.
Has anyone got a solution or workaround?
One option would be to save the file in a specific location and then creating a download link pointing to it. However, this is not very Shiny-esque as multiple users would cause havok.
Many Thanks
Marcus
Try using this for the content(...) function; it works for me...
content = function(file){
fname <- paste(file,"xlsx",sep=".")
wb <- loadWorkbook(fname, create = TRUE)
createSheet(wb, name = "Sheet1")
writeWorksheet(wb, c(1:3), sheet = "Sheet1") # writes numbers 1:3 in file
saveWorkbook(wb)
file.rename(fname,file)
}
The problem is that file is a randomly generated temp file, without an extension, whereas saveWorkbook(...) requires the .xlsx extension. So this just appends .xlsx to file and uses that for all the XLConnect manipulations, then renames the final file to the original name (e.g., strips off the extension).
Related
I have a function that receives DataFrame does a bunch of transformations with openxlsx and exports the data from R to .xlsx:
export_workbook_from_df <- function(data, path) {
wb <- openxlsx::createWorkbook()
openxlsx::addWorksheet(wb, sheetName = "Sheet1")
openxlsx::openxlsx_setOp("numFmt", "0,00")
number_format <- openxlsx::createStyle(numFmt = "Number") # create thousands format
wb |>
openxlsx::addStyle(sheet = 1,
number_format,
rows = 1:nrow(dados) + 1, cols = c(6),
gridExpand = T
)
openxlsx::writeData(wb, sheet = 1, data)
openxlsx::saveWorkbook(wb, paste0(path, ".xlsx"))
}
if I try to save as .xls using openxlsx::saveWorkbook(wb, paste0(path, ".xls")) I get the following error:
Which roughly translates to:
The format of the file and the extension don't correspond. The file may be corrupted or not be safe. Don't open it, unless you trust the source. Do you want to open anyway?
The file works fine if I save it as .xlsx and manually save as .xls within Excel;
I also tried using XLConnect to load the file after is saved and export in a different format, like:
openxlsx::saveWorkbook(wb, paste0(path, ".xlsx"))
XLConnect::loadWorkbook(paste0(path, ".xlsx")) %>%
XLConnect::saveWorkbook(paste0(path, ".xls"))
While it does export the file as .xls I get the same error.
It may be worth mentioning that when I open the file I get exactly the same data as in the .xlsx file when using either methods (using openxlsx and XLConnect)
The xls and xlsx file formats are not the same: XLSX is a zipped, XML-based file format. Microsoft Excel 2007 and later uses XLSX as the default file format when creating a new spreadsheet. Support for loading and saving legacy XLS files is also included. XLS is the default format used with Office 97-2003. When you try to load the XLSX which you saved as an XLS Excel barfs as above because it is expecting the old binary format but it is encountering a zipped XML-based one instead.
I am trying to link files to a xlsx file. I have xlsx file named my file.xlsx
I have a myfolder and 3 files are in that folder names file1.pdf file2.pdf and file3.pd
in my xlsx file in Sheet1, I have a column with header named File and 3 names file1, file2 and file3 .
xlsx_file <- '/Users/admin/Desktop/myfolder/myfile.xlsx'
I go to specific sheet
myxlsx <- read.xlsx(xlsx_file, sheet = 'Sheet1')
filePaths <- c("file1", "file2", "file3")
Then I make the link between the folder and each cell of the xlsx
myfiles <- sprintf("/User/admin/Desktop/myfolder/%s.pdf", filePaths)
I make it hyperlink
class(myfiles) <- 'hyperlink'
I load it as wb
wb <- loadWorkbook(file = xlsx_file)
I write to it in sheet1, based on myfiles and starting from second row
writeData(wb,"Sheet1",x = myfiles,startRow = 2)
then save it
saveWorkbook(wb, xlsx_file, overwrite = TRUE)
so far so good, the problem is that it will show the path to the file in the xlsx.
how can I hide it?
I dont want the hyperlink to show
/User/admin/Desktop/myfolder/file1.pdf
/User/admin/Desktop/myfolder/file2.pdf
/User/admin/Desktop/myfolder/file3.pdf
instead I want to show the hyperlink to be
file1.pdf
file2.pdf
file3.pdf
Depending on your version of excel it will be a different dialog, but should still be the same methodology. Keep "Use relative path for hyperlink" active and dont specify a folder in the Path: filename.pdf
readxl_1.1.0
I'm trying to read the file from this link (US gov website)
https://www.cftc.gov/files/dea/history/dea_com_xls_2018.zip
When I unzip the xls file inside, and read with readxl::read_excel, it fails with the error message failed to open C:\path to file
I can open the file in excel, save it to csv and read it to R by fread, but there are a lot of those files, so that's tedious. By the way, some other xls files downloaded from the same webpage can be read by read_excel
There's something odd about the xls file. I think it's because it contains some VBA code.
If you are happy to use XLConnect here is an alternative that reads the file.
library(XLConnect)
extdir = tempdir()
unzip("dea_com_xls_2018.zip", exdir = extdir)
file = list.files(extdir, pattern = 'xls', full.names = T)
wb = loadWorkbook(file)
ws = readWorksheet(wb, sheet = 1)
dim(ws)
#[1] 11131 126
My question seems pretty straight forward but for some reason I haven't found any answer yet. :(
I build a shiny app and I want to use a download button for the computed matrices. Is there any way to use write.csv in order to download a .csv with multiple tabs (for different matrices), so the user isn't forced to download 3-4 different files?
Thank you in advance
Adding to all the comments, XLConnect is a good idea. The download handler code would be:
library(XLConnect)
output$dwnld <- donwloadHandler(
filename = "xyz.xlsx"
},
content = function(file) {
wb <- loadWorkbook(file, create = TRUE)
createSheet(wb, name="x")
createSheet(wb, name="y")
writeWorkSheet(wb, data=df_x, sheet=x, header=TRUE)
writeWorkSheet(wb, data=df_y, sheet=y, header=TRUE)
saveWorkbook(wb)
}
)
I get the corruption error when I try to open the Excel workbook created in R.
I tried with both .xlsx and .xls extensions but neither worked!
The code that I used for doing all this is:
wb <- loadWorkbook("RCreated.xls", create = TRUE);
saveWorkbook(wb)
createSheet(wb, name = "First")
HELP!
Create the sheet BEFORE saving the workbook.