使用 DT(DataTables 按钮扩展)导出表格时保持格式

2024-03-21

我制作了一个闪亮的应用程序,有人上传文件,计算一些比率,并且可以使用阈值滑块来格式化这些比率。我用DT::formatStyle为此,它工作得非常好。据我了解这个函数,它创建一个回调来处理条件格式。

然后,我想使用按钮扩展导出数据DT。我想在导出为 pdf 或打印时保留格式。事实证明这不起作用:数据在没有任何格式的情况下导出。我尝试设置exportOptions(list(stripHtml = FALSE)),但还是不行。

同样令我惊讶的是,即使我直接从 Firefox 打印(作为文件/打印...;我只尝试过使用 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 = "&#8239;"  # small unbreakable space
              )
            )
  )
}

formatter_DT <- function(table, input) {
  table %>% 
    formatPercentage(columns = c("ratio_j"),
                     digits = 1L, dec.mark = ",", mark = "&#8239;") %>%
    formatRound(columns = c("height", "mass"),
                digits = 1L, dec.mark = ",", mark = "&#8239;") %>%
    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)

我可以导出为 pdf 或打印,但显示已修改。我还可以生成一个pdfrmarkdown and knitr,但这会是两倍的工作,而且感觉好像我错过了使用按钮扩展的东西。

我希望这是清楚的,感谢您的帮助!

Florian


tl;dr 你不能继续格式化;你必须编写一个自定义 JavaScript 函数。

PDF and print按钮有非常不同的行为。

The print按钮行为

当您单击print按钮,您使用用户代理(在本用例中为浏览器)来呈现HTML文档为分页文档 (PDF)。有一个 W3C 标准名为CSS 分页媒体它定义了 CSS 规则如何应用于分页媒体。
这些 CSS 规则包含在 CSS 中@media printat规则。
这里有一个关于 CSS 分页媒体的综合指南:print-css.rocks https://print-css.rocks/.

处理 CSS 分页媒体并不简单:

  • 浏览器糟糕地实现了 CSS 分页媒体标准;无头用户代理(wkhtmltopdf, weasyprint, XML Prince...) 用于使用 CSS 分页媒体生成 PDF。使用这些用户代理之一非常容易,因为pandoc 2.0: 他们可以替换LaTeX引擎。
  • 当你打开一个HTML文件,浏览器不适用@media print默认情况下(它们适用@media screenat 规则)。所以,很难弄清楚@media print规则。我知道跟踪这些规则的唯一方法是使用 Chrome 开发者工具(打开菜单,选择More tools and Rendering。在里面Rendering面板,您可以模拟分页媒体选择print).

由于您想使用浏览器生成样式PDF,我认为CSS分页媒体规则是一种不切实际的方式。此外,使用带有动态 HTML 文档的无头用户代理作为 Shiny 应用程序非常复杂。所以,我的建议是忘记print button.

The PDF按钮行为

DataTables库依赖于pdfmake用于生成 PDF 文件的 JavaScript 库。您可以应用自定义样式,将 JavaScript 函数传递给customize的选项pdfHtml5 button https://datatables.net/reference/button/pdfHtml5。该函数自定义发送到的文档对象pdfmake API https://github.com/bpampuch/pdfmake.

为了理解该结构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 = "&#8239;"  # small unbreakable space
              )
            )
  )
}

formatter_DT <- function(table, input) {
  table %>% 
    formatPercentage(columns = c("ratio_j"),
                     digits = 1L, dec.mark = ",", mark = "&#8239;") %>%
    formatRound(columns = c("height", "mass"),
                digits = 1L, dec.mark = ",", mark = "&#8239;") %>%
    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)

您可以修改默认样式。这是一个更改字体颜色的示例tableHeader style:

customize = JS("function(doc){doc.styles.tableHeader.color='yellow';}"))

为了进一步定制,您必须编写自己的 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))+'%'}})}"))
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 DT(DataTables 按钮扩展)导出表格时保持格式 的相关文章

