如何调用shinyjs代码仅打印第一页

问题描述 投票:0回答:1

这里RShiny打印当前页面展示了如何用js代码打印当前页面:

我想控制打印的页数。我只想打印第一页。通常我这样做:

但我想用代码来做到这一点。这是一个例子:

library(shiny)
library(shinyjs)

jsCode <- 'shinyjs.winprint = function() { window.print(); }'

ui <- fluidPage(
  useShinyjs(),
  
  tags$style(HTML("
  @media print {
    @page {
      size: A4 landscape; 
      margin: 10mm; 
    }
    body * {
      visibility: hidden;
    }
    #printArea, #printArea * {
      visibility: visible;
    }
    #printArea {
      position: absolute;
      left: 0;
      top: 0;
      width: 100%;
      transform: scale(0.90); 
    }
  }
")),

extendShinyjs(text = jsCode, functions = c("winprint")),

actionButton("print", "PRINT"),

div(id = "printArea",  # start area to print

    tableOutput("table"),
    tableOutput("table1")
) # End of area to print
)

server <- function(input, output, session) {
  
  output$table <- renderTable({
    iris
  })
  
  output$table1 <- renderTable({
    mtcars
  })
  
  observeEvent(input$print, {
    shinyjs::runjs('shinyjs.winprint()')
  })
}

shinyApp(ui, server)

我想要的输出是这样的:

进一步说明:

通常,打印为 PDF 时,有一个选项菜单可让您选择页面大小、方向(例如纵向或横向)和其他格式首选项。这些选项包括打印特定页面的功能,方法是选择“打印”,然后选择“页面”,最后选择“自定义”来指定范围(例如 1:10),或者手动输入单个页码(例如 1)。现在,我的目标是以编程方式复制此功能。通过利用 @media print { @page { ... } CSS 指令,我们可以以编程方式调整其中一些设置。

所以我想知道这是否可能。仅供参考,第一次旅程从这里开始无法从带有背景图像的闪亮应用程序中截取屏幕截图以将其用作报告,原因是我的应用程序只有一个网站,其中包含一些按钮、信息等。在底部/脚注,我不想打印。相信我,我尝试了所有可能的软件包,如

shinyscreenshot
capture
及其衍生物,但 @Stéphane Laurent 的解决方案是唯一适合我的情况。但每个 pdf 的大小为 7 MB。现在,通过上面所示的方法,我可以将大小减少到 200 KB。一切正常,除非有一个小问题,即两个站点打印一个需要,一个空白。 :-)

javascript r json shiny shinyjs
1个回答
0
投票

要在 Shiny 应用程序中以编程方式实现仅打印第一页,您可以使用 JavaScript 来设置打印范围。在你的jsCode中,你可以添加一个函数来指定打印的页面范围。以下是如何修改代码以仅打印第一页:

library(shiny)
library(shinyjs)

jsCode <- '
shinyjs.winprint = function() { 
  window.print(); 
}

shinyjs.setPrintRange = function(page) {
  var style = document.createElement("style");
  style.innerHTML = "@media print { @page { size: A4 landscape; margin: 10mm; } body * { visibility: hidden; } #printArea, #printArea * { visibility: visible; } #printArea { position: absolute; left: 0; top: 0; width: 100%; transform: scale(0.90); } @page :first { size: A4 portrait; margin: 10mm; } @page :not(:first) { display: none; } }";
  document.head.appendChild(style);
}
'

ui <- fluidPage(
  useShinyjs(),
  
  extendShinyjs(text = jsCode, functions = c("winprint", "setPrintRange")),
  
  actionButton("print", "PRINT"),
  
  div(id = "printArea",  # start area to print
      tableOutput("table"),
      tableOutput("table1")
  ) # End of area to print
)

server <- function(input, output, session) {
  
  output$table <- renderTable({
    iris
  })
  
  output$table1 <- renderTable({
    mtcars
  })
  
  observeEvent(input$print, {
    shinyjs::runjs('shinyjs.setPrintRange(1); shinyjs.winprint();')
  })
}

shinyApp(ui, server)

在此修改后的代码中,我添加了一个新的 JavaScript 函数 setPrintRange(page),该函数将 CSS 动态注入到页面中。此 CSS 指定仅显示第一页进行打印。然后,在打印按钮的observeEvent 中,我在使用winprint() 启动打印过程之前调用此函数。这应该确保只打印第一页。

© www.soinside.com 2019 - 2024. All rights reserved.