1. 程式人生 > >ajax結合symfony請求下載excel,資料流的誤區

ajax結合symfony請求下載excel,資料流的誤區

ajax請求下載excel

ajax請求下載excel,資料流的誤區

最近專案有個需求是根據條件進行下載excel,而且要無重新整理請求下載excel,本來想的很簡單,點選按鈕直接用post方式傳遞到後臺,後臺返回響應資料流生成excel完成下載,我這裡用的是谷歌和火狐瀏覽器,最後都可以下載,但是火狐瀏覽器的畫面中有些控制元件的樣式改變了,於是開始了兩天的掙扎。。。。。

前端是jquery,後臺是php的symfony框架

在這裡申明一下,不考慮畫面樣式的直接可以用form中的post方式實現
前臺程式碼

var form=$("<form>");//定義一個form表單
form.attr("style","display:none");
form.attr("target","");
form.attr("method","post");
form.attr("action","{{path('tquick_common_download_calls')}}");  
$("body").append(form);//將表單放置在web中
form.append(inputs);//定義的input資料
form.submit();//表單提交
form.remove()

後臺核心程式碼
‘$baseLogic->writeTempFile 是生成excel檔案並返回檔案路徑

  // ‘$baseLogic->writeTempFile 是生成excel檔案並返回檔案路徑
  $filePath = $baseLogic->writeTempFile($this->get('phpexcel'), $headInfoAndDatas);
  $response = new BinaryFileResponse($filePath);
  $response->headers->set('Content-Type', 'text/vnd.ms-excel; charset=utf-8');
  $response->setContentDisposition
( ResponseHeaderBag::DISPOSITION_ATTACHMENT, date("YmdHis") . $entity . '.xlsx' ); return $response;

這樣直接就可以完成下載了,不得不說symfony框架還是蠻方便的

谷歌瀏覽器正常下載,火狐瀏覽器的樣式變了,頁面還是重新整理

最後只能用ajax,一開始選擇用post方式直接,想通過獲取資料流進行轉換,最後發現根本實現不了,原因是返回來的資料全是亂碼,網上很多種方法說重新定義一個a標籤連結至資料流的地方,當我把前後臺的字符集除錯成一樣時能夠生成excel,但是無法開啟。

在這裡插入圖片描述
最後還是用了一個笨但是實用的方法
用ajax的post方式生成臨時檔案,然後用get方式下載臨時檔案
這樣總算搞定了

 $.ajax({
          cache: false,
          type: "POST",
          url: createExcelUrl,
          data: data,
          success: function(data, status, response){
           //建立一個a標籤                        
           var oReq = new XMLHttpRequest();
           oReq.open("GET", getExcelUrl, true);
           oReq.responseType = "blob";
           oReq.onload = function (oEvent) {
               var content = oReq.response;
               var elink = document.createElement('a');
               var fileName = oReq.getResponseHeader("Content-Disposition").split(";") [1].split("filename=")[1];//檔名
               ileName = fileName.substr(1,fileName.length-2);
               elink.download = fileName;
               elink.style.display = 'none';
               var blob = new Blob([content]);
                elink.href = URL.createObjectURL(blob);
                document.body.appendChild(elink);
                elink.click();
                document.body.removeChild(elink);
            };
            oReq.send(); 
            layer.closeAll("loading");
             },
             error: function(){
                   layer.closeAll("loading");
                   alert("下載失敗");
              }
       });

後臺
post生成臨時檔案的程式碼就不貼了,根據自己的業務來就行,主要是記錄檔案路徑


//get 方式直接下載
 if (file_exists($savePath)) {
            $response = new BinaryFileResponse($savePath);
            $response->headers->set('Content-Type', 'application/zip');
            $response->setContentDisposition(
            ResponseHeaderBag::DISPOSITION_ATTACHMENT, date("YmdHis") . $flag . ".zip");
            return $response;
   }
   return $this->rawResponse(ErrorMessage::FILE_NOT_EXISTS);

好了,結束。
[1]: http://meta.math.stackexchange.com/questions/5020/mathjax-basic-tutorial-and-quick-reference
[2]: https://mermaidjs.github.io/
[3]: https://mermaidjs.github.io/
[4]: http://adrai.github.io/flowchart.js/