1 环境建设
1.1 复制文件至shinyserver
cp -r /www/wwwroot/www.mmphcrc.com/pdf/jupyter/HuLinhuiPy/Shiny学习笔记/download-word-file /srv/shiny-server/app/r/download-word-file
1.2 查看报错信息
查看最新生成文件的最后50行
latest_file=$(ls -t /var/log/shiny-server/ | head -1)
tail -n 50 /var/log/shiny-server/$latest_file
1.3 通过终端安装包
Rscript install_packages.R package1,package2,package3
Rscript install_packages.R rlang
install_packages.R
的内容
# 安装所需的R包(不检查是否已安装)
<- function(packages) {
install_packages for (package in packages) {
install.packages(package, dependencies = TRUE, lib="/usr/local/lib/R/site-library")
}
}
# 从命令行参数获取要安装的包列表
<- commandArgs(trailingOnly = TRUE)
args <- strsplit(args, ",")[[1]]
packages_to_install
# 安装包
install_packages(packages_to_install)
# 加载已安装的包
for (package in packages_to_install) {
library(package, character.only = TRUE)
}
2 示例
2.1 officer生成文档并下载
- 代码
library(shiny)
library(officer)
library(ggplot2)
<- fluidPage(
ui
# Application title
titlePanel("Old Faithful Geyser Data"),
sidebarLayout(
sidebarPanel(
sliderInput("bins", "Number of bins:", min = 1, max = 50, value = 30),
downloadButton("downloadReport", "Download report")
),mainPanel(
plotOutput("distPlot")
)
)
)
<- function(input, output) {
server
<- reactive({
my_plot ggplot(faithful, aes(eruptions)) + geom_histogram(bins = input$bins)
})$distPlot <- renderPlot({
outputmy_plot()
})$downloadReport <- downloadHandler(
outputfilename = function() {
paste("report-", Sys.Date(), ".docx", sep="")
},content = function(file) {
<- read_docx()
doc <- body_add_gg(doc, value = my_plot())
doc print(doc, target = file)
}
)
}
shinyApp(ui = ui, server = server)
2.2 quickquery
2.2.1 index.Rmd
文件内容
---
: "快捷查询"
title: "交互性文档"
description:
output:
html_document: custom.css
css:
includes: icon.html # 将网页内容添加至html头部
in_header-external-icon: true
link-external-newwindow: true
link: shiny
runtime: 'https://ts1.cn.mm.bing.net/th/id/R-C.cddc513b06b31b85a22283bc2f975fbf?rik=JUJ%2bvImS%2fC9YbA&pid=ImgRaw&r=0'
image---
<!-- # 一般信息
> Shiny官网 <https://shiny.posit.co/r/getstarted/shiny-basics/lesson1/index.html>
> 日志查看路径: `/var/log/shiny-server` -->
```{r}
#| echo: false
#| warning: false
#| message: false
library(stringr)
library(magrittr)
library(DT)
library(DBI)
library(RMySQL)
# Global variables can go here
con <- dbConnect(
MySQL(),
user = "hulinhui2",
password = "kJxa2TGzHTJ8C83M",
host = "www.mmphcrc.com",
dbname = "hulinhui2"
)
# Define the UI
ui <- fluidPage(
includeCSS("custom.css"),
tags$head(
tags$style(
HTML(
"
#notification {
display: none;
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 1000;
padding: 10px;
background-color: #f8d7da;
color: #721c24;
border: 1px solid #f5c6cb;
border-radius: 5px;
text-align: center;
}
"
)
),
tags$script(
HTML(
"
Shiny.addCustomMessageHandler('showNotification', function(message) {
$('#notification').text(message);
$('#notification').fadeIn().delay(3000).fadeOut();
});
"
)
)
),
fluidRow(
column(width = 12,
passwordInput('authcode', '输入验证码', '')
),
column(width = 12,
textInput('keyword', '输入查询关键词', '', placeholder = '输入关键词进行查询')
),
),
fluidRow(
column(width = 12,
dataTableOutput("table")
),
tags$div(id = "notification", "这是一个通知")
),
fluidRow(
column(width = 12,
textInput('rowid', 'id', '', placeholder = '输入id进行更新')
),
column(width = 12,
textInput('title', '标题', '')
),
column(width = 12,
textAreaInput("content", "内容", "", rows = 10, width = "500px"),
),
column(width = 12,
textInput("tags", "标签", ""),
),
column(width = 12,
actionButton("updateRow", "更新"),
actionButton("addRow", "新增")
),
)
)
server <- function(input, output, session) {
true_authcode <- format(Sys.Date(), "%Y%m%d")
# 监听关键词输入事件
observeEvent(input$keyword, {
output$table <- renderDataTable({
authcode <- input$authcode # 获取验证码
keyword <- input$keyword
if (is.null(keyword) || trimws(keyword) == "") {
return(NULL) # 如果关键词为空,返回空表格
}
if (authcode != true_authcode) { # 假设验证码不正确
session$sendCustomMessage(type = "showNotification", message = "验证码不正确")
return(NULL) # 返回空表格
}
dbSendQuery(con, "SET NAMES utf8") # 否则不能查询中文,或者查询英文时返回的中文为乱码
# 在数据库中执行查询
# keyword <- enc2utf8(keyword)
query <- paste("SELECT * FROM `quickquerydb` WHERE `content` LIKE '%", keyword, "%'", sep = "")
result <- dbGetQuery(con, query) # 返回查询结果
# 高亮显示关键词
highlight_keyword_pattern <- sprintf("<span style='background-color: yellow;'>%s</span>", keyword)
# 大小写敏感
# result$content <- str_replace_all(result$content, keyword, highlight_keyword_pattern)
# 大小写不敏感
result$content <- str_replace_all(result$content, regex(paste0('(?i)', keyword)), paste0("<span style='background-color: yellow;'>", "\\0", "</span>"))
result$content <- str_replace_all(result$content, "\n", "<br>")
result
},
escape = FALSE)
})
# 监听id输入事件
observeEvent(input$rowid, {
authcode <- input$authcode # 获取验证码
rowid <- input$rowid
if (rowid != "") {
if (authcode != true_authcode) { # 假设验证码不正确
session$sendCustomMessage(type = "showNotification", message = "验证码不正确")
return(NULL) # 返回空表格
}
dbSendQuery(con, "SET NAMES utf8") # 否则不能查询中文,或者查询英文时返回的中文为乱码
# 在数据库中执行查询
query <- paste("SELECT * FROM `quickquerydb` WHERE `id` = ", rowid, sep = "")
result <- dbGetQuery(con, query) # 返回查询结果
title = result$title
content = result$content
tags = result$tags
} else {
title = ''
content = ''
tags = ''
}
updateTextInput(session, "title", value = title)
updateTextInput(session, "content", value = content)
updateTextInput(session, "tags", value = tags)
})
# 监听更新按钮被点击
observeEvent(input$updateRow, {
authcode <- input$authcode # 获取验证码
rowid <- input$rowid
title <- input$title
content <- input$content
tags = input$tags
if (rowid != "") {
if (authcode != true_authcode) { # 验证码不正确
session$sendCustomMessage(type = "showNotification", message = "验证码不正确")
updateTextInput(session, "title", value = '')
updateTextInput(session, "content", value = '')
updateTextInput(session, "tags", value = '')
return(NULL) # 返回空内容
}
if (title == "" | content == "") {
session$sendCustomMessage(type = "showNotification", message = "标题和内容不能为空")
return(NULL) # 返回空内容
}
dbSendQuery(con, "SET NAMES utf8")
# 构建UPDATE语句
query <- paste("UPDATE `quickquerydb` SET title = '", title,
"', content = '", content,
"', tags = '", tags,
"' WHERE id = ", rowid, sep="")
# 在数据库中执行更新
result <- dbSendQuery(con, query)
session$sendCustomMessage(type = "showNotification", message = "完成更新")
} else {
session$sendCustomMessage(type = "showNotification", message = "id为空,更新失败!")
}
})
# 监听新增按钮被点击
observeEvent(input$addRow, {
authcode <- input$authcode # 获取验证码
title <- input$title
content <- input$content
tags <- input$tags
if (title == "" | content == "") {
session$sendCustomMessage(type = "showNotification", message = "标题和内容不能为空")
return(NULL) # 返回空内容
} else {
if (authcode != true_authcode) { # 验证码不正确
session$sendCustomMessage(type = "showNotification", message = "验证码不正确")
return(NULL) # 返回空内容
}
dbSendQuery(con, "SET NAMES utf8")
# 构建INSERT语句
query <- paste("INSERT INTO `quickquerydb` (title, content, tags) VALUES ('", title, "', '", content, "', '", tags, "')", sep="")
# 执行INSERT语句
result <- dbSendQuery(con, query)
session$sendCustomMessage(type = "showNotification", message = "完成插入")
}
})
onStop(function() {
dbDisconnect(con) # 关闭数据库连接
})
}
options <- list(height = 800)
# Return a Shiny app object
shinyApp(ui = ui, server = server, options = options)
```\
2.2.2 custom.css
的内容
/*自定义滚动条*/
::-webkit-scrollbar {
/*滚动条整体样式*/
width : 6px; /*对应竖滚动条的宽度*/
height : 8px; /*对应横滚动条的高度*/
}::-webkit-scrollbar-thumb {
/*滚动条里面小方块*/
border-radius: 6px;
background-color: #9e9e9e;
}::-webkit-scrollbar-track {
/*滚动条里面轨道*/
background: #ffffff;
/* border-radius: 6px; */
}
2.2.3 icon.html
的内容
<link rel="icon" href="favicon.ico" type="image/x-icon">