post請求上傳與下載excel文件、處理報錯

需求:上傳excel表格到服務器,然後接收返回的結果(二進制)並轉成excel表格下載

實施:採用 Element-UI的uploade 組件,功能較全且有完整的生命週期鉤子可設置。

 	<el-upload
        class="upload-demo"
        ref="upload"
        action=""
        :on-remove="handleRemove"
        :on-error="handleError"
        :file-list="fileList"
        :auto-upload="false"
        :limit=1
      >
        <el-button
          slot="trigger"
          size="small"
          type="primary"
        >選取文件</el-button>
      </el-upload>

問題1:post請求,不能用window.open(_url)的方式觸發瀏覽器下載。
解決方法:在DOM中增加一個a標籤,href設置成轉出文件地址,手動觸發a標籤的click事件。

downloadFile(data) {
        if (!data) {
          return;
        }
        let url = window.URL.createObjectURL(new Blob([data]));
        let link = document.createElement("a");
        link.style.display = "none";
        link.href = url;
        link.setAttribute("download", "check.xlsx");
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
      }

ok,成功下載了.xlsx文件。
問題2:下載的.xlsx文件無法打開,office excel 提示文件被損壞
原因分析:Uploader組件包裝了上傳的文件/請求,導致返回的數據類型出現錯誤,無法轉換成真正的.xlsx文件。
解決方法
採用原生的Request對象發送請求,拿到返回的Response,再調用 downloadFile() 方法

		var formData = new FormData();//FormData對象用以將數據編譯成鍵值對,以便用XMLHttpRequest來發送數據
        formData.append("file", this.$refs.upload.uploadFiles[0].raw);//拿到組件中的上傳文件的原始數據,添加到FormData中
        var xhr = new XMLHttpRequest();
        xhr.responseType = "blob";//設置responseType 爲 blob
        xhr.open(
          "POST",
          "http://devserver.6tiantian.com/ajax/question-bank-service/admin/question/knowledge_tag/check",
          true
        );
        xhr.onload = function() {
          this.downloadFile(xhr.response);
        }.bind(this);
        xhr.send(formData); //發送請求
      },

問題3:由於設置responseTypeblob,當後端報錯時,無法直接顯示報錯信息。要將blob類型轉成string。這裏用到 fileReader 對象。
FileReader 對象允許Web應用程序異步讀取存儲在用戶計算機上的文件(或原始數據緩衝區)的內容,使用 File 或 Blob 對象指定要讀取的文件或數據。
解決方法

xhr.onload = function() {
          if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {
            this.res = xhr.response;
            toastr.success("上傳成功!");
            this.status = 2;
          } else {
            var fr = new FileReader();
            fr.onload = function(e) {
              toastr.error(e.target.result);
              };
            fr.readAsText(xhr.response);
            this.status = 0;
          }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章