JS前端创立CSV或Excel文件并浏览器导出下载,Chrome中应用HTML5贯彻所有文件

了解HTML/HTML5中的download属性

2016/04/07 · HTML5 · 5
评论 ·
download

原文出处:
张鑫旭(@张鑫旭)   

一、download属性是个如何鬼?

JS前端创立CSV或Excel文件并浏览器导出下载,Chrome中应用HTML5贯彻所有文件。首先看下边那种截图:
美高梅开户网址 1

假如大家想已毕点击上边的下载按钮下载一张图纸,你会怎么样贯彻?

俺们兴许会想到一个最简单易行的不二法门,就是一贯按钮a标签链接一张图片,类似上边这样:

<a href=”large.jpg”>下载</a>

1
<a href="large.jpg">下载</a>

然则,想法虽好,实际效果却不是大家想要的,因为浏览器可以一向浏览图片,由此,咱们点击上面的“下载”链接,并是不下载图片,而是在新窗口直接浏览图片。

下载

看本身的双眼,美高梅开户网址 2

于是,基本上,如今的贯彻都是轻重倒置HTML策略,而是接纳,例如php那样的后端语言,通过报告浏览器header美高梅开户网址 ,信息,来促成下载。

header(‘Content-type: image/jpeg’); header(“Content-Disposition:
attachment; filename=’download.jpg'”);

1
2
header(‘Content-type: image/jpeg’);
header("Content-Disposition: attachment; filename=’download.jpg’");

唯独,那种光景端都要顾虑的形式神烦,现在都流行前后端分离,还搅在联名太累了,感觉不会再爱了。

那有没有哪些只要求前端动下手指就能促成下载的法门吗?有,就是本文要介绍的download属性。

诸如,大家期待点击“下载”链接下载图片而不是浏览,间接增加一个download特性就足以:

<a href=”large.jpg” download>下载</a>

1
<a href="large.jpg" download>下载</a>

科学,你没有看错,就那样停止了,不妨点击前边的链接试试:下载

结果在Chrome浏览器下(Fire福克斯浏览器因为跨域限制无效):
美高梅开户网址 3

不仅如此,大家还足以指定下载图片的文件名:

<a href=”index_logo.gif” download=”_5332_.gif”>下载</a>

1
<a href="index_logo.gif" download="_5332_.gif">下载</a>

假诺后缀名一样,我们还足以缺省,直接文件名:

<a href=”index_logo.gif” download=”_5332_”>下载</a>

1
<a href="index_logo.gif" download="_5332_">下载</a>

截图为虚,操作为实:下载

Chrome下的截图效果示意:
美高梅开户网址 4

一个大写的酷里!

【Data URL】

未雨绸缪工作

想要将canvas元素当前显示的始末生成为图像文件,我们率先要博取canvas中的数据,在HTML5
<canvas>要素的规范中提供了toDataURL()的章程可以将canvas中的内容生成为指定格式的DataURL,使用方法如下:

// 假设有一个id为cvs的canvas元素
var dataurl = document.getElementById('cvs').toDataURL('image/png');

咱俩今天亟待将DataURL生成为一个png类型的图像文件,并且那一个操作是在该地达成的,不须求服务器帮忙生成文书。以下提供两种艺术:

长期以来,在做文件下载功用的时候都是前者通过ajax把须要转变的文件的内容参数传递给后端,后端通过Java语言将文件生成在服务器,然后回到一个文本下载的总是地址url。前端通过location.href
= url或者window.open(url),完成文件的下载。

前端如同在那一个进度中绝非爆发什么较大的法力,无非是殡葬请求和开拓页面的机能。此前就在搜索那样的文件下载形式,前几日终于在工作要求的压力下找到了对应的缓解方案。

二、浏览器包容性和跨域策略

美高梅开户网址 5

可是,caniuse体现的包容性只是个笼统,按照鄙人的耳闻目睹测试,事情要比见到的扑朔迷离。

紧要表现在跨域策略的拍卖上,由于自身手上没有IE13,所以,只好相比Chrome浏览器和FireFox浏览器:

比方急需下载的资源是跨域的,包罗跨子域,在Chrome浏览器下,使用download质量是足以下载的,然则,并不可能重置下载的文件的命名;而FireFox浏览器下,则download特性是不著见效的,也就是Fire福克斯浏览器无论如何都不辅助跨域资源的download属性下载。

而,假使资源是同域名的,则多个浏览器都是畅通无阻的下载,不会冒出下载变浏览的场地。
美高梅开户网址 6

是或不是辅助download属性的监测
要监测当前浏览器是还是不是帮衬download特性,一行JS代码就可以了,如下:

var isSupportDownload = ‘download’ in document.createElement(‘a’);

1
var isSupportDownload = ‘download’ in document.createElement(‘a’);

风行的HTML5浏览器中,已经协助用Data URL(RFC2397)来引用“外部”资源了。

方法一 利用HTML5 <a>标签的download属性

在HTML5规范中,<a>标签拥有一个新的习性download,download属性用来指明该超链接指向的靶子是相应被下载的文书,例如

<a href="http://www.jianshu.com" download>下载</a>

download属品质够被赋值,用来指明下载文件的称号,例如

<a href="http://www.jianshu.com" download="index.html">下载</a>

HTML与公事下载

若是期望在前端直接出发某些资源的下载,最方便急忙的艺术就是选拔HTML5原生的download属性,
例如:

<a href="large.jpg" download>下载</a>

但明明,若是纯粹利用HTML属性来落实公文的下载(而不是浏览器打开或浏览),对于动态内容,就不能。

诸如,大家对于页面进行分享的时候,希望享受图片是页面内容的实时截图,此时,那么些图片就是动态的,纯HTML显著无法满意大家的要求,借助JS和别的一些HTML5特征,例如,将页面元素转换来canvas上,然后在转成图片举办下载。

单只是做到图片的下载无法满意经常业务的必要,对于事情必要是遥远不够的。

三、结束语

而外图片资源,我们还足以是PDF资源,或者txt资源等等。更加Chrome等浏览器可以直接打开PDF文件,使得此文件格式必要download处理的景色更是宽广。

此HTML属性就算非常实用和便利,不过包容性制约了咱们的广大使用。

再就是考虑到很多时候,需求展开一些下载的总括,纯前端的方法想要保存下载量数据,仍旧有些吃紧,须要跟开发的同桌合作才行,还不如选拔传统方式。

所以,download属性的前途前景在何地?当下是还是不是足以一贯加入到实在项目?还索要大家一道可以想想。其实拔取JS完毕download特性的polyfill并不难,可是,考虑到为啥不拥有浏览器都选用polyfill的章程,又觉得为了技术而技术是不太妥当的。

简单来说,先放着心上,再观看观察。

1 赞 3 收藏 5
评论

美高梅开户网址 7

比如下边的链接,在HTML5浏览器中点击后,会转到一个新页面,显示“Hello Data
URL!”字样。

示例

现在,大家可以因此将DataURL赋值给a标签的href属性,并且利用download属性使其变化为可下载的图样。

var dataurl = document.getElementById('cvs').toDataURL('image/png');
var a = document.createElement('a');
a.href = dataurl;
a.download = "sample";
a.click();

依靠HTML5 Blob完结文件音讯文件下载

假使对Blob不明白,可以先看看张鑫旭的明亮DOMString、Document、FormData、Blob、File、ArrayBuffer数据类型一文。

规律其实很粗略,大家得以将文件或者JS字符串借助Blob转换成二进制,然后,作为a元素的href属性,合营download属性,落成下载。

代码也相比较简单,如下示例(包容Chrome和FireFox):

var funDownload = function(content, filename){
    // 创建隐藏的可下载链接
    var eleLink = document.createElement('a');
    eleLink.download = filename;
    eleLink.style.display = 'none';
    // 字符内容转变成blob地址
    var blob = new Blob([content]);
    eleLink.href = URL.createObjectURL(blob);
    // 触发点击
    document.body.appendChild(eleLink);
    eleLink.click();
    // 然后移除
    document.body.removeChild(eleLink);
};

中间,content指需求下载的文件或者字符串内容,filename指下载到系统中的文件名称。

[html] 
<a href=”data:text/plain,Hello Data URL!”>Hello</a> 
万一文本内容包罗特殊字符咋办?Data
URL也是一种URL,也可以选用通用的URL转义编码:

兼容性

如今唯有Chrome和FireFox帮忙download属性

借助Base64达成任一文件下载

对于非文本文件,也是足以一贯JS触发下载的,例如,若是大家想下载一张图纸,能够把这张图片转换成Base64格式,然后下载。

代码示例:

var funDownload = function(domImg, filename){
    // 创建隐藏的可下载链接
    var eleLink = document.createElement('a');
    eleLink.download = filename;
    eleLink.style.display = 'none';
    // 图片base64地址
    var canvas = document.createElement('canvas');
    var context = canvas.getContext('2d');
    var width = domImg.natureWidth;
    var height = domImg.natureHeight;
    context.drawImage(domImg, 0, 0);
    // 如果是PNG图片,则context.toDataURL('image/png');
    eleLink.href = context.toDataURL('image/jpeg');
    // 触发点击
    document.body.appendChild(eleLink);
    eleLink.click();
    // 移除
    document.body.removeChild(eleLink);
};

频频是.html文件,.txt,.json等只要内容是文本的公文,都足以接纳那种小技巧已毕下载。

在Chrome浏览器下,模拟点击创制的a元素及时不append到页面中,也是足以触发下载的,可是在FireFox浏览器中却极度,因而,上边的funcDownload()方法有一个appendChild和removeChild的拍卖,就是为着兼容FireFox浏览器。

[html] 
<a
href=”data:text/html;charset=utf8,%3Ch1%3E%E4%BD%A0%E5%A5%BD%3C/h1%3E”>URL
escaped</a> 
上边的例子都是纯文本数据。其实Data
URL也足以代表二进制数据,用Base64编码即可(当然URL转义也能落到实处)。
下边是一个表示GIF图片的Data URL(引用自RFC2397):

方法二 修改DataURL的Mime-type

比方大家一直将赢得的DataURL赋值给a标签的href属性,在点击链接后浏览器只会在新窗口打开图片,并不会一直实施下载。大家可以修改DataURL的Mime-type为octet-stream,强制让浏览器下载。

延续说完成在下CSV文件的法子

我们经过ajax从后端请求到的数码貌似都是json格式,也就是说必要把json数据转成csv格式的数额,经过查找终于找到了一个相比较好用的json转csv的工具。

平素上演示代码:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>Download</title>
    <link rel="stylesheet" href="">
</head>
<body>
    <div class="demo">
        <p><input type="button" value="作为test.html文件下载"></p>
    </div>
    <script src="json2csv.js" type="text/javascript" charset="utf-8"></script>
    <script type="text/javascript" charset="utf-8">
        // 示例数据
        var fields = ['car', 'price', 'color'];
        var myCars = [
          {
            "car": "Audi",
            "price": 40000,
            "color": "blue"
          }, {
            "car": "BMW",
            "price": 35000,
            "color": "black"
          }, {
            "car": "Porsche",
            "price": 60000,
            "color": "green"
          }
        ];
        // json数据转csv格式
        var csv = json2csv({ data: myCars, fields: fields });

        var eleButton = document.querySelector('input[type="button"]');

        // 下载文件方法
        var funDownload = function (content, filename) {
            var eleLink = document.createElement('a');
            eleLink.download = filename;
            eleLink.style.display = 'none';
            // 字符内容转变成blob地址
            var blob = new Blob([content]);
            eleLink.href = URL.createObjectURL(blob);
            // 触发点击
            document.body.appendChild(eleLink);
            eleLink.click();
            // 然后移除
            document.body.removeChild(eleLink);
        };

        if ('download' in document.createElement('a')) {
            // 作为test.html文件下载
            eleButton.addEventListener('click', function () {
                funDownload(csv, 'test.csv');    
            });
        } else {
            eleButton.onclick = function () {
                alert('浏览器不支持');    
            };
        }
    </script>
</body>
</html>

其间的json2csv.js文本能够在那里下载,或者赢得源码。

[html] 
<a
href=”data:image/gif;base64,R0lGODdhMAAwAPAAAAAAAP///ywAAAAAMAAwAAAC8IyPqcvt3wCcDkiLc7C0qwyGHhSWpjQu5yqmCYsapyuvUUlvONmOZtfzgFzByTB10QgxOR0TqBQejhRNzOfkVJ+5YiUqrXF5Y5lKh/DeuNcP5yLWGsEbtLiOSpa/TPg7JpJHxyendzWTBfX0cxOnKPjgBzi4diinWGdkF8kjdfnycQZXZeYGejmJlZeGl9i2icVqaNVailT6F5iJ90m6mvuTS4OK05M0vDk0Q4XUtwvKOzrcd3iq9uisF81M1OIcR7lEewwcLp7tuNNkM3uNna3F2JQFo97Vriy/Xl4/f1cf5VWzXyym7PHhhx4dbgYKAAA7″>Larry</a> 
也不是兼备的二进制文件格式都不可能不编码,当实际数据不包罗特殊字符的时候,不编码也是足以的:

示例

var dataurl = document.getElementById('cvs').toDataURL('image/png').replace("image/png", "image/octet-stream");
var tmpa = document.createElement('a');
a.href = dataurl;
a.target = "_blank";
a.click();
情节参考来源

1.下载效能主要参考张鑫旭的博客中的一片文章:小tip:JS前端创立html或json文件并浏览器导出下载;

2.json2cav的代码参考来源为:;

美高梅开户网址 8

[html] 
<a
href=”data:application/octet-stream,12345″>octet-stream</a> 
地方的链接都得以点右键“另存为”本地磁盘文件,这一个历程似乎平常下载远程文件的操作一样。
那样的话,理论上大家得以将此外数据转载为一个Data
URL链接,以便让用户“下载”。

兼容性

这一个主意对于大多数主流浏览器都可用,不过octet-stream并不含有文件名和扩充名的音讯,所以采用这么些形式下载下来的文件是没有扩充名的文件,浏览器可能默许的命名为“下载”或者“unknown”

【自动下载和默许文件名】
地方已经落到实处了变动文书数量并保存到地点的功用,不过还有不足:

对于浏览器可以展现的MIME类型,点击链接的话会直接在浏览器中浮现,比如纯文本、HTML以及图片等档次。

若手动将链接另存,Chrome
22普通话版弹出的保存框默许主文件名永远为“下载”,Firefox
16则是一串莫名其妙并以.part结尾的字符串做默许名。

对此浏览器不可能突显的MIME类型,Chrome 22和Firefox
16都会自动调用下载功效。然而Chrome中文版下载的默许主文件名如故总为“下载”,Firefox
16则仍旧无缘无故的字符串。

而是,Chrome
22中早已对<a>元素伸张了一个新的价签属性“download”来缓解那些难点。

[html] 
<a href=”data:text/plain,Hello Data URL!”
download=”hello.txt”>hello</a> 
<a
href=”data:text/html;charset=utf8,%3Ch1%3E%E4%BD%A0%E5%A5%BD%3C/h1%3E”
download=”URL escaped.html”>URL escaped</a> 
<a
href=”data:image/gif;base64,R0lGODdhMAAwAPAAAAAAAP///ywAAAAAMAAwAAAC8IyPqcvt3wCcDkiLc7C0qwyGHhSWpjQu5yqmCYsapyuvUUlvONmOZtfzgFzByTB10QgxOR0TqBQejhRNzOfkVJ+5YiUqrXF5Y5lKh/DeuNcP5yLWGsEbtLiOSpa/TPg7JpJHxyendzWTBfX0cxOnKPjgBzi4diinWGdkF8kjdfnycQZXZeYGejmJlZeGl9i2icVqaNVailT6F5iJ90m6mvuTS4OK05M0vDk0Q4XUtwvKOzrcd3iq9uisF81M1OIcR7lEewwcLp7tuNNkM3uNna3F2JQFo97Vriy/Xl4/f1cf5VWzXyym7PHhhx4dbgYKAAA7″
download=”Larry.gif”>Larry</a> 
<a href=”data:application/octet-stream,12345″
download=”octet-stream.bin”>octet-stream</a> 
对于指定了download标签属性的链接,点击后,Chrome
总是会实施下载操作,并且下载保存的默许文件名即为download的属性值。
不满的是Firefox 16还不援救那样的品质。

其它,Chrome下载默许不提示文件保留地点和称号。若希望每回都提示,可在Chrome的设置中修改。

【附】

以往要在浏览器中贯彻如此一个另存为的机能,可以用IE的document.execCommand(‘SaveAs’)模拟,可是对复杂的数额格式就无奈处理了。

或者合作服务端程序可以处理复杂的数目,但处理进程也变复杂了,纯粹的地方利用还非得搭建一个附加的服务器。

再不怕运用HTA+FSO/ADO.Stream来扭转文书,但是各代Windows系统中没用统一完善的通用对话框控件来完成“另存为”对话框,要么单独登记,要么使用Office中的对话框组件,或者其余措施模拟落成,结果这些非主旨作用造成整个落成复杂了好多。

对此更扑朔迷离的多寡,Data URL可能不太够用,那时可以考虑功效更强硬的HTML5
File API,使用createObjectURL()方法可以博得比Data
URL更短的URL,那里不作具体讲述。

有关Chrome
22支撑的<a>的竹签属性download,我是从“zip.js”(一个开源的zip压缩解压JS库)的demo中发现的。已毕此属性最早的Chrome版本未知。

URL】 最新的HTML5浏览器中,已经支撑用Data
URL(RFC2397)来引用外部资源了。
比如上面的链接,在HTML5浏览器中点击后,会转到一个新…

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图