R Shiny中读取RTF文件传入renderDiffr的响应式函数实现方法
RShiny RTF文件对比实现方案
原有代码核心问题
- 错误使用
file.choose():该函数仅支持R本地控制台的交互选文件,无法在Shiny网页端生效,你之前注释掉的fileInput才是Shiny原生的响应式文件选择组件,会自动处理文件上传、返回文件路径等元数据。 - 响应式逻辑错误:自定义的响应式表达式调用时必须加
()取值,且对比逻辑没有绑定按钮点击事件,会在应用启动时就提前执行,无法拿到用户后续选择的文件路径。 - RTF格式不兼容:
diffr默认读取纯文本文件,直接传入RTF会解析出大量格式控制符,需要先提取RTF中的纯文本内容再做对比。
RTF文件读取方法
使用striprtf包的read_rtf()函数即可直接读取RTF文件的纯文本内容,该函数可以直接写在Shiny的响应式表达式中,在传入renderDiffr之前完成文件解析。解析后的纯文本可以先写入临时txt文件,再将临时文件路径传给diffr即可正常完成对比。
可运行修正代码
先安装缺失依赖:
install.packages(c("shiny", "diffr", "striprtf"))
完整应用代码:
library(shiny) library(diffr) library(striprtf) ui <- fluidPage( titlePanel(HTML("<center>Comparison of two RTF files</center>")), sidebarLayout( position = "left", sidebarPanel( # 启用文件选择组件,限制仅可选择.rtf格式文件 fileInput("file1", "Select first RTF file", accept = ".rtf"), fileInput("file2", "Select second RTF file", accept = ".rtf"), actionButton("goButton", "Compare", class = "btn-success") ), mainPanel( verbatimTextOutput("path1"), verbatimTextOutput("path2"), diffrOutput("diff_result") ) ) ) server <- function(input, output, session) { # 展示已选中的第一个文件信息 output$path1 <- renderText({ req(input$file1) paste("Selected first file:", input$file1$name) }) # 展示已选中的第二个文件信息 output$path2 <- renderText({ req(input$file2) paste("Selected second file:", input$file2$name) }) # 绑定对比按钮点击事件,仅点击后执行对比逻辑 diff_content <- eventReactive(input$goButton, { # 校验两个文件均已上传 req(input$file1, input$file2) # 读取RTF文件纯文本内容 text1 <- read_rtf(input$file1$datapath) text2 <- read_rtf(input$file2$datapath) # 写入临时纯文本文件供diffr调用 tmp_file1 <- tempfile(fileext = ".txt") tmp_file2 <- tempfile(fileext = ".txt") writeLines(text1, tmp_file1) writeLines(text2, tmp_file2) # 生成对比结果 diffr(tmp_file1, tmp_file2, before = "First RTF", after = "Second RTF") }) # 渲染差异对比结果 output$diff_result <- renderDiffr({ diff_content() }) } shinyApp(ui, server)
内容的提问来源于stack exchange,提问作者Persimmons
相关产品推荐
相关产品推荐

