整合營(yíng)銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          js 實(shí)現(xiàn)純前端將數(shù)據(jù)導(dǎo)出excel兩種方式,親測(cè)有

          js 實(shí)現(xiàn)純前端將數(shù)據(jù)導(dǎo)出excel兩種方式,親測(cè)有效

          法一

          將table標(biāo)簽,包括tr、td等對(duì)json數(shù)據(jù)進(jìn)行拼接,將table輸出到表格上實(shí)現(xiàn),這種方法的弊端在于輸出的是偽excel,雖說(shuō)生成xls為后綴的文件,但文件形式上還是html,代碼如下

          <html>
          <head>
              <p style="font-size: 20px;color: red;">使用table標(biāo)簽方式將json導(dǎo)出xls文件</p>
              <button onclick='tableToExcel()'>導(dǎo)出</button>
          </head>
          <body>
              <script>  
              const tableToExcel=()=> {
                  // 要導(dǎo)出的json數(shù)據(jù)
                  const jsonData=[
                      {
                          name:'路人甲',
                          phone:'123456',
                          email:'123@123456.com'
                      },
                      {
                          name:'炮灰乙',
                          phone:'123456',
                          email:'123@123456.com'
                      },
                      {
                          name:'土匪丙',
                          phone:'123456',
                          email:'123@123456.com'
                      },
                      {
                          name:'流氓丁',
                          phone:'123456',
                          email:'123@123456.com'
                      },
                  ]
                  // 列標(biāo)題
                  let str='<tr><td>姓名</td><td>電話</td><td>郵箱</td></tr>';
                  // 循環(huán)遍歷,每行加入tr標(biāo)簽,每個(gè)單元格加td標(biāo)簽
                  for(let i=0 ; i < jsonData.length ; i++ ){
                      str+='<tr>';
                      for(const key in jsonData[i]){
                          // 增加\t為了不讓表格顯示科學(xué)計(jì)數(shù)法或者其他格式
                          str+=`<td>${ jsonData[i][key] + '\t'}</td>`;     
                      }
                      str+='</tr>';
                  }
                  // Worksheet名
                  const worksheet='Sheet1'
                  const uri='data:application/vnd.ms-excel;base64,';
           
                  // 下載的表格模板數(shù)據(jù)
                  const template=`<html xmlns:o="urn:schemas-microsoft-com:office:office" 
                  xmlns:x="urn:schemas-microsoft-com:office:excel" 
                  xmlns="http://www.w3.org/TR/REC-html40">
                  <head><!--[if gte mso 9]><xml><x:ExcelWorkbook><x:ExcelWorksheets><x:ExcelWorksheet>
                  <x:Name>${worksheet}</x:Name>
                  <x:WorksheetOptions><x:DisplayGridlines/></x:WorksheetOptions></x:ExcelWorksheet>
                  </x:ExcelWorksheets></x:ExcelWorkbook></xml><![endif]-->
                  </head><body><table>${str}</table></body></html>`;
                  // 下載模板
                  window.location.href=uri + base64(template);
              };
           
              // 輸出base64編碼
              const base64=s=> window.btoa(unescape(encodeURIComponent(s)));
              </script>
          </body>
          </html>

          方法二

          通過(guò)將json遍歷進(jìn)行字符串拼接,將字符串輸出到csv文件,代碼如下

          <html>
            
          <head>
              <p style="font-size: 20px;color: red;">使用a標(biāo)簽方式將json導(dǎo)出csv文件</p>
              <button onclick='tableToExcel()'>導(dǎo)出</button>
          </head>
          <body>
              <script>
              const tableToExcel=()=> {
                  // 要導(dǎo)出的json數(shù)據(jù)
                  const jsonData=[
                      {
                          name:'路人甲',
                          phone:'123456789',
                          email:'000@123456.com'
                      },
                      {
                          name:'炮灰乙',
                          phone:'123456789',
                          email:'000@123456.com'
                      },
                      {
                          name:'土匪丙',
                          phone:'123456789',
                          email:'000@123456.com'
                      },
                      {
                          name:'流氓丁',
                          phone:'123456789',
                          email:'000@123456.com'
                      },
                  ];
                  // 列標(biāo)題,逗號(hào)隔開(kāi),每一個(gè)逗號(hào)就是隔開(kāi)一個(gè)單元格
                  let str=`姓名,電話,郵箱\n`;
                  // 增加\t為了不讓表格顯示科學(xué)計(jì)數(shù)法或者其他格式
                  for(let i=0 ; i < jsonData.length ; i++ ){
                      for(const key in jsonData[i]){
                          str+=`${jsonData[i][key] + '\t'},`;     
                      }
                      str+='\n';
                  }
                  // encodeURIComponent解決中文亂碼
                  const uri='data:text/csv;charset=utf-8,\ufeff' + encodeURIComponent(str);
                  // 通過(guò)創(chuàng)建a標(biāo)簽實(shí)現(xiàn)
                  const link=document.createElement("a");
                  link.href=uri;
                  // 對(duì)下載的文件命名
                  link.download="json數(shù)據(jù)表.csv";
                  link.click();
              }
              </script>
          </body>
          </html>

          純干貨,希望對(duì)給位同僚有所幫助,感謝觀看,喜歡就點(diǎn)個(gè)贊吧

          avaScript在前端領(lǐng)域占據(jù)著絕對(duì)的統(tǒng)治地位,目前更是從瀏覽器到服務(wù)端,移動(dòng)端,嵌入式,幾乎所有的所有的應(yīng)用領(lǐng)域都可以使用它。技術(shù)圈有一句很經(jīng)典的話“凡是能用JavaScript實(shí)現(xiàn)的東西,最后都會(huì)用JavaScript實(shí)現(xiàn)”。

          Excel 電子表格自 1980 年代以來(lái)一直為各行業(yè)所廣泛使用,至今已擁有超過(guò)3億用戶,大多數(shù)人都熟悉 Excel 電子表格體驗(yàn)。許多企業(yè)在其業(yè)務(wù)的各個(gè)環(huán)節(jié)中使用了 Excel 電子表格進(jìn)行數(shù)據(jù)管理。

          作為全球領(lǐng)先的軟件開(kāi)發(fā)技術(shù)和低代碼平臺(tái)提供商,葡萄城專注開(kāi)發(fā)技術(shù)和工具已經(jīng)長(zhǎng)達(dá)四十余年,一直以來(lái)引領(lǐng)著國(guó)內(nèi)控件技術(shù)和數(shù)據(jù)分析工具的發(fā)展。SpreadJS表格控件作為葡萄城的核心產(chǎn)品,能夠完美兼容 Excel 的功能和使用體驗(yàn)并高度匹配在線辦公場(chǎng)景的需求。

          SpreadJS可以為我們的Web應(yīng)用提供更好的交互體驗(yàn),以及更靈活的權(quán)限控制、數(shù)據(jù)整合、數(shù)據(jù)可視化、戰(zhàn)略績(jī)效測(cè)量 (SPM)、復(fù)雜的統(tǒng)計(jì)分析等。多年來(lái),Excel 兼容性一直是SpreadJS最重要的功能之一。

          SpreadJS 提供了熟悉的 Excel 電子表格界面。用戶可以通過(guò)SpreadJS直接在頁(yè)面端導(dǎo)入和導(dǎo)出 Excel 文件——這一切無(wú)需依賴 Excel。

          在本博客中,我們將介紹如何按照以下步驟在 JavaScript 中,實(shí)現(xiàn)頁(yè)面端電子表格導(dǎo)入/導(dǎo)出到 Excel:

          1. 設(shè)置 JavaScript 電子表格項(xiàng)目

          2. 添加 Excel 導(dǎo)入代碼

          3. 將數(shù)據(jù)添加到導(dǎo)入的 Excel 文件

          4. 添加迷你圖

          5. 添加 Excel 導(dǎo)出代碼

          設(shè)置 JavaScript 電子表格項(xiàng)目

          首先,我們可以使用托管在 NPM 上的 SpreadJS 文件。為此,我們可以使用命令行參數(shù)進(jìn)行安裝。打開(kāi)命令提示符并導(dǎo)航到應(yīng)用程序的位置。在那里,您可以使用一個(gè)命令安裝所需的文件。

          在這種情況下,我們需要基本的 Spread-Sheets 庫(kù)、Spread-ExcelIO 和 jQuery:

          npm i @grapecity/spread-sheets @grapecity/spread-excelio jquery

          SpreadJS 不依賴于 jQuery,但在這種情況下,我們使用它來(lái)提供簡(jiǎn)單的跨域請(qǐng)求支持,稍后我們將對(duì)其進(jìn)行回顧。

          一旦安裝了這些,我們就可以在我們的代碼中添加對(duì)這些腳本和 CSS 文件的引用:

          <!DOCTYPE html>
          <html>
          <head>
          <title>SpreadJS ExcelIO</title>
          <script src="./node_modules/jquery/dist/jquery.min.js" type="text/javascript"></script>
          <script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/2014-11-29/FileSaver.min.js"></script>
          <link href="./node_modules/@grapecity/spread-sheets/styles/gc.spread.sheets.excel2013white.css" rel="stylesheet" type="text/css" />
          <script type="text/javascript" src="./node_modules/@grapecity/spread-sheets/dist/gc.spread.sheets.all.min.js"></script>
          <script type="text/javascript" src="./node_modules/@grapecity/spread-excelio/dist/gc.spread.excelio.min.js"></script>
          </head>
          <body>
          <div id="ss" style="height:600px; width :100%; "></div>
          </body>
          </html>

          除了 SpreadJS 和 jQuery 文件之外,我們還需要導(dǎo)入 FileSaver 庫(kù),為了便于后續(xù)程序處理,SpreadJS默認(rèn)提供完整的文件流,F(xiàn)ileSaver庫(kù)可以用來(lái)把文件流轉(zhuǎn)成文件下載到本地。

          然后我們可以在頁(yè)面中添加一個(gè)腳本來(lái)初始化 Spread.Sheets 組件和一個(gè) div 元素來(lái)包含它(因?yàn)?SpreadJS 電子表格組件使用了一個(gè)畫布,這是初始化組件所必需的):

          <script type="text/javascript">
          $(document).ready(function () {
          var workbook=new GC.Spread.Sheets.Workbook(document.getElementById("ss"));
          });
          </script>
          </head>
          <body>
          <div id="ss" style="height:600px ; width :100%; "></div>
          </body>

          添加 Excel 導(dǎo)入代碼

          我們需要?jiǎng)?chuàng)建一個(gè)客戶端 ExcelIO 組件的實(shí)例,我們可以使用它來(lái)打開(kāi)文件:

          var excelIO=new GC.Spread.Excel.IO();

          然后我們需要添加一個(gè)函數(shù)來(lái)導(dǎo)入文件。在此示例中,我們導(dǎo)入了一個(gè)本地文件,但您可以對(duì)服務(wù)器上的文件執(zhí)行相同的操作。如果從服務(wù)器導(dǎo)入文件,您需要引用該位置。下面是一個(gè)輸入元素的示例,用戶可以在其中輸入文件的位置:

          <input type="text" id="importUrl" value="http://www.testwebsite.com/files/TestExcel.xlsx" style="width:300px" />

          一旦你有了它,你可以直接在腳本代碼中訪問(wèn)該值:

          var excelUrl=$("#importUrl").val();

          導(dǎo)入函數(shù)的以下代碼使用“excelUrl”變量的本地文件:

          function ImportFile() {
          var excelUrl="./test.xlsx";
          
          var oReq=new XMLHttpRequest();
          oReq.open('get', excelUrl, true);
          oReq.responseType='blob';
          oReq.onload=function () {
          var blob=oReq.response;
          excelIO.open(blob, LoadSpread, function (message) {
          console.log(message);
          });
          };
          oReq.send(null);
          }
          function LoadSpread(json) {
          jsonData=json;
          workbook.fromJSON(json);
          
          workbook.setActiveSheet("Revenues (Sales)");
          }

          無(wú)論您是在服務(wù)器上還是在本地引用文件,都需要在 $(document).ready 函數(shù)內(nèi)的腳本中添加以下內(nèi)容:

          $(document).ready(function () {
          $.support.cors=true;
          workbook=new GC.Spread.Sheets.Workbook(document.getElementById("ss"));
          //...
          });

          在這種情況下,我們需要啟用 Cross-Origin-Request-Support,因?yàn)槲覀兛赡軙?huì)從 URL 加載文件。因此 $.support.cors=true;行,否則嘗試加載它會(huì)導(dǎo)致 CORS 錯(cuò)誤。

          將數(shù)據(jù)添加到導(dǎo)入的 Excel 文件

          我們使用本教程的“損益表”Excel 模板導(dǎo)入本地文件。

          現(xiàn)在我們可以使用 Spread.Sheets 腳本在這個(gè)文件中添加另一個(gè)收入行。讓我們?cè)陧?yè)面上添加一個(gè)按鈕來(lái)執(zhí)行此操作:

          <button id="addRevenue">Add Revenue</button>

          我們可以為該按鈕的單擊事件處理程序編寫一個(gè)函數(shù)來(lái)添加一行并從前一行復(fù)制樣式以準(zhǔn)備添加一些數(shù)據(jù)。要復(fù)制樣式,我們需要使用 copyTo 函數(shù)并傳入:

          1. 原始和目標(biāo)行和列索引

          2. 行數(shù)和列數(shù)

          3. 樣式的 CopyToOptions 值

          document.getElementById("addRevenue").onclick=function () {
          var sheet=workbook.getActiveSheet();
          sheet.addRows(newRowIndex, 1);
          sheet.copyTo(10, 1, newRowIndex, 1, 1, 29, GC.Spread.Sheets.CopyToOptions.style);
          }

          以下用于添加數(shù)據(jù)和 Sparkline 的腳本代碼將包含在此按鈕單擊事件處理程序中。對(duì)于大部分?jǐn)?shù)據(jù),我們可以使用 setValue 函數(shù)。這允許我們通過(guò)傳入行索引、列索引和值來(lái)在 Spread 中的工作表中設(shè)置值:

          sheet.setValue(newRowIndex, 1, "Revenue 8");
          for (var c=3; c < 15; c++) {
          sheet.setValue(newRowIndex, c, Math.floor(Math.random() * 200) + 10);
          }

          在 P 列中設(shè)置 SUM 公式以匹配其他行并為 Q 列設(shè)置百分比:

          sheet.setFormula(newRowIndex, 15, "=SUM([@[Jan]:[Dec]])")
          sheet.setValue(newRowIndex, 16, 0.15);

          最后,我們可以再次使用 copyTo 函數(shù)將先前行中的公式復(fù)制到 R 到 AD 列的新行,這次使用 CopyToOptions.formula:

          sheet.copyTo(10, 17, newRowIndex, 17, 1, 13, GC.Spread.Sheets.CopyToOptions.formula);

          添加迷你圖

          現(xiàn)在,我們可以添加迷你圖來(lái)匹配其他數(shù)據(jù)行。為此,我們需要提供一系列單元格以從中獲取數(shù)據(jù)以及迷你圖的一些設(shè)置。在這種情況下,我們可以指定:

          1. 單元格的范圍,我們只是將數(shù)據(jù)添加到

          2. 使迷你圖看起來(lái)像同一列中的其他迷你圖的設(shè)置

          var data=new GC.Spread.Sheets.Range(11, 3, 1, 12);
          var setting=new GC.Spread.Sheets.Sparklines.SparklineSetting();
          setting.options.seriesColor="Text 2";
          setting.options.lineWeight=1;
          setting.options.showLow=true;
          setting.options.showHigh=true;
          setting.options.lowMarkerColor="Text 2";
          setting.options.highMarkerColor="Text 1";

          之后,我們調(diào)用 setSparkline 方法并指定:

          1. 迷你圖的位置

          2. 數(shù)據(jù)的位置

          3. 迷你圖的方向

          4. 迷你圖的類型

          5. 我們創(chuàng)建的設(shè)置

          sheet.setSparkline(11, 2, data, GC.Spread.Sheets.Sparklines.DataOrientation.horizontal, GC.Spread.Sheets.Sparklines.SparklineType.line, setting);

          如果您現(xiàn)在嘗試運(yùn)行代碼,它可能看起來(lái)有點(diǎn)慢,因?yàn)槊看胃臄?shù)據(jù)和添加樣式時(shí)工作簿都會(huì)重新繪制。為了顯著加快速度并提高性能,Spread.Sheets 提供了暫停繪畫和計(jì)算服務(wù)的能力。讓我們?cè)谔砑右恍屑捌鋽?shù)據(jù)之前添加代碼以暫停兩者,然后在之后恢復(fù)兩者:

          workbook.suspendPaint();
          workbook.suspendCalcService();
          //...
          workbook.resumeCalcService();
          workbook.resumePaint();

          添加該代碼后,我們可以在 Web 瀏覽器中打開(kāi)該頁(yè)面,并查看 Excel 文件加載到 Spread.Sheets 中并添加了收入行。重要提示:請(qǐng)記住,出于安全考慮,Chrome 不允許您打開(kāi)本地文件,因此您需要使用 Firefox 等網(wǎng)絡(luò)瀏覽器才能成功運(yùn)行此代碼。或者,從網(wǎng)站 URL 加載文件應(yīng)該可以在任何瀏覽器中正常打開(kāi)。

          添加 Excel 導(dǎo)出代碼

          最后,我們可以添加一個(gè)按鈕來(lái)導(dǎo)出包含添加行的文件。為此,我們可以使用 Spread.Sheets 中內(nèi)置的客戶端 ExcelIO 代碼:

          function ExportFile() {
          var fileName=$("#exportFileName").val();
          if (fileName.substr(-5, 5) !=='.xlsx') {
          fileName +='.xlsx';
          }
          var json=JSON.stringify(workbook.toJSON());
          
          excelIO.save(json, function (blob) {
          saveAs(blob, fileName);
          }, function (e) {
          if (e.errorCode===1) {
          alert(e.errorMessage);
          }
          });
          }

          該代碼從 exportFileName 輸入元素獲取導(dǎo)出文件名。我們可以定義它并讓用戶像這樣命名文件:

          <input type="text" id="exportFileName" placeholder="Export file name" value="export.xlsx" />

          然后我們可以添加一個(gè)按鈕來(lái)調(diào)用這個(gè)函數(shù):

          <button id="export">Export File</button>
          document.getElementById("export").onclick=function () {
          ExportFile();
          }

          添加收入行后,您可以使用“導(dǎo)出文件”按鈕導(dǎo)出文件。確保添加 FileSaver 外部庫(kù)以允許用戶將文件保存在他們想要的位置:

          <script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/2014-11-29/FileSaver.min.js"></script>

          成功導(dǎo)出文件后,您可以在 Excel 中打開(kāi)它,并查看文件與導(dǎo)入時(shí)的外觀相同,只是現(xiàn)在我們添加了額外的收入行。

          這只是一個(gè)示例,說(shuō)明如何使用 SpreadJS JavaScript 電子表格將數(shù)據(jù)添加到 Excel 文件,然后使用簡(jiǎn)單的 JavaScript 代碼將它們導(dǎo)出回 Excel。

           前言

            導(dǎo)出Excel文件這個(gè)功能,通常都是在后端實(shí)現(xiàn)返回前端一個(gè)下載鏈接,但有時(shí)候我們只想導(dǎo)出前端頁(yè)面上已經(jīng)有了的數(shù)據(jù),不想再調(diào)后端導(dǎo)出接口浪費(fèi)服務(wù)器資源,學(xué)習(xí)本文demo例子,我們踹掉后端,直接在前端導(dǎo)出Excel!

            代碼實(shí)現(xiàn)

            1、利用Blob對(duì)象構(gòu)造一個(gè)a標(biāo)簽的href鏈接,從而實(shí)現(xiàn)文件下載,Excel支持html格式,因此我們只需要將構(gòu)造好的html內(nèi)容放到Blob對(duì)象中,即可下載Excel表格

            2、利用base64編碼構(gòu)造一個(gè)a標(biāo)簽的href鏈接,從而實(shí)現(xiàn)文件下載,同上,我們需要將構(gòu)造好的html內(nèi)容URI編碼拼到base64鏈接,即可下載Excel表格

              //blob、base64轉(zhuǎn)文件下載,通過(guò)A標(biāo)簽?zāi)M點(diǎn)擊,設(shè)置文件名
              /*
                  萬(wàn)能流  application/octet-stream
                  word文件  application/msword
                  excel文件  application/vnd.ms-excel
                  txt文件  text/plain
                  圖片文件  image/png、jpeg、gif、bmp
               */
              function downloadByBlob(fileName, text) {
                  let a=document.createElement("a");
                  a.href=URL.createObjectURL(new Blob([text], {type: "application/octet-stream"}));
                  a.download=fileName || 'Blob導(dǎo)出測(cè)試.txt';
                  a.click();
                  a.remove();
                  URL.revokeObjectURL(a.href);
              }
              function downloadByBase64(fileName, text) {
                  let a=document.createElement('a');
                  a.href='data:application/octet-stream;base64,' + window.btoa(unescape(encodeURIComponent(text)));
                  a.download=fileName || 'Base64導(dǎo)出測(cè)試.txt';
                  a.click();
                  a.remove();
                  URL.revokeObjectURL(a.href);
              }

            封裝導(dǎo)出Excel表格方法

              //踹掉后端,前端導(dǎo)出Excel!
              function exportExcel(fileName,columns,datas){
                  //列名
                  let columnHtml="";
                  columnHtml +="<tr style=\"text-align: center;\">\n";
                  for (let key in columns) {
                      columnHtml +="<td style=\"background-color:#bad5fd\">"+columns[key]+"</td>\n";
                  }
                  columnHtml +="</tr>\n";
          
                  //數(shù)據(jù)
                  let dataHtml="";
                  for (let data of datas) {
                      dataHtml +="<tr style=\"text-align: center;\">\n";
                      for (let key in columns) {
                          dataHtml +="<td>"+data[key]+"</td>\n";
                      }
                      dataHtml +="</tr>\n";
                  }
          
                  //完整html
                  let excelHtml="<html xmlns:o=\"urn:schemas-microsoft-com:office:office\"\n" +
                      "      xmlns:x=\"urn:schemas-microsoft-com:office:excel\"\n" +
                      "      xmlns=\"http://www.w3.org/TR/REC-html40\">\n" +
                      "<head>\n" +
                      "   <!-- 加這個(gè),其他單元格帶邊框 -->" +
                      "   <xml>\n" +
                      "        <x:ExcelWorkbook>\n" +
                      "            <x:ExcelWorksheets>\n" +
                      "                <x:ExcelWorksheet>\n" +
                      "                    <x:Name></x:Name>\n" +
                      "                    <x:WorksheetOptions>\n" +
                      "                        <x:DisplayGridlines/>\n" +
                      "                    </x:WorksheetOptions>\n" +
                      "                </x:ExcelWorksheet>\n" +
                      "            </x:ExcelWorksheets>\n" +
                      "        </x:ExcelWorkbook>\n" +
                      "   </xml>\n" +
                      "   <style>td{font-family: \"宋體\";}</style>\n" +
                      "</head>\n" +
                      "<body>\n" +
                      "<table border=\"1\">\n" +
                      "    <thead>\n" +
                      columnHtml +
                      "    </thead>\n" +
                      "    <tbody>\n" +
                      dataHtml +
                      "    </tbody>\n" +
                      "</table>\n" +
                      "</body>\n" +
                      "</html>";
          
                  //下載
                  downloadByBlob((fileName || "導(dǎo)出Excel")+".xls",excelHtml);
              }

            效果演示

            導(dǎo)出txt文檔

          downloadByBlob("downloadByBlob-導(dǎo)出txt文檔.txt","downloadByBlob\n導(dǎo)出txt簡(jiǎn)單測(cè)試\n");
          downloadByBase64("downloadByBase64-導(dǎo)出txt文檔.txt","downloadByBase64\n導(dǎo)出txt簡(jiǎn)單測(cè)試\n");

            導(dǎo)出Excel表格

          exportExcel("xx業(yè)務(wù)Excel導(dǎo)出", {"id": "編號(hào)", "name": "名字", "age": "年齡", "time": "參加工作時(shí)間"}, [{
                      "id": "A001",
                      "name": "張三",
                      "age": "18",
                      "time": new Date().toLocaleString()
                  },{
                      "id": "A002",
                      "name": "李四",
                      "age": "20",
                      "time": new Date().toLocaleString()
                  }]);

            導(dǎo)出word文檔也是一樣

            后記

            參考上我們之前的《FreeMarker模板引擎》,先畫好我們想要的文檔格式然后轉(zhuǎn)成xml,調(diào)用我們封裝好的方法,將構(gòu)造好的xml內(nèi)容轉(zhuǎn)成文件,實(shí)現(xiàn)前端導(dǎo)出復(fù)雜格式文檔!

            如果有復(fù)雜數(shù)據(jù),建議還是在后端操作,當(dāng)然你也可以把數(shù)據(jù)返回前端在前端導(dǎo)出也行

            前端導(dǎo)出Excel主要是利用Bolb、base64,以及Excel支持html格式的特性,這個(gè)特性不僅前端可以利用,后端也一樣可以,這里也分享一下后端工具類,原理都是一樣的

          package cn.huanzi.qch.util;
          
          import javax.servlet.http.HttpServletResponse;
          import java.io.File;
          import java.io.OutputStream;
          import java.io.PrintWriter;
          import java.text.SimpleDateFormat;
          import java.util.*;
          
          /**
           * Excel工具類
           */
          public class ExcelUtil {
          
              /**
               * 導(dǎo)出
               * 無(wú)需依賴POI
               */
              /*
                  示例:
                  try {
                      //列名
                      LinkedHashMap<String, String> columns=new LinkedHashMap<>(4);
                      columns.put("id","編號(hào)");
                      columns.put("name","名字");
                      columns.put("age","年齡");
                      columns.put("time","參加工作時(shí)間");
          
                      //數(shù)據(jù)
                      List<Map<String, Object>> datas=new ArrayList<>(3);
                      HashMap<String, Object> hashMap=new HashMap<>();
                      hashMap.put("id","A001");
                      hashMap.put("name","張三");
                      hashMap.put("age",18);
                      hashMap.put("time",new Date());
                      datas.add(hashMap);
          
                      //帶換行符:
          
                      HashMap<String, Object> hashMap2=new HashMap<>();
                      hashMap2.put("id","A002");
                      hashMap2.put("name","李四
          李四1
          李四2");
                      hashMap2.put("age",20);
                      hashMap2.put("time",new Date());
                      datas.add(hashMap2);
          
                      HashMap<String, Object> hashMap3=new HashMap<>();
                      hashMap3.put("id","A003");
                      hashMap3.put("name","王五");
                      hashMap3.put("age",25);
                      hashMap3.put("time",new Date());
                      datas.add(hashMap3);
          
                      //導(dǎo)出
                      ExcelUtil.exportByResponse(this.getResponse(),"Excel導(dǎo)出測(cè)試",columns,datas);
                      //ExcelUtil.exportByFile(new File("D:\\XFT User\\Downloads\\Excel導(dǎo)出測(cè)試.xls"),columns,datas);
                  } catch (Exception e) {
                      e.printStackTrace();
                  }
               */
              public static void exportByResponse(HttpServletResponse response, String fileName, LinkedHashMap<String, String> columns, List<Map<String, Object>> datas) throws Exception {
                  response.addHeader("Content-disposition", "attachment; filename=" + fileName + ".xls");
                  response.setContentType("application/ms-excel");
          
                  StringBuilder sb=exportOfData(columns, datas);
          
                  OutputStream out=response.getOutputStream();
                  out.write(sb.toString().getBytes("UTF-8"));
                  out.flush();
                  out.close();
              }
          
              public static void exportByFile(File file, LinkedHashMap<String, String> columns, List<Map<String, Object>> datas) {
                  StringBuilder sb=exportOfData(columns, datas);
          
                  try (PrintWriter myFile=new PrintWriter(file,"UTF-8")) {
                      myFile.println(sb);
                  } catch (Exception e) {
                      System.err.println("exportByFile(),操作出錯(cuò)...");
                      e.printStackTrace();
                  }
                  System.out.println(file.getName() + ",操作完成!");
              }
          
              //其他單元格無(wú)邊框
              private static StringBuilder exportOfData(LinkedHashMap<String, String> columns, List<Map<String, Object>> datas) {
                  StringBuilder sb=new StringBuilder("<html xmlns:o=\"urn:schemas-microsoft-com:office:office\"" +
                          "      xmlns:x=\"urn:schemas-microsoft-com:office:excel\"" +
                          "      xmlns=\"http://www.w3.org/TR/REC-html40\">");
          
                  //加這個(gè),其他單元格帶邊框
                  sb.append("<head>" +
                          "    <xml>" +
                          "        <x:ExcelWorkbook>" +
                          "            <x:ExcelWorksheets>" +
                          "                <x:ExcelWorksheet>" +
                          "                    <x:Name></x:Name>" +
                          "                    <x:WorksheetOptions>" +
                          "                        <x:DisplayGridlines/>" +
                          "                    </x:WorksheetOptions>" +
                          "                </x:ExcelWorksheet>" +
                          "            </x:ExcelWorksheets>" +
                          "        </x:ExcelWorkbook>" +
                          "    </xml>" +
                          "   <style>td{font-family: \"宋體\";}</style>" +
                          "</head>");
          
                  sb.append("<body>");
          
                  sb.append("<table border=\"1\">");
          
                  //列名
                  sb.append("<tr style=\"text-align: center;\">");
                  for (Map.Entry<String, String> entry : columns.entrySet()) {
                      sb.append("<td style=\"background-color:#bad5fd\">" + entry.getValue() + "</td>");
                  }
                  sb.append("</tr>");
          
                  //數(shù)據(jù)
                  for (Map<String, Object> data : datas) {
                      sb.append("<tr style=\"text-align: center;\">");
                      for (Map.Entry<String, String> entry : columns.entrySet()) {
                          Object dataValue=data.get(entry.getKey());
          
                          //如果是日期類型
                          if (dataValue instanceof java.util.Date) {
                              dataValue=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(dataValue);
                          }
                          sb.append("<td>" + dataValue.toString() + "</td>");
                      }
                      sb.append("</tr>");
                  }
          
                  sb.append("</table>");
          
                  sb.append("</body>");
          
                  sb.append("</html>");
          
                  return sb;
              }
          
              //前端導(dǎo)出Excel
              /*
                  示例:
                   exportExcel("xx業(yè)務(wù)Excel導(dǎo)出", {"id": "編號(hào)", "name": "名字", "age": "年齡", "time": "參加工作時(shí)間"}, [{
                      "id": "A001",
                      "name": "張三",
                      "age": "18",
                      "time": new Date().toLocaleString()
                  },{
                      "id": "A002",
                      "name": "李四",
                      "age": "20",
                      "time": new Date().toLocaleString()
                  }]);
               */
              /*
                  //blob、base64轉(zhuǎn)文件下載,通過(guò)A標(biāo)簽?zāi)M點(diǎn)擊,設(shè)置文件名
                  //萬(wàn)能流  application/octet-stream
                  //word文件  application/msword
                  //excel文件  application/vnd.ms-excel
                  //txt文件  text/plain
                  //圖片文件  image/png、jpeg、gif、bmp
                  function downloadByBlob(fileName, text) {
                      let a=document.createElement("a");
                      a.href=URL.createObjectURL(new Blob([text], {type: "application/octet-stream"}));
                      a.download=fileName || 'Blob導(dǎo)出測(cè)試.txt';
                      a.click();
                      a.remove();
                      URL.revokeObjectURL(a.href);
                  }
                  function downloadByBase64(fileName, text) {
                      let a=document.createElement('a');
                      a.href='data:application/octet-stream;base64,' + window.btoa(unescape(encodeURIComponent(text)));
                      a.download=fileName || 'Base64導(dǎo)出測(cè)試.txt';
                      a.click();
                      a.remove();
                      URL.revokeObjectURL(a.href);
                  }
              
                  //踹掉后端,前端導(dǎo)出Excel!
                  function exportExcel(fileName,columns,datas){
                      //列名
                      let columnHtml="";
                      columnHtml +="<tr style=\"text-align: center;\">\n";
                      for (let key in columns) {
                          columnHtml +="<td style=\"background-color:#bad5fd\">"+columns[key]+"</td>\n";
                      }
                      columnHtml +="</tr>\n";
              
                      //數(shù)據(jù)
                      let dataHtml="";
                      for (let data of datas) {
                          dataHtml +="<tr style=\"text-align: center;\">\n";
                          for (let key in columns) {
                              dataHtml +="<td>"+data[key]+"</td>\n";
                          }
                          dataHtml +="</tr>\n";
                      }
              
                      //完整html
                      let excelHtml="<html xmlns:o=\"urn:schemas-microsoft-com:office:office\"\n" +
                              "      xmlns:x=\"urn:schemas-microsoft-com:office:excel\"\n" +
                              "      xmlns=\"http://www.w3.org/TR/REC-html40\">\n" +
                              "<head>\n" +
                              "   <!-- 加這個(gè),其他單元格帶邊框 -->" +
                              "   <xml>\n" +
                              "        <x:ExcelWorkbook>\n" +
                              "            <x:ExcelWorksheets>\n" +
                              "                <x:ExcelWorksheet>\n" +
                              "                    <x:Name></x:Name>\n" +
                              "                    <x:WorksheetOptions>\n" +
                              "                        <x:DisplayGridlines/>\n" +
                              "                    </x:WorksheetOptions>\n" +
                              "                </x:ExcelWorksheet>\n" +
                              "            </x:ExcelWorksheets>\n" +
                              "        </x:ExcelWorkbook>\n" +
                              "   </xml>\n" +
                              "   <style>td{font-family: \"宋體\";}</style>\n" +
                              "</head>\n" +
                              "<body>\n" +
                              "<table border=\"1\">\n" +
                              "    <thead>\n" +
                              columnHtml +
                              "    </thead>\n" +
                              "    <tbody>\n" +
                              dataHtml +
                              "    </tbody>\n" +
                              "</table>\n" +
                              "</body>\n" +
                              "</html>";
              
                      //下載
                      downloadByBlob((fileName || "導(dǎo)出Excel")+".xls",excelHtml);
                  }
               */
          }

          版權(quán)聲明

          作者:huanzi-qch

          出處:https://www.cnblogs.com/huanzi-qch

          若標(biāo)題中有“轉(zhuǎn)載”字樣,則本文版權(quán)歸原作者所有。若無(wú)轉(zhuǎn)載字樣,本文版權(quán)歸作者所有,歡迎轉(zhuǎn)載,但未經(jīng)作者同意必須保留此段聲明,且在文章頁(yè)面明顯位置給出原文鏈接,否則保留追究法律責(zé)任的權(quán)利.


          主站蜘蛛池模板: 亚洲成av人片一区二区三区 | 亚洲成AV人片一区二区| 日本v片免费一区二区三区| 精品日本一区二区三区在线观看| 日本精品夜色视频一区二区| 相泽南亚洲一区二区在线播放 | 福利视频一区二区牛牛| 欧洲精品码一区二区三区免费看| 亚洲熟妇无码一区二区三区| 国产精品视频一区二区猎奇| 一区二区三区观看免费中文视频在线播放 | 在线视频一区二区三区| 国产伦精品一区二区三区不卡| 亚洲av无码一区二区三区在线播放| 成人精品一区二区不卡视频| 丰满岳妇乱一区二区三区| 精品无人区一区二区三区在线| 无码人妻精品一区二区三区99不卡| 精品一区二区三区免费 | 一区二区三区日韩精品| 精品一区二区无码AV| 无码人妻精品一区二区三区不卡| 一区二区三区在线|日本| 无码精品视频一区二区三区| 日本免费一区二区三区最新| 国产成人一区二区三区精品久久| 亚洲AV无码一区二区三区鸳鸯影院 | 国产精品亚洲午夜一区二区三区 | 无码国产精品一区二区免费vr| 一区二区日韩国产精品| 国产在线观看精品一区二区三区91 | 日韩动漫av在线播放一区| 国产精品亚洲专一区二区三区| 亚洲无线码在线一区观看| 精品视频一区二区三区在线观看| 国产一区二区三区免费| 国产一区二区三区无码免费| 一区二区三区视频在线| 成人无码精品一区二区三区| 亚洲中文字幕一区精品自拍| 一区二区视频免费观看|