我正在开发一个闪亮的应用程序,在该应用程序中,用户将上传excel文件,将对数据进行操作,然后将导出具有此数据的新excel文件供用户检查。我在downloadHandler函数上遇到问题。我以前每次都基于这样的上传数据创建一个全新的excel文件:
output$export <- downloadHandler(
filename = "answers.xlsx",
content = function(file){
write.xlsx(exportdata(), file)
})
})
这很好。
现在,我想编辑一个Excel文件,该文件将在发布应用程序时包括在内,并允许用户下载此编辑版本,如下所示:
output$export <- downloadHandler(
filename = "answers.xlsx",
content = function(file){
wb <- loadWorkbook("6rep-charts.xlsx")
writeData(wb, sheet = "Species Match Results", correlInput())
writeData(wb, sheet = "BS1 Data", bs1Input())
writeData(wb, sheet = "BS2 Data", bs2Input())
saveWorkbook(wb, file)
})
但是,这将导致错误Warning: Error in write_file: Expecting a single string value: [type=character; extent=0]. [No stack trace available]
。我不确定出什么问题了,因为当我在闪亮的应用程序外部运行内容部分时,它就可以正常工作。问题似乎出在saveWorkbook
命令中。
我想编辑一个现有的excel文件而不是创建一个新的excel文件的原因是,我在应用程序中包含的模板文件已经制作了图表,当将新数据写入文件时该图表应该会更改。用户希望能够自己编辑这些图表,而不仅仅是看到图表。如果有人有更简单的方法来做到这一点,那就太好了!预先感谢您的帮助!
使用this Excel文件的可复制示例:
library(shiny); library(readxl); library(xlsx)
ui <- shinyUI(fluidPage(
titlePanel("Old Faithful Geyser Data"),
fluidRow(
column(3,
downloadButton(outputId = "export",
label = "Export Results to Excel")
),
column(6,
dataTableOutput("data")
))))
server <- function(input, output) {
adata <- faithful[1:20,]
bdata <- faithful[21:50,]
cdata <- faithful[51:200,]
read_excel_allsheets <- function(filename, tibble = FALSE) {
sheets <- readxl::excel_sheets(filename)
x <- lapply(sheets, function(Y) {readxl::read_excel(filename, sheet = Y)})
if(!tibble) x <- lapply(x, as.data.frame)
names(x) <- sheets
x
}
output$data <- renderDataTable({
adata })
output$export <- downloadHandler(
filename = "answers.xlsx",
content = function(file){
wb <- loadWorkbook("./Data/template.xlsx")
writeData(wb, sheet = "Alpha", adata)
writeData(wb, sheet = "Beta", bdata)
writeData(wb, sheet = "Gamma", cdata)
saveWorkbook(wb, file="./Data/temp.xlsx", overwrite = T)
print("done")
Fin_WB<- read_excel_allsheets("./Data/temp.xlsx")
write.xlsx(Fin_WB, file)
} ) }
shinyApp(ui = ui, server = server)
答案 0 :(得分:0)
saveWorkbook
函数不喜欢用作content
函数的写函数。是的,令人困惑,但是我们仍然可以在content函数中使用它,只是不作为最后一步。我们必须使用经典的写入功能,例如write.xlsx
才能满足要求写入文件和文件路径的内容功能。
要解决此问题,我们在Data文件夹中创建一个临时文件(此文件夹将位于服务器和ui的目录中,并将被发布)。该程序将读取模板文件(请参见下面的特殊功能),对其进行修改,然后写入/覆盖 temp 文件。然后,该临时文件由read.xlsx
读取并分配,然后由write.xlsx
写入。这满足了内容功能,并允许我们使用模板进行导出。
read_excel_allsheets <- function(filename, tibble = FALSE) {
sheets <- readxl::excel_sheets(filename)
x <- lapply(sheets, function(X) readxl::read_excel(filename, sheet = X))
if(!tibble) x <- lapply(x, as.data.frame)
names(x) <- sheets
x
}
output$export <- downloadHandler(
filename = "answers.xlsx",
content = function(file){
wb <- loadWorkbook("./Data/template.xlsx")
writeData(wb, sheet = "Alpha", adata)
writeData(wb, sheet = "Beta", bdata)
writeData(wb, sheet = "Gamma", cdata)
saveWorkbook(wb, file="./Data/temp.xlsx", overwrite = T)
print("done")
Fin_WB<- read_excel_allsheets("./Data/temp.xlsx")
write.xlsx(Fin_WB, file)
})
}
为了阅读所有表,我们不能简单地使用read.xlsx
,因为它不会查看所有表。使用Jeromy Anglim创建的here函数,我们可以阅读excel中的所有图纸。这是read_excel_allsheets
函数。
答案 1 :(得分:0)
更简单的解决方案(由于信誉太低,我无法发表评论):
output$export <- downloadHandler(
filename = "answers.xlsx",
content = function(file){
wb <- loadWorkbook("./Data/template.xlsx")
writeData(wb, sheet = "Alpha", adata)
writeData(wb, sheet = "Beta", bdata)
writeData(wb, sheet = "Gamma", cdata)
saveWorkbook(wb, file="./Data/temp.xlsx", overwrite = T)
file.copy(from = "./Data/temp.xlsx", to = file)
})
不需要功能 read_excel_allsheets 。