Right now I have a nice R Shiny app that is able to create a pdf from parts of it using a piece of javascript. However right now it just automatically downloads.
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');
});
});
});
"
I want to be able to store it locally (either as a file in a relative directory OR as a variable in the Shiny app) and then give the user the choice to either print it to pdf(like above) OR send it over email to a chosen adress (using the emayili package from R). I allready tried Shiny.setInputValue(), but that did not work at all (even just sending a number from the javascript didn't seem to work, but maybe I am doing something wrong here.
I would really appreciate your help!
EDIT I made Shiny.setinputValue() work, but don't know how to write it to a temporary .pdf file from the field. I also wonder if this still is officially recognized as a pdf or if there was some information loss when moved to R
EDIT 2: Basically I manage to send the PDF to R as a shiny input with the following adjusted code:
$(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)
});
});
});
Now I would just need to be able to create a PDF in R from this. However in R the resulting file ist just a list of lists and various components (a large structure probably describing the PDF in some way).
Printing this to console gives the following output:
$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......
is there any way to turn this kind of thing into a pdf?
Edit 3:
My half decent solution for anyone interested was to just move the "blob" to Shiny (Shiny.setInputValue)
than use the base64decoder
read image using magick::image_read and write to tempfile pdf using magick::image_write
Next time you copy from one of my post, please give the link, this would have been easier.
You can proceed as follows, using base64 encoding/decoding:
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)