javascript - 在 R Shiny App 中存储来自 Javascript 的变量

标签 javascript r shiny

现在我有一个不错的 R Shiny 应用程序,它能够使用一段 javascript 从其中的一部分创建一个 pdf。但是现在它只是自动下载。

js <- "
$(document).on('shiny:sessioninitialized', function(event) {
  $('#printPdf_CA').click(function () {
    domtoimage.toPng(document.getElementById('mainOrder_CA'))
      .then(function (blob) {
        var pdf = new jsPDF('l', 'pt', [$('#mainOrder_CA').width(), $('#mainOrder_CA').height()]);
        pdf.addImage(blob, 'PNG', 0, 0, $('#mainOrder_CA').width(), $('#mainOrder_CA').height());
        pdf.save($('#name').val() + '.pdf');
      });
  });
});
"
我希望能够将其存储在本地(作为相对目录中的文件或作为 Shiny 应用程序中的变量),然后让用户选择将其打印为 pdf(如上)或通过电子邮件发送到选择的地址(使用 R 中的 emayili 包)。我已经尝试过 Shiny.setInputValue(),但这根本不起作用(即使只是从 javascript 发送一个数字似乎也不起作用,但也许我在这里做错了什么。
我将衷心感谢您的帮助!
编辑
我让 Shiny.setinputValue() 工作,但不知道如何从现场将其写入临时 .pdf 文件。我还想知道这是否仍被官方认可为 pdf,或者在移至 R 时是否存在一些信息丢失
编辑 2:
基本上,我设法使用以下调整后的代码将 PDF 作为 Shiny 的输入发送到 R:
$(document).on('shiny:sessioninitialized', function(event) {
var pdf
  $('#storePDF').click(function () {
    domtoimage.toPng(document.getElementById('Capture'))
      .then(function (blob) {
        pdf = new jsPDF('l', 'pt', [$('#Capture').width(), $('#Capture').height()]);
        pdf.addImage(blob, 'PNG', 0, 0, $('#Capture').width(), $('#Capture').height());
        Shiny.setInputValue('pdf', pdf)
      });
  });
});
现在我只需要能够在 R 中创建一个 PDF。然而,在 R 中,生成的文件只是列表和各种组件的列表(可能以某种方式描述 PDF 的大型结构)。
将其打印到控制台会得到以下输出:
$internal
$internal$collections
$internal$collections$addImage_images
$internal$collections$addImage_images$`0`
$internal$collections$addImage_images$`0`$alias
[1] 1916164677

$internal$collections$addImage_images$`0`$w
[1] 1905

$internal$collections$addImage_images$`0`$h
[1] 880

$internal$collections$addImage_images$`0`$cs
[1] "DeviceRGB"

$internal$collections$addImage_images$`0`$bpc
[1] 8

..... And much more......

有没有办法把这种东西变成pdf?
编辑 3:
对于任何感兴趣的人,我的半体面解决方案是将“blob”移动到Shiny(Shiny.setInputValue)
比使用 base64decoder
使用 magick::image_read 读取图像
并使用 magick::image_write 写入 tempfile pdf

最佳答案

下次您从我的一篇文章中复制时,请提供链接,这会更容易。
您可以使用 base64 编码/解码进行如下操作:

library(shiny)
library(base64enc)

js <- "
$(document).ready(function(){
  $('#printPdf').click(function () {
    domtoimage.toPng(document.getElementById('frame_print'))
      .then(function (blob) {
        var pdf = new jsPDF('l', 'pt', [$('#frame_print').width(), $('#frame_print').height()]);
        pdf.addImage(blob, 'PNG', 0, 0, $('#frame_print').width(), $('#frame_print').height());
        pdf.save('test.pdf');
      });
  });
  $('#getPdf').click(function () {
    domtoimage.toPng(document.getElementById('frame_get'))
      .then(function (blob) {
        var pdf = new jsPDF('l', 'pt', [$('#frame_get').width(), $('#frame_get').height()]);
        pdf.addImage(blob, 'PNG', 0, 0, $('#frame_get').width(), $('#frame_get').height());
        var b64 = pdf.output('datauristring');
        Shiny.setInputValue('b64pdf', b64);
      });
  });
});
"

ui <- fluidPage(
  tags$head(
    tags$script(src = "https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.5.3/jspdf.min.js"),
    tags$script(src = "https://cdnjs.cloudflare.com/ajax/libs/dom-to-image/2.6.0/dom-to-image.min.js"),
    tags$script(js)
  ),
  br(),
  actionButton("printPdf", "PRINT", class = "btn-primary"),
  div(
    id = "frame_print",
    style = "border: 2px solid black;",
    h3("Click on the button to print me as PDF")
  ),
  br(),
  actionButton("getPdf", "GET", class = "btn-info"),
  div(
    id = "frame_get",
    style = "border: 2px solid red;",
    h3("Click on the button to get me as PDF")
  ),
  br(),
  conditionalPanel(
    "input.b64pdf !== undefined",
    downloadButton("dwnld")
  )
)

server <- function(input, output, session){
  
  observeEvent(input[["getPdf"]], {
    showNotification(
      "PDF base64 string stored in `input$b64pdf`.",
      type = "message"
    )
  })
  
  output[["dwnld"]] <- downloadHandler(
    filename = "Test.pdf",
    content = function(file){
      mybase64 <- input[["b64pdf"]]
      conn <- file(file, open = "wb")
      base64decode(substr(mybase64, 51L, nchar(mybase64)), output = conn)
      close(conn)
    }
  )
  
}

shinyApp(ui, server)

关于javascript - 在 R Shiny App 中存储来自 Javascript 的变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70588969/

相关文章:

javascript - 从列表中删除空值并使用 jquery 中的复选框创建空值

javascript - 当项目在网络上时,TinyMCE 不应用字体大小和文本颜色

r - 在 R 中从 [包] 导入 [函数]

css - 如何更改某些 textOutput 元素的字体?

javascript - 如何使用 jquery 和 select2 获取所选 optgroup 的值?

javascript - IndexedDB 在升级期间覆盖值

RStudio 和 R 有不同的 `~` (Home) 目录

r - ggplot2在geom_raster中结合连续变量和离散变量

r - 无法使用 Shiny 的 actionButton 和 eventReactive 方法在 flexdashboard 的 tabset 面板中获得预测图

Javascript逻辑运算符在R Shiny 中不起作用