整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          前端導出Excel,讓后端刮目相看

          前端導出Excel,讓后端刮目相看

          這幾天在開發中遇到一個事情,做一個導出的功能,但是后臺是新來的菜鳥,等了三天沒反應,接口做不出來,我內心一萬個。。。。,于是乎我就打算前端做導出了,網上復制了一些代碼就出來了。

          導入依賴

          // npm
          npm install -S file-saver xlsx
          npm install -D script-loader
          復制代碼

          導入Bolb.js與Export2Excel.js

          首先拷貝以下兩個文件代碼: Export2Excel.js

          /* eslint-disable */
          require('script-loader!file-saver');
          require('script-loader!vendor/Blob');
          require('script-loader!xlsx/dist/xlsx.core.min');
          function generateArray(table) {
              var out=[];
              var rows=table.querySelectorAll('tr');
              var ranges=[];
              for (var R=0; R < rows.length; ++R) {
                  var outRow=[];
                  var row=rows[R];
                  var columns=row.querySelectorAll('td');
                  for (var C=0; C < columns.length; ++C) {
                      var cell=columns[C];
                      var colspan=cell.getAttribute('colspan');
                      var rowspan=cell.getAttribute('rowspan');
                      var cellValue=cell.innerText;
                      if (cellValue !=="" && cellValue==+cellValue) cellValue=+cellValue;
                      //Skip ranges
                      ranges.forEach(function (range) {
                          if (R >=range.s.r && R <=range.e.r && outRow.length >=range.s.c && outRow.length <=range.e.c) {
                              for (var i=0; i <=range.e.c - range.s.c; ++i) outRow.push(null);
                          }
                      });
                      //Handle Row Span
                      if (rowspan || colspan) {
                          rowspan=rowspan || 1;
                          colspan=colspan || 1;
                          ranges.push({s: {r: R, c: outRow.length}, e: {r: R + rowspan - 1, c: outRow.length + colspan - 1}});
                      }
                      ;
                      //Handle Value
                      outRow.push(cellValue !=="" ? cellValue : null);
                      //Handle Colspan
                      if (colspan) for (var k=0; k < colspan - 1; ++k) outRow.push(null);
                  }
                  out.push(outRow);
              }
              return [out, ranges];
          };
          function datenum(v, date1904) {
              if (date1904) v +=1462;
              var epoch=Date.parse(v);
              return (epoch - new Date(Date.UTC(1899, 11, 30))) / (24 * 60 * 60 * 1000);
          }
          function sheet_from_array_of_arrays(data, opts) {
              var ws={};
              var range={s: {c: 10000000, r: 10000000}, e: {c: 0, r: 0}};
              for (var R=0; R !=data.length; ++R) {
                  for (var C=0; C !=data[R].length; ++C) {
                      if (range.s.r > R) range.s.r=R;
                      if (range.s.c > C) range.s.c=C;
                      if (range.e.r < R) range.e.r=R;
                      if (range.e.c < C) range.e.c=C;
                      var cell={v: data[R][C]};
                      if (cell.v==null) continue;
                      var cell_ref=XLSX.utils.encode_cell({c: C, r: R});
                      if (typeof cell.v==='number') cell.t='n';
                      else if (typeof cell.v==='boolean') cell.t='b';
                      else if (cell.v instanceof Date) {
                          cell.t='n';
                          cell.z=XLSX.SSF._table[14];
                          cell.v=datenum(cell.v);
                      }
                      else cell.t='s';
                      ws[cell_ref]=cell;
                  }
              }
              if (range.s.c < 10000000) ws['!ref']=XLSX.utils.encode_range(range);
              return ws;
          }
          function Workbook() {
              if (!(this instanceof Workbook)) return new Workbook();
              this.SheetNames=[];
              this.Sheets={};
          }
          function s2ab(s) {
              var buf=new ArrayBuffer(s.length);
              var view=new Uint8Array(buf);
              for (var i=0; i !=s.length; ++i) view[i]=s.charCodeAt(i) & 0xFF;
              return buf;
          }
          export function export_table_to_excel(id) {
              var theTable=document.getElementById(id);
              console.log('a')
              var oo=generateArray(theTable);
              var ranges=oo[1];
              /* original data */
              var data=oo[0];
              var ws_name="SheetJS";
              console.log(data);
              var wb=new Workbook(), ws=sheet_from_array_of_arrays(data);
              /* add ranges to worksheet */
              // ws['!cols']=['apple', 'banan'];
              ws['!merges']=ranges;
              /* add worksheet to workbook */
              wb.SheetNames.push(ws_name);
              wb.Sheets[ws_name]=ws;
              var wbout=XLSX.write(wb, {bookType: 'xlsx', bookSST: false, type: 'binary'});
              saveAs(new Blob([s2ab(wbout)], {type: "application/octet-stream"}), "test.xlsx")
          }
          function formatJson(jsonData) {
              console.log(jsonData)
          }
          export function export_json_to_excel(th, jsonData, defaultTitle) {
              /* original data */
              var data=jsonData;
              data.unshift(th);
              var ws_name="SheetJS";
              var wb=new Workbook(), ws=sheet_from_array_of_arrays(data);
              /* add worksheet to workbook */
              wb.SheetNames.push(ws_name);
              wb.Sheets[ws_name]=ws;
              var wbout=XLSX.write(wb, {bookType: 'xlsx', bookSST: false, type: 'binary'});
              var title=defaultTitle || '列表'
              saveAs(new Blob([s2ab(wbout)], {type: "application/octet-stream"}), title + ".xlsx")
          }
          復制代碼

          Blob.js

          
          (function (view) {
              "use strict";
              view.URL=view.URL || view.webkitURL;
              if (view.Blob && view.URL) {
                  try {
                      new Blob;
                      return;
                  } catch (e) {}
              }
              // Internally we use a BlobBuilder implementation to base Blob off of
              // in order to support older browsers that only have BlobBuilder
              var BlobBuilder=view.BlobBuilder || view.WebKitBlobBuilder || view.MozBlobBuilder || (function(view) {
                      var
                          get_class=function(object) {
                              return Object.prototype.toString.call(object).match(/^\[object\s(.*)\]$/)[1];
                          }
                          , FakeBlobBuilder=function BlobBuilder() {
                              this.data=[];
                          }
                          , FakeBlob=function Blob(data, type, encoding) {
                              this.data=data;
                              this.size=data.length;
                              this.type=type;
                              this.encoding=encoding;
                          }
                          , FBB_proto=FakeBlobBuilder.prototype
                          , FB_proto=FakeBlob.prototype
                          , FileReaderSync=view.FileReaderSync
                          , FileException=function(type) {
                              this.code=this[this.name=type];
                          }
                          , file_ex_codes=(
                              "NOT_FOUND_ERR SECURITY_ERR ABORT_ERR NOT_READABLE_ERR ENCODING_ERR "
                              + "NO_MODIFICATION_ALLOWED_ERR INVALID_STATE_ERR SYNTAX_ERR"
                          ).split(" ")
                          , file_ex_code=file_ex_codes.length
                          , real_URL=view.URL || view.webkitURL || view
                          , real_create_object_URL=real_URL.createObjectURL
                          , real_revoke_object_URL=real_URL.revokeObjectURL
                          , URL=real_URL
                          , btoa=view.btoa
                          , atob=view.atob
                          , ArrayBuffer=view.ArrayBuffer
                          , Uint8Array=view.Uint8Array
                          ;
                      FakeBlob.fake=FB_proto.fake=true;
                      while (file_ex_code--) {
                          FileException.prototype[file_ex_codes[file_ex_code]]=file_ex_code + 1;
                      }
                      if (!real_URL.createObjectURL) {
                          URL=view.URL={};
                      }
                      URL.createObjectURL=function(blob) {
                          var
                              type=blob.type
                              , data_URI_header
                              ;
                          if (type===null) {
                              type="application/octet-stream";
                          }
                          if (blob instanceof FakeBlob) {
                              data_URI_header="data:" + type;
                              if (blob.encoding==="base64") {
                                  return data_URI_header + ";base64," + blob.data;
                              } else if (blob.encoding==="URI") {
                                  return data_URI_header + "," + decodeURIComponent(blob.data);
                              } if (btoa) {
                                  return data_URI_header + ";base64," + btoa(blob.data);
                              } else {
                                  return data_URI_header + "," + encodeURIComponent(blob.data);
                              }
                          } else if (real_create_object_URL) {
                              return real_create_object_URL.call(real_URL, blob);
                          }
                      };
                      URL.revokeObjectURL=function(object_URL) {
                          if (object_URL.substring(0, 5) !=="data:" && real_revoke_object_URL) {
                              real_revoke_object_URL.call(real_URL, object_URL);
                          }
                      };
                      FBB_proto.append=function(data/*, endings*/) {
                          var bb=this.data;
                          // decode data to a binary string
                          if (Uint8Array && (data instanceof ArrayBuffer || data instanceof Uint8Array)) {
                              var
                                  str=""
                                  , buf=new Uint8Array(data)
                                  , i=0
                                  , buf_len=buf.length
                                  ;
                              for (; i < buf_len; i++) {
                                  str +=String.fromCharCode(buf[i]);
                              }
                              bb.push(str);
                          } else if (get_class(data)==="Blob" || get_class(data)==="File") {
                              if (FileReaderSync) {
                                  var fr=new FileReaderSync;
                                  bb.push(fr.readAsBinaryString(data));
                              } else {
                                  // async FileReader won't work as BlobBuilder is sync
                                  throw new FileException("NOT_READABLE_ERR");
                              }
                          } else if (data instanceof FakeBlob) {
                              if (data.encoding==="base64" && atob) {
                                  bb.push(atob(data.data));
                              } else if (data.encoding==="URI") {
                                  bb.push(decodeURIComponent(data.data));
                              } else if (data.encoding==="raw") {
                                  bb.push(data.data);
                              }
                          } else {
                              if (typeof data !=="string") {
                                  data +=""; // convert unsupported types to strings
                              }
                              // decode UTF-16 to binary string
                              bb.push(unescape(encodeURIComponent(data)));
                          }
                      };
                      FBB_proto.getBlob=function(type) {
                          if (!arguments.length) {
                              type=null;
                          }
                          return new FakeBlob(this.data.join(""), type, "raw");
                      };
                      FBB_proto.toString=function() {
                          return "[object BlobBuilder]";
                      };
                      FB_proto.slice=function(start, end, type) {
                          var args=arguments.length;
                          if (args < 3) {
                              type=null;
                          }
                          return new FakeBlob(
                              this.data.slice(start, args > 1 ? end : this.data.length)
                              , type
                              , this.encoding
                          );
                      };
                      FB_proto.toString=function() {
                          return "[object Blob]";
                      };
                      FB_proto.close=function() {
                          this.size=this.data.length=0;
                      };
                      return FakeBlobBuilder;
                  }(view));
              view.Blob=function Blob(blobParts, options) {
                  var type=options ? (options.type || "") : "";
                  var builder=new BlobBuilder();
                  if (blobParts) {
                      for (var i=0, len=blobParts.length; i < len; i++) {
                          builder.append(blobParts[i]);
                      }
                  }
                  return builder.getBlob(type);
              };
          }(typeof self !=="undefined" && self || typeof window !=="undefined" && window || this.content || this));
          復制代碼

          因為我們在Export2Excel.js中設置的Blob路徑為vendor,所以我們要在src下建立相關文件夾并放入這兩個js。

          設置導出表格數據

          假設我們需要導出一個這樣的表格

          數據

          // data
          dataList: [
              { name: "張明", loginTime: 16, id: 1, department: "生產部", sex: "男" },
              { name: "小金", loginTime: 11, id: 2, department: "生產部", sex: "女" },
              { name: "小凌", loginTime: 21, id: 3, department: "生產部", sex: "男" },
              { name: "蓋倫", loginTime: 5, id: 4, department: "測試部", sex: "男" }
          ]
          復制代碼

          html

          <table border>
                <tr>
                  <th>ID</th>
                  <th>名稱</th>
                  <th>登陸次數</th>
                  <th>部門</th>
                </tr>
                <tr v-for="item in dataList" :key="item.id">
                  <td>{{ item.id }}</td>
                  <td>{{ item.name }}</td>
                  <td>{{ item.loginTime }}</td>
                  <td>{{ item.department }}</td>
                </tr>
              </table>
              <button @click="exportExcel">導出信息</button>
          復制代碼

          methods

          
          // 導出excel
          exportExcel() {
            // 引入文件
            const { export_json_to_excel }=require("vendor/Export2Excel.js");
            // 表頭
            const tHeader=["ID", "名稱", "登陸次數", "部門"];
            // table表格中對應的屬性名
            const filterVal=["id", "name", "loginTime", "department"];
            // 表格綁定數據轉json
            const data=this.formatJson(filterVal, this.dataList);
            export_json_to_excel(
              tHeader,
              data,
              "部門登陸信息" + new Date().toLocaleDateString()
            ); // 對應下載文件的名字
          },
          // 導出列表格式化數據的方法
          formatJson(filterVal, jsonData) {
            return jsonData.map(v=> filterVal.map(j=> v[j]));
          }
          
          復制代碼

          展示效果

          到此,前端導出功能實現。這種方式的優勢在于:1.不用請求后端獲取文件。2.所見即所得,前端可有靈活地把控輸出的數據,不用因為導出的數據有差錯而拉著后端一起聯調。

          多sheet導出

          我們可能有時候會遇到對Excel多sheet的操作,比如部門的多季度績效分多sheet導出。

          我們需要在Export2Excel.js中添加一個方法:

          /**
           * 多sheet導出
           * @param {Array} th 表頭
           * @param {Array} jsonDatas 數據集 
           * @param {String} defaultTitle 導出的excel名稱
           * @param {Array} sheetNames sheet名稱集
           */
          export function export_season_to_excel(th, jsonDatas, defaultTitle, sheetNames) {
            var wb=new Workbook()
            jsonDatas.forEach((item, index)=> {
              var data=item;
              data.unshift(th);
              var ws_name=sheetNames[index];
              var ws=sheet_from_array_of_arrays(data);
              /* add worksheet to workbook */
              wb.SheetNames.push(ws_name);
              wb.Sheets[ws_name]=ws;
            })
            var wbout=XLSX.write(wb, {
              bookType: 'xlsx',
              bookSST: false,
              type: 'binary'
            });
            var title=defaultTitle || '列表'
            saveAs(new Blob([s2ab(wbout)], {
              type: "application/octet-stream"
            }), title + ".xlsx")
          }
          復制代碼

          頁面中的data內容:

          // data 季度績效數據
          seasonDatas: [
                  [
                    { name: "張明", score: 72 },
                    { name: "小金", score: 21 },
                    { name: "小凌", score: 16 },
                    { name: "蓋倫", score: 84 }
                  ],
                  [
                    { name: "張明", score: 32 },
                    { name: "小金", score: 54 },
                    { name: "小凌", score: 45 },
                    { name: "蓋倫", score: 26 }
                  ],
                  [
                    { name: "張明", score: 67 },
                    { name: "小金", score: 87 },
                    { name: "小凌", score: 45 },
                    { name: "蓋倫", score: 78 }
                  ],
                  [
                    { name: "張明", score: 54 },
                    { name: "小金", score: 34 },
                    { name: "小凌", score: 26 },
                    { name: "蓋倫", score: 34 }
                  ]
                ]
          復制代碼

          html

          <div class="season">
                <template v-for="(item, index) in seasonDatas">
                  <div :key="index">
                    {{ `第${index + 1}季度績效` }}
                    <table border>
                      <tr>
                        <th>名稱</th>
                        <th>績效分</th>
                      </tr>
                      <tr v-for="(scoreItem, scoreindex) in item" :key="scoreindex">
                        <td>{{ scoreItem.name }}</td>
                        <td>{{ scoreItem.score }}</td>
                      </tr>
                    </table>
                  </div>
                </template>
              </div>
              <button @click="exportSeason">導出績效信息</button>
          復制代碼

          執行方法

          
              // methods 導出績效信息excel
              exportSeason() {
                // 引入文件
                const { export_season_to_excel }=require("vendor/Export2Excel.js");
                // 表頭
                const tHeader=["名稱", "績效分"];
                // table表格中對應的屬性名
                const filterVal=["name", "score"];
                let datas=[];
                let sheets=[];
                this.seasonDatas.forEach((item, index)=> {
                  // 表格綁定數據轉json
                  datas.push(this.formatJson(filterVal, item));
                  sheets.push(`第${index + 1}季度績效`);
                });
                export_season_to_excel(
                  tHeader,
                  datas,
                  "部門季度績效" + new Date().toLocaleDateString(),
                  sheets
                ); // 對應下載文件的名字
              },
          復制代碼

          展示效果:

          至此,多Sheet導出我們也完成了。

          項目地址

          項目地址:https://github.com/FireSmallPanda/vuexDemo.git



          存疑解析

          大數據導出和自定義表頭名稱

          在文章發出后大家對大數據導出和怎么自定義表頭存在疑惑,我這邊設置了一個可以自定義導出規模的例子。

          html部分

              <p><input type="number" v-model="rows" />行</p>
              <p><input type="number" v-model="cols" />列</p>
              <button @click="outPutBigData">導出自定義大小表格信息</button>
          復制代碼

          js部分

          // data
          rows: 100, // 行
          cols: 100 // 列
          // methods
           // 導出自定義數據
          outPutBigData() {
            // 引入文件
            const { export_json_to_excel }=require("vendor/Export2Excel.js");
            // 表頭
            let tHeader=[];
            // table表格中對應的屬性名
            let filterVal=[];
            // 需要導出的內容
            let pushData=[];
            // 自定義生成列
            for (let i=0; i < this.cols * 1; i++) {
              tHeader.push(`第${i + 1}列數據`);
              filterVal.push(i);
            }
            // 生成自定義數據
            for (let j=0; j < this.rows * 1; j++) {
              let pushObj={};
              for (let i=0; i < this.cols * 1; i++) {
                // 這邊為展示數據不一致性設置為隨機數
                pushObj[i]=Math.random();
              }
              // 插入一條數據
              pushData.push(pushObj);
            }
            // ---至此模擬后端請求數據結束---
            // 表格綁定數據轉json
            const data=this.formatJson(filterVal, pushData);
            export_json_to_excel(
              tHeader,
              data,
              "自定義導出數據" + new Date().toLocaleDateString()
            ); // 對應下載文件的名字
          },
          復制代碼

          演示效果:

          為方便大家直觀的看到,我們這次導出10000行10列的隨機數據.可以看到,其中的列名稱我也是自動生成的。


          作者:有趣的老凌
          鏈接:https://juejin.cn/post/7030291455243452429
          來源:稀土掘金
          著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。

          年(Light Year Admin)后臺管理系統模板是一個基于Bootstrap v3.3.7的純HTML模板。

          作為后端開發人員,自己在做一些簡單系統時,經常為了后臺的模板煩惱,國內的少,也不太喜歡tab形式的;國外的又太復雜;vue什么框架的又不會用,因而想自己整理出來一個簡單點的通用后臺模板,結合自己的使用和國外模板的配色、細節處理,這就有了光年后臺模板。

          簡潔而清新的后臺模板,功能雖少,倒也滿足簡單的后臺功能,也能夠快速上手,希望大家支持。

          特別感謝

          • Bootstrap
          • JQuery
          • bootstrap-colorpicker
          • bootstrap-datepicker
          • bootstrap-datetimepicker
          • ion-rangeslider
          • jquery-confirm
          • jquery-tags-input
          • bootstrap-notify
          • Chart.js
          • chosen.jquery.js
          • perfect-scrollbar

          登錄頁面

          后臺首頁

          開關樣式

          文檔列表

          項目代碼

          東優就業

          頁面傳值小技巧

          平常我們在做的web項目,一般一個HTML頁面上會有好幾個步驟,step_num①,step_num②,step_num③,一般先顯示step_num①,根據跳轉條件顯示step_num②,step_num①隱藏,再跳轉step_num③,step_num①,step_num②隱藏,step_num③顯示。

          思路: (js設置全局變量,哪里需要在哪里添加一個input標簽,把值賦給一個input,然后再讓input隱藏)

          廣東優就業

          先說下這個頁面的結構,進入xxx.html頁面,通過js發送ajax.postForm請求,請求一個action,action調用handler,每一個功能都要請求一個action。

          廣東優就業

          前兩天就是這樣的一個頁面,然后在傳值的時候就碰到了一個讓人腦仁疼的問題,需要在step_num①中顯示和未顯示的值,傳到step_num③對應的后臺Java代碼,試了好幾種方法都不好用,最后,采用了一個小技巧

          在js中先設一個全局變量,比如var groupID=" "; ,然后把從step_num①中從后臺action傳過來的GroupID賦給groupID,怎么傳給頁面三對應的Java后臺呢?

          現在step_num③對應的HTML代碼中寫上這樣一條語句:<input id="chuanzhi" name="chuanzhi" type="hidden"/>然后在對應的js代碼中把 $("#chuanzhi").val(groupID);

          這樣你在step_num③對應的Java后臺中就可以通過request.getParameter("chuanzhi"); 獲得你想要的groupID了

          更多IT精彩內容推薦:http://www.ujiuye.com/guangdong/?wt.mc_id=17009338


          主站蜘蛛池模板: 国产一区高清视频| 亚洲日韩精品一区二区三区无码| 亚洲AV无码一区东京热| 国产一区二区精品久久91| 国产一区二区三区福利| 久久久91精品国产一区二区| 精品一区二区三区AV天堂| 久久免费区一区二区三波多野| 精品一区二区三区3d动漫| 亚洲精品国产suv一区88| 香蕉免费一区二区三区| 亚洲AV无码一区二三区| 国产精品免费视频一区| 成人毛片一区二区| 3D动漫精品一区二区三区| 亚洲福利一区二区三区| 无码少妇一区二区三区浪潮AV| 中文字幕亚洲乱码熟女一区二区| 一区二区三区四区在线视频| 日本精品3d动漫一区二区| 午夜一区二区免费视频| 午夜一区二区在线观看| 国产在线一区视频| 国产一区二区三区在线| 一区二区三区内射美女毛片| 日韩一区二区三区免费体验| 久久精品国产第一区二区三区| 国产色情一区二区三区在线播放 | 成人区人妻精品一区二区不卡视频| 亚洲熟妇av一区二区三区下载| 亚洲综合在线一区二区三区| 日韩精品中文字幕无码一区| 日韩精品无码一区二区视频| 久久精品道一区二区三区| 熟妇人妻系列av无码一区二区| 人妻无码一区二区三区AV| 日本一区午夜爱爱| 亚洲午夜电影一区二区三区| 日本精品夜色视频一区二区| 日韩一区二区在线免费观看| 国产精品一区电影|