随机推荐

  • 从方法返回元组

    我正在编写一个方法 成功时返回一个元组 但是None失败时 我还没有最终确定None 作为失败案例返回 但它是选择之一 我们可以回来吗 1 1对于失败案例 我正在寻找最好的Pythonic方法来实现这一点 以便拆包很容易 请让我知道我们如何
  • 如何添加链接来下载pdf文件nuxt?

    我只想在 nuxt 项目中添加一个下载 pdf 文件的链接 我怎么做 我已经尝试过以下方法 a class btn btn sm btn sub color Download a 它适用于图像 但不适用于 pdf 文件 我发现vue pdf
  • 如何使用 Maven 构建可运行的 JavaFX 应用程序?

    我是 JavaFX 新手 我使用 Maven 创建了一个 Hello World 项目 当我在 Eclipse 中运行它时 它工作得很好 public static void main String args launch args Ove
  • 将类元素更改为界面元素

    当对类图进行建模时 工具箱包含类和接口的特殊对象 它们的不同之处在于它们的图标 这些图标显示在Project Browser如果它们被添加到图表中 它们的属性似乎是相同的 是否可以更改创建为的对象class到一个类型的对象interface
  • 如何在测试已弃用的 Scala 函数时抑制弃用警告?

    假设我有一个库 其中包含已弃用的函数和首选函数 object MyLib def preferredFunction deprecated Use preferredFunction instead 1 0 def deprecatedFu
  • Matlab:如何导出voronoi图中多边形的顶点(坐标)?

    我手头有一个创建的函数文件 它是在图像中画线 img drawline point1 point2 color img 它用于连接图像内的任意两点 我被要求在图像中创建 voronoi 图 不使用绘图功能 目前 我正在尝试显示图像中的线条
  • 解密xml文档时出现问题

    我编写了一些代码来加密包含用户凭据的 XML 配置文件 以及解密该文件的代码 当我在本地计算机上同时运行加密和解密时 它按预期工作 但是 当我部署程序时 仅使用解密代码 xml 文件将无法解密 我收到加密异常 错误数据 这是我的代码 pub
  • FutureWarning:不推荐使用非元组序列进行多维索引,使用“arr[tuple(seq)]”

    我搜索过 S O 但找不到答案 当我尝试使用 seaborn 绘制分布图时 我收到了未来警告 我想知道这里可能出了什么问题 import pandas as pd import numpy as np import seaborn as s
  • 为什么 PHP 中的 _GET 会错误地解码斜杠?

    今天我遇到了 PHP 的一些奇怪问题 我在文档中找不到正确的解释 考虑以下代码 代码很简单 它在 url 上采用单个 t 参数并将其输出回来 因此 如果您使用 test php t 5Ca 5c 是 调用它 我希望看到 a 然而 这就是我得
  • JavaScript 生成 dataURL 格式的透明 1X1 像素

    我想知道一种在 JavaScript 中生成单个像素并将其转换为 base64 的方法 理想的函数是 function createPixel hexColor opacity Calculate return base64DataURL
  • 为什么 Gensim doc2vec 给出 AttributeError: 'list' object has no attribute 'words'?

    我正在尝试使用以下代码来实验 gensim doc2vec 据我从教程中了解到 它应该有效 然而它给出了属性错误 列表 对象没有属性 单词 from gensim models doc2vec import LabeledSentence
  • 我可以用javascript创建下雨效果吗?

    我需要为我的网站实现这样的目标 闪光雨效果 http active tutsplus com tutorials effects create a rain effect in flash using actionscript 30 这可以
  • 在 64 位机器上,我可以安全地并行操作 64 位四字的各个字节吗?

    背景 我正在对图像中的行和列进行并行操作 我的图像是 8 位或 16 位像素 而我使用的是 64 位机器 当我并行对列进行操作时 两个相邻列可能共享相同的 32 位int或 64 位long 基本上 我想知道是否可以安全地并行操作同一四字的
  • 忽略正则表达式匹配中的换行符

    我正在尝试使用以下脚本将所有匹配的事件替换为标题大小写 当过滤词之间有换行符 在本例中为 ABC 和 DEF 时 该行不会按预期被替换 在这种情况下如何忽略换行符 编辑 我不想从字符串中完全删除所有换行符 而只想删除过滤词之间的换行符 Ed
  • 加载 YouTube 视频并收听 onPlayerStateChange

    单击链接后 我尝试播放 YouTube 视频 并在播放完毕后用图像替换该视频 上半场很轻松 然而我在下半场遇到了麻烦 最初我只是简单地附加了一个iframe嵌入 然而要听ENDED事件中 我尝试遵循 YouTube 开发文档 现在 我似乎什
  • DB2 v9.5 类型 2 驱动程序的 JPA 2.0 Provider Hibernate 3.6 在配置准备中抛出异常

    JPA 2 0 Provider Hibernate 在为实体管理器工厂准备配置时抛出异常 我正在使用 DB2 v9 5 数据库和 DB2 v9 5 JDBC 类型 2 驱动程序 java sql SQLException IBM JDBC
  • Python 有同步吗?

    The 同步手册页 http linux die net man 2 sync says sync 导致对文件元数据和数据的所有缓冲修改 写入底层文件系统 Python 是否有调用来执行此操作 附 不是fsync http docs pyt
  • 在运行时更改 AR core 中对象的纹理

    我正在创建一个应用程序 我需要在其中更改 3d 对象的纹理 图案 我正在使用 AR Core SDK 和 android 我已经使用了下面的代码 但它不起作用 Texture builder setSource this R drawabl
  • Clojure 中的块注释

    如何在 Clojure 中注释多行 其实 还有办法 comment 定义嘿 嘿 对我进行检查
  • 使用 DT(DataTables 按钮扩展)导出表格时保持格式

    我制作了一个闪亮的应用程序 有人上传文件 计算一些比率 并且可以使用阈值滑块来格式化这些比率 我用DT formatStyle为此 它工作得非常好 据我了解这个函数 它创建一个回调来处理条件格式 然后 我想使用按钮扩展导出数据DT 我想在导