第六章 MVC之 FileResult和JS請求二進制流文件


一、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

C# byte數組與Image的相互轉換

https://www.cnblogs.com/xielong/p/5940535.html

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM