现在我有一个不错的 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/