【问题标题】:Embed csv in html rmarkdown在 html rmarkdown 中嵌入 csv
【发布时间】:2017-05-02 23:36:45
【问题描述】:
  • 示例
  • 问题陈述
  • 解决方案搜索和
  • 问题

...参见 rmarkdown 示例代码。

通过修改 rmarkdown sn-p 来欣赏演示解决方案的答案。

---
title: "Reproducable Example"
author: "user2030503"
output: html_document
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```

## Example: mtcars

```{r}
write.csv2(mtcars, "./file.csv")

# Code to embed mtcars as csv
# Code to provide mechanism for button or link for later user interaction to open/save the csv. 
```

## Problem

* I want to embed the csv file into the html generated by this rmarkdown script.
* Embedding here means, that the csv data are integral part of the hmtl (i.e. for offline use).
* I want a mechanism (button or link) in the html, which allows the user to open/save the data the csv.

## Search for a solution

There are techniques for embedding rdata files.

* http://rmarkdown.rstudio.com/articles_rdata.html
* https://github.com/richarddmorey/BayesFactorExtras/blob/master/BayesFactorExtras/R/downloadURI.R

## Question

* Dispite of above approaches, I did not find a solution yet how to solve the problem.
* How can it be achieved demonstrating it via this reproducable example ?

【问题讨论】:

    标签: r csv r-markdown


    【解决方案1】:

    没有javascript;没有小部件;没有额外的 CSS; 4 LoC(如果您喜欢不可读的代码,可以使用 1 LoC):

    ```{r}
    write.csv2(mtcars, "./file.csv")
    
    library(magrittr)
    readLines("./file.csv") %>% 
      paste0(collapse="\n") %>% 
      openssl::base64_encode() -> encoded
    ```
    
    [Download CSV](`r sprintf('data:text/csv;base64,%s', encoded)`)
    

    相当简单:

    • 将文件视为“东西”并将其作为行读入
    • 全部由换行符分隔的文本组成
    • 将其编码为 base 64
    • 使用适当的媒体类型制作数据 URI
    • 将其嵌入为降价链接

    你也可以这样做:

    <a download="mtcars.csv" href="`r sprintf('data:text/csv;base64,%s', encoded)`">Straight HTML Download Link</a>
    

    如果您想为浏览器(以及用户)提供建议的文件名(适用于 Markdown 规则中的 HTML 位置)。

    注意:

    readBin("./file.csv", "raw", file.info("./file.csv")$size) %>% 
      openssl::base64_encode() -> encoded
    

    readLines() 版本同样有效。

    【讨论】:

    • 不幸的是,此解决方案在 IE 11 (Windows 8) 中不起作用。解决方案生成的链接不会触发任何内容。怎么解决?
    • 是的,使用真正的浏览器 ;-) 这似乎是 IE 11 脑死亡的已知问题:caniuse.com/#feat=datauri;这意味着你不能为 IE 11 嵌入这种类型的数据 URI。看起来 Edge 也脑死了。
    • 这个解决方案非常适合 Chrome,但在 Safari 中,不会启动下载,我们只会看到浏览器上显示的 csv。有解决办法吗?
    • 您可以尝试使用application/vnd.ms-excel 而不是text/csv,它应该能够在所有“支持”的平台上持续下载。
    • 这可能会有所帮助,但如果您使用降价方法进行嵌入,则会在 Chrome + Excel 中产生警告,指出下载的文件不是实际的 XLS。
    【解决方案2】:

    基于用户 hrbrmstr 的answer,我准备了一个方便的函数embed_data(),看看它的实际操作:

    ---
    title: "Untitled"
    author: "user2030503"
    date: "17 12 2016"
    output: html_document
    ---
    
    ```{r setup, include=FALSE}
    knitr::opts_chunk$set(echo = TRUE)
    ``` 
    
    ```{r echo=FALSE}
    
    embed_data= function(x= mtcars, filename= "file.csv", label= "Get data"){
    
      # Create encoded Base64 datastream 
      encode_data= function(x){
        write.csv2(x, "./file.csv")
        enc= sprintf('data:text/csv;base64,%s', openssl::base64_encode(paste0(readLines("./file.csv"), collapse="\n")) )
        unlink("./file.csv")
        return(enc)
      }
    
      # String result ready to be placed in rmarkdown
      paste0("<a download='", filename, "' href=", encode_data(x), ">", label, "</a>")
    
    }
    ```
    
    `r embed_data(mtcars, filename="mtcars.csv")` 
    

    【讨论】:

    • 如果我多次保存到相同的文件名,但使用新数据并不会从文件中完全删除旧数据。因此,如果新数据有 5 行,旧数据有 10 行,则旧数据的底部 5 行仍然存在。有没有办法替换整个文件?
    【解决方案3】:

    这样的事情怎么样:

    ---
    title: "Reproducable Example"
    author: "dimitris_ps "
    date: "17 December 2016"
    output: html_document
    ---
    
    <style>
      #DataTables_Table_0 {
         visibility: hidden;
      }
    
      #DataTables_Table_0_paginate {
        visibility: hidden;
      }
    
    </style>
    
    ```{r setup, include=FALSE}
    knitr::opts_chunk$set(echo = TRUE)
    library(DT)
    
    dt <-   datatable(mtcars, rownames=T, 
                # filter = 'top',
                  callback=JS('$("a.buttons-collection").css("background","#008CBA");
               $("a.buttons-collection").css("font-size","15px");
               $("a.buttons-collection").css("border-radius", "8px");
               $("a.buttons-collection").css("margin-right","0px");
               return table;'),
            extensions = 'Buttons',
            options = list(searching=F,
                           paging = T,
                           bInfo = F,
                           columnDefs = list(list(className = 'dt-left',  targets = 0),
                                             list(className = 'dt-center',  targets = 1:11)),
                           pageLength = 1,
                           initComplete = JS("function(settings, json) {",
                                             "$(this.api().table().header()).css({'background-color': '#99ccff', 'color': '#003333'});",
                                             "}"),
                           dom = 'Bfrtip',
                           buttons = list(
                                          list(extend = 'collection',
                                               buttons = c('excel', 'csv'),
                                               text = 'DOWNLOAD DATA')
                           )
            )
      )
    
    ```
    <br>
    
    ```{r mtcars, echo=FALSE}
    dt
    ```
    

    您需要安装 DT

    【讨论】:

    • 感谢您的努力。两个问题: 1. 一个小问题:两个JS函数都需要一个DT::前缀。 2.是一个更大的:我不想显示一个表。你能重构只剩下按钮吗?
    • 在第 1 点上,加载 library(DT),这是我最初拥有的。感谢您指出。在您的观点上,css 隐藏表可能有一种解决方法。我稍后会回到这个问题
    • 我已经更新了我的答案。不是最好的方法,但接近你正在寻找的。基本上,我用css 隐藏DataTable
    • 很好,最后我正在寻找什么,谢谢你的帮助。由于您的解决方案的开销较高,我选择了用户 hrbrmstr 的答案。希望你能理解。您的解决方案的优势在于它还提供 Excel 导出功能。
    • 当然没有问题,这是有道理的,它更直接
    猜你喜欢
    • 2015-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-14
    • 1970-01-01
    • 2020-08-02
    • 2016-05-29
    相关资源
    最近更新 更多