R语言 Shiny可以追加到现有的Excel工作簿吗?

toe95027  于 2023-06-19  发布在  其他
关注(0)|答案(1)|浏览(125)

用例:存在多表Excel工作簿,其中的内容无法在R中处理,因此上传整个工作簿并使用新内容重写它不是一个选项。xlsx库的write.xlsx2函数可以从R会话向现有工作簿追加一个新工作表,但我无法让Shiny做同样的事情。
下面是一个示例Shiny应用程序,用于从现有Excel工作簿中读取工作表,更改数据,并将新工作表写回同一Excel工作簿,而不会干扰工作簿中的现有工作表。我使用的test_excel工作簿在一个名为“Test_data”的工作表中包含一个3 x 3的随机数矩阵,带有列标题。下面的示例代码基于另一个StackOverflow查询的示例,但经过修改以适合我的特定用例。另一个查询的答案是使用downloadHandler(),我正在使用它,但它覆盖了现有的Excel工作簿,而不是追加到它。如何修改脚本使其附加到现有工作簿中?

library(shiny)
library(xlsx)
library(readxl)

ui <- fluidPage(   
    titlePanel("Writer App"),
    sidebarLayout(
        sidebarPanel(fileInput("file","Read File Here", accept = ".xlsx"),
            downloadButton('download1',"Save to Excel")
        ),
        mainPanel(tableOutput("table1"))
    )
)

server <- function(input, output) {
        observeEvent(eventExpr  = input$file,{
            data <- read_xlsx(input$file$datapath,sheet = "Test_data")
            div_mtx <- data/5

            output$table1 <- renderTable({    
                div_mtx
            }) # end of renderDataTable
    
            output$download1 <- downloadHandler(filename = input$file$name,
                content = function(file) {
                write.xlsx2(div_mtx,file,sheetName="div_mtx",row.names=FALSE,append=TRUE)
            }) # end of downloadHandler
        }) # end of observeEvent
} # end of server

shinyApp(ui,server)
yrdbyhpb

yrdbyhpb1#

一种解决方案是在R脚本文件中定义一个函数,并从Shiny应用程序服务器代码中获取该文件的源代码,然后调用该函数从服务器环境中追加一个数据对象,作为本地Excel工作簿中的新工作表。R脚本文件保存在包含app.R文件的文件夹中名为resources的目录中,该目录包含以下代码:

library(rJava)
library(xlsx)

write_data <- function(x, y, z) {
  # x is local data object, y is name of Excel workbook to modify, 
  # z is sheetName in workbook
  write.xlsx2(x, y, sheetName=z, col.names=TRUE, row.names=TRUE, 
              append=TRUE, showNA=FALSE)
  }

app.R脚本包含以下内容:

library(shiny)
library(xlsx)
library(readxl)
ui <- fluidPage(   
    titlePanel("Writer App"),
    sidebarLayout(
        sidebarPanel(
            fileInput("file","Load File to Modify", accept = ".xlsx"),
            textOutput("filename1"),
            actionButton("save","Click to Save")
        ),
        mainPanel(tableOutput("table1"))
    )
)

server <- function(input, output) {

        observeEvent(eventExpr  = input$file,{
            # Save input file name as variable available to global 
            # environment - note double arrow * <<- *
            input_workbook <<- input$file$name
            output$filename1 <- renderText({paste0(
                       "The file to modify is ", input_workbook)})
            # Read data from input Excel workbook, sheet named "Test_data"
            data <- read_xlsx(input$file$datapath, sheet = "Test_data")
            div_mtx <- data/5

            # Use renderTable() to display changed data to Shiny browser 
            # window
            output$table1 <- renderTable({div_mtx})
            
            # Load the source code for the write_data function and invoke 
            # that function with the changed data
            source("./resources/functions.R")
            write_data(div_mtx, input_workbook, "div_mtx")
        }) # end of observeEvent 1
} # end of server

shinyApp(ui, server)

相关问题