openxlsx 的功能在 R 控制台上有效,但在 Shiny 中失败

Function with openxlsx works on R console but fails in Shiny

我正在尝试使用 openxlsx 包编写一个函数来包装一些数据帧以导出到 Excel。当 运行 来自 Shiny 应用程序中的 downloadHandler 函数时失败,但在 R.

的控制台上运行良好

运行良好的常规 R 脚本:

library(openxlsx)

datDf1 <- data.frame(grr = c(1:10),
                     hrm = c(11:20),
                     boo = c(21:30))
datDf2 <- data.frame(will = c(31:40),
                     this = c(41:50),
                     work = c(51:60))

addSheetFun <- function(df, datName){
  addWorksheet(wbExp, sheetName=datName)
  writeData(wbExp, sheet=datName, df)
  freezePane(wbExp, sheet=datName, firstRow=TRUE)
  setColWidths(wbExp, sheet=datName, widths="auto", cols=1:ncol(df))
}

wbExp <- createWorkbook()
addSheetFun(datDf1, "SheetOne")
addSheetFun(datDf2, "SheetTwo")

闪亮申请失败:

ui.r

shinyUI(
  fluidPage(
    downloadButton("xlExl", "Click to Export")
  )
)

server.r

library(openxlsx)
library(shiny)

shinyServer(
  function(
    input, output, session
  ){
    addSheetFun <- function(df, datName){
      addWorksheet(wbExp, sheetName=datName)
      writeData(wbExp, sheet=datName, df)
      freezePane(wbExp, sheet=datName, firstRow=TRUE)
      setColWidths(wbExp, sheet=datName, widths="auto", cols=1:ncol(df))
    }

    output$xlExl <- downloadHandler(
      filename="Test.xlsx",
      content=function(file){
        datDf1 <- data.frame(grr = c(1:10),
                             hrm = c(11:20),
                             boo = c(21:30))
        datDf2 <- data.frame(will = c(31:40),
                             this = c(41:50),
                             work = c(51:60))
        wbExp <- createWorkbook()
        addSheetFun(datDf1, "SheetOne")
        addSheetFun(datDf2, "SheetTwo")
        saveWorkbook(wbExp, file, overwrite=TRUE)
      }
    )
  }
)

当 运行 来自 Shiny 时我得到的错误是:“警告:%in% 错误:找不到对象 'wbExp' [没有可用的堆栈跟踪]

我试着把这个添加到 addSheetFun 的顶部:

if (exists("wbExp")) {
  wbExp <- wbExp
}
else {
  wbExp <- createWorkbook()
}

然后这样调用它:

wbExp <- addSheetFun(datDf1, "SheetOne")
wbExp <- addSheetFun(datDf2, "SheetTwo")

但这只能设法用第二个覆盖第一个 sheet。

想法?

错误解释了失败的原因,它找不到您的 wbExp

克服错误的最简单方法可能是在 createWorkbook.

时使用 <<-

所以wbExp <<- createWorkbook()。那么你闪亮的应用程序应该可以工作了。

这类似于'superassignment',将在父环境中分配对象(建议阅读http://adv-r.had.co.nz/Environments.html

或者,您可以在 downloadHandler 之前包含 addSheetFun wbExp <- createWorkbook().

所以server.R

library(openxlsx)
library(shiny)

shinyServer(
  function(
    input, output, session
  ){


    output$xlExl <- downloadHandler(
      filename="Test.xlsx",
      content=function(file){
        datDf1 <- data.frame(grr = c(1:10),
                             hrm = c(11:20),
                             boo = c(21:30))
        datDf2 <- data.frame(will = c(31:40),
                             this = c(41:50),
                             work = c(51:60))

        addSheetFun <- function(df, datName){
          addWorksheet(wbExp, sheetName=datName)
          writeData(wbExp, sheet=datName, df)
          freezePane(wbExp, sheet=datName, firstRow=TRUE)
          setColWidths(wbExp, sheet=datName, widths="auto", cols=1:ncol(df))
        }

        wbExp <- createWorkbook()
        addSheetFun(datDf1, "SheetOne")
        addSheetFun(datDf2, "SheetTwo")
        saveWorkbook(wbExp, file, overwrite=TRUE)
      }
    )
  }
)