一、FileResult
1、簡介
表示一個用於將二進制文件內容發送到響應的基類。它有三個子類:
FileContentResult
FilePathResult
FileStreamResult
推薦閱讀:https://www.cnblogs.com/weiweixiang/p/5667355.html
2、FilePathResult
首先、創建一個mvc5項目、然后添加一個FileTest控制器,添加以下方法
public ActionResult Export() { // Response.ContentType指定文件類型 可以為application/ms-excel || application/ms-word || application/ms-txt || application/ms-html return File(Server.MapPath("/UserData/test.docx"), "application/ms-word", "test.docx"); }
<p> <a href='/filetest/export' download>下載</a> </p>
使用非常方便,這樣即可實現下載
3、FileContentResult
public ActionResult Getbg() { string bgimg = AppDomain.CurrentDomain.BaseDirectory + "/UserData/bg.jpg"; Image img = Image.FromFile(bgimg); byte[] bytes = ImageToBytes(img); return File(bytes, "image/jpeg"); }
<img src="/filetest/Getbg" width="300" alt="" />
使用非常方便,這樣即可實現圖片的顯示,在臨時描繪圖片並展示的場景中非常實用。
4、FileStreamResult
public ActionResult ExportDoc() { var path = Server.MapPath("/UserData/test.docx"); var fileName = HttpUtility.UrlEncode("test.docx", Encoding.GetEncoding("UTF-8")); return File(new FileStream(path, FileMode.Open), "application/ms-word", fileName); }
<a href='/filetest/exportdoc' download>使用FileStreamResult下載Doc</a>
二、JS請求二進制流文件
在第一部分已經介紹了直接通過url去實現,為什么還需要使用js?
我遇到的場景:在js加載相關數據后,根據相關參數去臨時生成圖片進行展示、下載、打印。
1、圖片顯示
<p> <button onclick="showBg()">JS顯示圖片</button> <div id="divImg"> </div> </p> <script type="text/javascript"> //window.location.href = "Export"; var showBg = function () { var xmlhttp = new XMLHttpRequest(); xmlhttp.open("GET", "/filetest/Getbg", true); xmlhttp.responseType = "blob"; xmlhttp.setRequestHeader("client_type", "DESKTOP_WEB"); xmlhttp.onload = function () { if (this.status === 200) { var blob = this.response; var img = document.createElement("img"); img.onload = function (e) { window.URL.revokeObjectURL(img.src); }; img.src = window.URL.createObjectURL(blob); img.width = 500; $("#divImg").html(img); } }; xmlhttp.send(); }; </script>
jquery並不支持流文件,
js重要實現來自於情郎的博文:ajax 請求二進制流 圖片 文件 XMLHttpRequest 請求並處理二進制流數據 之最佳實踐
2、下載
html代碼
<p> <button onclick="downImg()">手動下載</button> <div id="divDown"> </div> </p>
js代碼
var downImg = function () { var xmlhttp = new XMLHttpRequest(); xmlhttp.open("GET", "/filetest/Getbg", true); xmlhttp.responseType = "blob"; xmlhttp.setRequestHeader("client_type", "DESKTOP_WEB"); xmlhttp.onload = function () { if (this.status === 200) { var blob = this.response; downloadFile("停車券二維碼.jpg", blob); } }; xmlhttp.send(); }; function downloadFile(fileName, content) { if (window.navigator.msSaveOrOpenBlob) { navigator.msSaveBlob(content, fileName); } else { var aLink = document.createElement('a'); var blob = new Blob([content], { type: 'image/png' }); var evt = document.createEvent("HTMLEvents"); evt.initEvent("click", false, false);//initEvent 不加后兩個參數在FF下會報錯, 感謝 Barret Lee 的反饋 aLink.download = fileName; aLink.href = URL.createObjectURL(blob); aLink.dispatchEvent(evt); aLink.id = "alink"; aLink.click(); } }
實際場景:href是動態的,通過js先獲取數據后再賦值的
<a href="" id="qrcodeDownload" onclick="downImg(this); return false"> 下載二維碼 </a>
3、打印
html代碼
<p> <img src='xxxx.jpg' id='qrimg' > <button onclick="doPrint()">手動打印</button> </p>
js代碼
function PrintPart() { var eleHtml = $("#qrimg").prop("outerHTML"); eleHtml = eleHtml.replace('width="200"','width="300"'); //console.log($("#qrimg").prop("outerHTML")); var ifr = document.createElement("iframe"); ifr.setAttribute('style', 'position:absolute;width:0px;height:0px;left:-500px;top:-500px;'); document.body.appendChild(ifr); ifr.style.pixelWidth = 1; ifr.style.pixelHeight = 1; var ifrdoc = ifr.contentWindow.document; ifrdoc.open(); ifrdoc.write("<BODY>"); ifrdoc.write(eleHtml); ifrdoc.write("</BODY>"); ifrdoc.close(); setTimeout(function () { ifr.contentWindow.focus(); ifr.contentWindow.print(); document.body.removeChild(ifr); }, 500); } </script>
這里稍微解釋下:
獲取到圖片后,然后修改了圖片的顯示寬度;
創建一個絕對定位的iframe,使得不顯示在頁面的可見區域;
焦點定位到iframe並打印出來;
知識點:
Content-Disposition
http://www.jb51.net/article/30565.htm
header中Content-Disposition的作用與使用方法:
當代碼里面使用Content-Disposition來確保瀏覽器彈出下載對話框的時候。 response.addHeader("Content-Disposition","attachment");一定要確保沒有做過關於禁止瀏覽器緩存的操作。如下:
response.setHeader("Pragma", "No-cache"); response.setHeader("Cache-Control", "No-cache"); response.setDateHeader("Expires", 0);
http://blog.csdn.net/iamiwangbo/article/details/52911716
XMLHttpRequest
使用blob實現文件的下載和上傳
本文源碼下載:https://gitee.com/zmsofts/XinCunShanNianDaiMa/blob/master/ActionResultOfMvc5Study.rar
參考:
https://msdn.microsoft.com/zh-cn/library/system.web.mvc.fileresult.aspx
http://www.cnblogs.com/bmib/p/3518486.html
http://www.runoob.com/ajax/ajax-intro.html ajax學習
https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest
http://www.ruanyifeng.com/blog/2012/09/xmlhttprequest_level_2.html 講解XMLHttpRequest 1 和2 的區別
http://www.cnblogs.com/cdemo/p/5225848.html
https://www.cnblogs.com/weiweixiang/p/5667355.html
https://www.cnblogs.com/xielong/p/5940535.html