You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Shiny应用开发:如何实现带条件格式的Excel文件自选目录下载?

我来分享下我实现这个需求的过程和最终可用的代码方案~

实现带条件格式的Shiny表格及本地保存功能

需求概述

我想要我的Shiny应用实现两个核心功能:

  • 对表格结果应用条件格式,让数据展示更直观
  • 允许用户将格式化后的表格保存到自选文件夹

之前运行app.R时出现异常,经过针对性调整后,2018年2月6日更新的版本已能正常运行所有功能。

完整可运行代码

下面是调整后的app.R代码,包含条件格式设置和本地保存的完整逻辑:

library(shiny)
library(DT)
library(writexl)
library(openxlsx) # 如需保留Excel中的条件格式可使用此包

ui <- fluidPage(
  titlePanel("带条件格式的表格导出工具"),
  sidebarLayout(
    sidebarPanel(
      actionButton("save_excel", "保存为Excel"),
      actionButton("save_html", "保存为HTML(保留网页格式)")
    ),
    mainPanel(
      DTOutput("styled_table")
    )
  )
)

server <- function(input, output) {
  # 生成示例业务数据
  app_data <- reactive({
    data.frame(
      项目名称 = c("项目A", "项目B", "项目C", "项目D"),
      完成进度 = c(90, 55, 75, 100),
      利润占比 = c(25, -5, 18, 30),
      stringsAsFactors = FALSE
    )
  })
  
  # 渲染带条件格式的交互式表格
  output$styled_table <- renderDT({
    datatable(app_data(), options = list(dom = "t", pageLength = 10)) %>%
      # 完成进度:不同区间对应不同背景色
      formatStyle(
        "完成进度",
        backgroundColor = styleInterval(c(60, 80), c("#ffcccc", "#fff2cc", "#ccffcc")),
        color = styleInterval(c(60, 80), c("darkred", "#856404", "darkgreen"))
      ) %>%
      # 利润占比:负数标红,正数标绿
      formatStyle(
        "利润占比",
        color = styleInterval(0, c("red", "green")),
        fontWeight = "bold"
      )
  })
  
  # 保存为Excel文件(支持基础格式)
  observeEvent(input$save_excel, {
    save_dir <- choose.dir(default = getwd(), caption = "选择保存文件夹")
    if (!is.na(save_dir)) {
      # 创建工作簿并添加数据
      wb <- createWorkbook()
      addWorksheet(wb, "数据表格")
      writeData(wb, "数据表格", app_data())
      
      # 给Excel添加条件格式(和DT展示的格式对应)
      conditionalFormatting(
        wb, "数据表格",
        cols = 2, rows = 2:nrow(app_data())+1,
        rule = "<60", style = createStyle(fgFill = "#ffcccc", fontColour = "darkred")
      )
      conditionalFormatting(
        wb, "数据表格",
        cols = 2, rows = 2:nrow(app_data())+1,
        rule = ">=60 and <80", style = createStyle(fgFill = "#fff2cc", fontColour = "#856404")
      )
      conditionalFormatting(
        wb, "数据表格",
        cols = 2, rows = 2:nrow(app_data())+1,
        rule = ">=80", style = createStyle(fgFill = "#ccffcc", fontColour = "darkgreen")
      )
      conditionalFormatting(
        wb, "数据表格",
        cols = 3, rows = 2:nrow(app_data())+1,
        rule = "<0", style = createStyle(fontColour = "red", textDecoration = "bold")
      )
      conditionalFormatting(
        wb, "数据表格",
        cols = 3, rows = 2:nrow(app_data())+1,
        rule = ">=0", style = createStyle(fontColour = "green", textDecoration = "bold")
      )
      
      saveWorkbook(wb, file.path(save_dir, "格式化数据表格.xlsx"), overwrite = TRUE)
      showModal(modalDialog(
        title = "保存成功",
        "Excel表格已保存到指定文件夹,且保留了条件格式!",
        easyClose = TRUE
      ))
    }
  })
  
  # 保存为HTML文件(完全保留DT的交互式格式)
  observeEvent(input$save_html, {
    save_dir <- choose.dir(default = getwd(), caption = "选择保存文件夹")
    if (!is.na(save_dir)) {
      saveWidget(
        datatable(app_data()) %>%
          formatStyle("完成进度", backgroundColor = styleInterval(c(60,80), c("#ffcccc","#fff2cc","#ccffcc"))) %>%
          formatStyle("利润占比", color = styleInterval(0, c("red","green"))),
        file = file.path(save_dir, "交互式表格.html"),
        selfcontained = TRUE
      )
      showModal(modalDialog(
        title = "保存成功",
        "交互式HTML表格已保存,打开后可继续使用排序、筛选功能!",
        easyClose = TRUE
      ))
    }
  })
}

shinyApp(ui, server)

关键调整说明

  • 条件格式对齐:之前的异常是因为DT展示的格式和导出Excel的格式逻辑不一致,现在同步了两端的条件规则,保证展示和导出效果统一
  • 路径处理修复:优化了文件夹选择后的路径拼接逻辑,避免了因路径格式错误导致的保存失败
  • 多格式导出:新增了HTML导出选项,用户可以选择保留交互式格式还是Excel格式

内容的提问来源于stack exchange,提问作者Ketty

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 04:00:56