下載json、csv、excel、img等文件,而不是直接在瀏覽器打開,在后台管理系統中很常見。那么都有哪些方式可以實現呢?
方式一:鏈接,參數不多
1. a標簽,直接實現
// href 放下載地址; // download 為空,默認是下載地址上的文件名稱,可以指定名稱,如tp.csv,加download是避免json、img等文件直接在瀏覽器打開而不是下載; // target="_black"在新頁面打開,避免當前頁閃屏 <a href="" download="" target="_black">點擊下載</a> // 如需帶參,直接在地址后加上url的search參數就可以,注意參數不要太多 <a class="download link-text" href="/newCrowd/crowdList/downFile?&is_tag=1&fileId=1023" target="_blank">點擊下載</a>
2. window.open,location.href,借助js,點擊按鈕,調用方法實現
function downloadFile(url){ window.open(url); } function downloadFile(url){ location.href=url; }
方式二:iframe
// js function downloadFile(url){ var iframe = document.createElement("iframe"); document.body.appendChild(iframe); iframe.src =url; } // jq function downloadFile(url){ $("body").append($("<iframe/>").attr("src",url); }
方式三:form表單,參數較多
1. form表單,不帶參
function downloadFile (){ var url = ""; var form = $("<form></form>").attr({ action : url, method : "post" }); form.appendTo($("body")).submit(); form.remove(); }
2. form表單,帶參,jq
function downloadFile (data, url) { // data格式 // obj {key: val} // obj {key: [val]} // obj {key: {key1: val}} var dataHtml=''; for(var i in data){ var item=data[i]; var type=typeof item; switch(type){ case 'object': if($.isArray(item)){ for(var k=0,klen=item.length; k<klen; k++){ dataHtml+=createInput(i+'[]',item[k]); // name=key[] value=val } }else{ for(var k in item){ dataHtml+=createInput(i+'['+k+']',item[k]) // name=key[key1] value=val } } break; default: dataHtml+=createInput(i,item); } } var exportForm=$("#export_form"); if(!exportForm.length){ $('body').append('<form id="export_form" enctype="multipart/form-data" method="post" target="_blank" action="'+url+'">'+dataHtml+'</form>'); }else{ exportForm.html(dataHtml); } $("#export_form").submit(); $('#export_form').remove(); function createInput(name,data){ return '<input name="'+name+'" type="hidden" value="'+data+'">' } }
3. form 表單,帶參,vue,element-ui
// 組件 download.vue <template> <div class="download"> <form :action="downloadUrl" method="post" target="_blank" style="display: none"> <template v-for="(value, key) in pageParams"> <!-- 值為數組或對象 --> <template v-if="typeof value === 'object'"> <input type="hidden" v-if="value.length" v-for="item in value" :name="key+'[]'" :value="item"> <input type="hidden" v-else v-for="(childValue, childKey) in value" :name="key+'['+childKey+']'" :value="childValue"> </template> <!-- 值為字符串或數字 --> <input v-else type="hidden" :name="key" :value="value"> </template> <button type="submit" ref="btnDownload"></button> </form> </div> </template> <script> export default { props: { pageParams: { type: Object, default () { return {} } }, downloadUrl: { type: String, required: true, default: '' } }, methods: { downLoad() { this.$refs.btnDownload.click(); } } } </script>
// 調用 <template> <el-button @click="$refs.download.downLoad()" type="primary" size="small">下載</el-button> <download :pageParams="params" :downloadUrl="api.downloadUrl" ref="download"></download> </template> <script> import download from 'components/download/download'; export default { data() { return { api: { downloadUrl: `${this.urlBase}/adunit/download` }, params: {} } }, components: {download} } </script>
方式四:前端組織內容,csv方式下載
參考:https://blog.csdn.net/oscar999/article/details/16342699
前面三種方式都是通過前端請求后端接口實現下載,但有時需要前端直接組織內容下載。
<a href="" download="文件.csv" id="btn">下載</a> <a href="" download="中文文件.csv" id="btn_chinese">下載中文</a>
var dataStr = "col1,col2,col3\nhello,world,english"; var dataChineseStr = "姓名,年齡!\n張三,34\n王五,32\n李四,25"; console.log() // chrome if (navigator.appName == "Netscape") { var blob = new Blob([dataStr], {type: "text/csv,charset=utf-8"}); document.getElementById("btn").href = window.URL.createObjectURL(blob); var blobChinese = new Blob(['\ufeff'+dataChineseStr], {type: "text/csv,charset=utf-8"}); document.getElementById("btn_chinese").href = window.URL.createObjectURL(blobChinese); } else { document.getElementById("btn").href = "data:text/csv;charset=utf-8," + encodeURIComponent(dataStr); document.getElementById("btn_chinese").href = "data:text/csv;charset=utf-8,\ufeff" + encodeURIComponent(dataStr); }