Flo*_*nGD 5 javascript css r datatables shiny
我制作了一个闪亮的应用程序,其中有人上载文件,计算了一些比率,并且可以使用阈值滑块设置这些比率的格式。我用DT::formatStyle它,它真的很好。据我了解此功能,它创建一个回调来处理条件格式。
然后,我想使用中的按钮扩展名导出数据DT。我想在导出为pdf或打印时保留格式。事实证明这是行不通的:数据未经任何格式导出。我尝试设置exportOptions(list(stripHtml = FALSE)),但仍然无法正常工作。
同样令我惊讶的是,即使我直接从Firefox打印(如File / Print ...;我仅尝试使用Firefox,并且该应用程序将仅在Firefox中运行),颜色也会下降,但是字体粗细保持。我怀疑可能需要调整CSS,但是我不知道该怎么做。
我想有一种方法可以使pdf和/或打印文件“保持原样”,与我在浏览器中看到的最接近。下面是一个示例:
library(shiny)
library(DT)
library(dplyr)
data("starwars")
ui <- fluidPage(title = "Ratios",
sidebarLayout(
sidebarPanel(width = 2,
actionButton("button", "Go"), # Emulates data loading
sliderInput("seuil_j", "Threshold J",
min = 0, max = 80, value = 35, step = 0.5)),
mainPanel(
fluidRow(column(width = 12,
DT::dataTableOutput("ratios"))))
)
)
server <- function(input, output, session) {
donnees_ratios <- reactive({
req(input$button)
set.seed(14)
starwars %>%
select(1:10) %>% # DataTables is not happy with list columns
mutate(signe = sample(c(1, -1), replace = TRUE, size = nrow(.)),
ratio_j = signe * mass / height) %>%
select(name, mass, height, signe, ratio_j, everything())
})
output$ratios <- DT::renderDataTable({
donnees_ratios() %>%
creer_DT() %>%
formatter_DT(input)
})
}
creer_DT <- function(donnees) {
datatable(donnees,
rownames = FALSE,
class = 'cell-border stripe compact hover',
extensions = c("Buttons"),
options = list(
dom = 'Blfrtip',
buttons = list(
list(extend = "pdf",
exportOptions = list(stripHtml = FALSE,
columns = ':visible'),
orientation = 'landscape'),
list(extend = "print",
exportOptions = list(stripHtml = FALSE,
columns = ':visible')),
"excel", "csv", "colvis"),
language = list(
decimal = ",",
thousands = " " # small unbreakable space
)
)
)
}
formatter_DT <- function(table, input) {
table %>%
formatPercentage(columns = c("ratio_j"),
digits = 1L, dec.mark = ",", mark = " ") %>%
formatRound(columns = c("height", "mass"),
digits = 1L, dec.mark = ",", mark = " ") %>%
format_seuil("ratio_j", input$seuil_j)
}
format_seuil <- function(table, column, seuil) {
# Threshold for the aboslute value, and different coloring if higher or lower
formatStyle(table, column,
fontWeight = styleInterval(
c(-seuil / 100, seuil / 100), c("bold", "normal", "bold")),
color = styleInterval(
c(-seuil / 100, seuil / 100), c("red", "black", "orange")
))
}
shinyApp(ui, server)
Run Code Online (Sandbox Code Playgroud)
我可以导出为pdf或打印,但是显示已修改。我还可以使用rmarkdown和生成pdf knitr,但这是工作的两倍,感觉就像我错过了使用按钮扩展名的东西。
我希望这很清楚,并感谢您的帮助!
弗洛里安
PDF和print按钮有非常不同的行为。
print按钮的行为当您单击该print按钮时,您将使用用户代理(在此用例中为浏览器)将HTML文档呈现为分页文档 (PDF)。有一个名为CSS Paged Media的 W3C 标准,它定义了如何将 CSS 规则应用于分页媒体。
这些 CSS 规则包含在 CSS @media printat-rule 中。
这里有一个关于 CSS Paged Media 的综合指南:print-css.rocks。
处理 CSS Paged Media 并不简单:
wkhtmltopdf, weasyprint, XML Prince...) 用于生成带有 CSS Paged Media 的 PDF。使用这些用户代理之一非常容易,因为pandoc 2.0:它们可以替换LaTeX引擎。 HTML文件时,浏览器@media print默认不应用(它们@media screen按规则应用)。因此,很难找出@media print规则。我知道跟踪这些规则的唯一方法是使用 Chrome 开发人员工具(打开菜单,选择More tools和Rendering。在Rendering面板中,您可以模拟分页媒体选择print)。由于您想使用浏览器生成样式化的PDF,我认为 CSS 分页媒体规则是一种不切实际的方式。此外,使用带有动态 HTML 文档的无头用户代理作为 Shiny 应用程序非常复杂。所以,我的建议是忘记print按钮。
PDF按钮的行为DataTableslibrary 依赖于pdfmakeJavaScript 库来生成 PDF 文件。您可以将传递 JavaScript 函数的自定义样式应用到按钮的customize选项pdfHtml5。此函数自定义发送到pdfmakeAPI的文档对象。
为了了解JSON传递DataTables给 to的文档对象的结构pdfmake,可以将其输出到浏览器控制台:
library(shiny)
library(DT)
library(dplyr)
data("starwars")
ui <- fluidPage(title = "Ratios",
sidebarLayout(
sidebarPanel(width = 2,
actionButton("button", "Go"), # Emulates data loading
sliderInput("seuil_j", "Threshold J",
min = 0, max = 80, value = 35, step = 0.5)),
mainPanel(
fluidRow(column(width = 12,
DT::dataTableOutput("ratios"))))
)
)
server <- function(input, output, session) {
donnees_ratios <- reactive({
req(input$button)
set.seed(14)
starwars %>%
select(1:10) %>% # DataTables is not happy with list columns
mutate(signe = sample(c(1, -1), replace = TRUE, size = nrow(.)),
ratio_j = signe * mass / height) %>%
select(name, mass, height, signe, ratio_j, everything())
})
output$ratios <- DT::renderDataTable({
donnees_ratios() %>%
creer_DT() %>%
formatter_DT(input)
})
}
creer_DT <- function(donnees) {
datatable(donnees,
rownames = FALSE,
class = 'cell-border stripe compact hover',
extensions = c("Buttons"),
options = list(
dom = 'Blfrtip',
buttons = list(
list(extend = "pdf",
exportOptions = list(stripHtml = FALSE,
columns = ':visible'),
orientation = 'landscape',
customize = JS("function(doc){console.dir(doc);}")),
list(extend = "print",
exportOptions = list(stripHtml = FALSE,
columns = ':visible')),
"excel", "csv", "colvis"),
language = list(
decimal = ",",
thousands = " " # small unbreakable space
)
)
)
}
formatter_DT <- function(table, input) {
table %>%
formatPercentage(columns = c("ratio_j"),
digits = 1L, dec.mark = ",", mark = " ") %>%
formatRound(columns = c("height", "mass"),
digits = 1L, dec.mark = ",", mark = " ") %>%
format_seuil("ratio_j", input$seuil_j)
}
format_seuil <- function(table, column, seuil) {
# Threshold for the aboslute value, and different coloring if higher or lower
formatStyle(table, column,
fontWeight = styleInterval(
c(-seuil / 100, seuil / 100), c("bold", "normal", "bold")),
color = styleInterval(
c(-seuil / 100, seuil / 100), c("red", "black", "orange")
))
}
shinyApp(ui, server)
Run Code Online (Sandbox Code Playgroud)
您可以修改默认样式。这是更改tableHeader样式字体颜色的一个示例:
customize = JS("function(doc){doc.styles.tableHeader.color='yellow';}"))
Run Code Online (Sandbox Code Playgroud)
为了进一步定制,您必须编写自己的 JavaScript 函数。这是使用百分比格式化第五列的示例:
customize = JS("function(doc){doc.content[1].table.body.forEach(function(el,idx){if(idx>0){el[4].text=String((parseFloat(el[4].text)*100).toFixed(1))+'%'}})}"))
Run Code Online (Sandbox Code Playgroud)