问题
Trying to use DT::datatable()
in R to export a table with multiline cells to pdf. DT::datatable()
works perfectly for multiline cells, but problems arise when trying to export to pdf. I’ve tried two different approaches, each with their own problems.
There are very many threads about keeping formatting when exporting to pdf, but none about exporting multiline cells.
Approach 1: The pdf print button of the Buttons
extension with the arguments escape = FALSE
and exportOptions = list(stripHtml = FALSE)
and customized JS()
functions.
The problem here is that the formatting is not preserved (in Rstudio it looks great until exporting to pdf). This solution (Keep formatting when exporting table with DT (DataTables buttons extension)) works perfectly to specifying certain formats for headers, colours, alignments etc (as I have tried in the customize
argument). However, what I’m trying to do is to keep HTML formatting in the values, namely multiline cells ("A</br>B</br>C"
). Does anyone know which JS()
function I need to pass to the customize
argument to have the </br>
be read and printed accordingly? Or is there another way to do this?
if (!require('DT')) install.packages('DT'); library(DT)
dt <- data.frame(Numbers = 1:100, Letter = paste0(c("A", "B", "C", "D", "E", "F"), collapse = "</br>"))
datatable(dt,
rownames = FALSE,
escape = FALSE,
extensions = c("Buttons"),
options = list(
dom = 'Blfrtip',
buttons = list(
list(extend = "pdf",
exportOptions = list(stripHtml = FALSE,
columns = ':visible'),
orientation = 'portrait',
customize = JS("function(doc){
doc.styles.tableHeader.color='yellow';
doc.defaultStyle.alignment = 'left';
doc.styles.tableHeader.alignment = 'left';
doc.pageMargins = [10,10,10,10];
doc.defaultStyle.fontSize = 7;
doc.styles.tableHeader.fontSize = 7;
doc.styles.title.fontSize = 9;
}"
)))))
Approach 2: Save the datatable
object to html
using saveWidget()
, then print the webpage using webshot()
. Here the format is preserved, but it just makes one very long pdf, making it useless if you want to print. I've tried to find a function which would split this pdf into A4 pages: webshot::resize()
, dev.print(onefile=F)
, staplr::split_pdf()
, and tabulizer::split_pdf()
, but could not get it working.
if (!require('webshot')) install.packages('webshot'); library(webshot)
if (!require('DT')) install.packages('DT'); library(DT)
df <- data.frame(No = 1:100, Letter = paste0(c("A", "B", "C", "D", "E", "F"), collapse = "</br>"))
dtable <- datatable(df,
rownames = T,
width = '100%',
height = '100%',
escape = FALSE,
options = list(
pageLength = 200,
dom = 't'
))
html <- "dtable.html"
saveWidget(dtable, html)
webshot(html, "dtable.pdf")
I feel like I'm making this harder than it should be. Am I missing something? Is there perhaps another method than the DT::datatable()
which can export multiline cells to pdf via R?
回答1:
The combination of knitr::kable
and wkhtmltopdf
does the trick: it ensures the formatting of multiline cells, produces multiple paged pdf's with table headers on every page.
if (!require('kableExtra')) install.packages('kableExtra'); library(kableExtra)
dt <- data.frame(Numbers = 1:100, Letter = paste0(c("A", "B", "C", "D", "E", "F"), collapse = "<br>"))
# make html file
kbl(dt, escape = FALSE) %>%
kable_paper() %>%
save_kable(file = "table1.html", self_contained = F)
# convert to pdf
system("wkhtmltopdf --enable-local-file-access table1.html file.pdf")
wkhtmltopdf
is a command run open source application, which you can download here: https://wkhtmltopdf.org/downloads.html
If you want to change the appearance of the table or pdf, see https://wkhtmltopdf.org/usage/wkhtmltopdf.txt and https://cran.r-project.org/web/packages/kableExtra/vignettes/awesome_table_in_html.html
来源:https://stackoverflow.com/questions/64452761/dtdatatable-export-to-pdf-while-preserving-html-br-for-multiline-cells