最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

spring+angular實(shí)現(xiàn)導(dǎo)出excel的實(shí)現(xiàn)代碼

 更新時(shí)間:2019年02月27日 09:32:09   作者:喵先生的進(jìn)階之路  
這篇文章主要介紹了spring+angular實(shí)現(xiàn)導(dǎo)出excel的實(shí)現(xiàn)代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧

需求描述

要求批量導(dǎo)出數(shù)據(jù),以excel的格式。

選擇方式

前臺(tái) + 后臺(tái)

之前在別的項(xiàng)目中也遇到過導(dǎo)出的問題,解決方式是直接在前臺(tái)導(dǎo)出將表格導(dǎo)出。

這次沒有選擇前臺(tái)導(dǎo)出的方式,是由于需要導(dǎo)出所有的數(shù)據(jù),所以考慮直接在后臺(tái)獲取所有的數(shù)據(jù),然后就直接導(dǎo)出,最后前臺(tái)觸發(fā)導(dǎo)出API。

后臺(tái)實(shí)現(xiàn)

導(dǎo)出使用的是POI,在上一篇文章中,我已做了基本的介紹,這里就不做介紹配置了,參照:POI實(shí)現(xiàn)將導(dǎo)入Excel文件

創(chuàng)建表格

首先先建立一張表,這里要建立.xlsx格式的表格,使用XSSFWorkbook:

Workbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet("new sheet");

接著創(chuàng)建表格的行和單元格:

Row row = sheet.createRow(0);
row.createCell(0);

然后設(shè)置表頭:

row.createCell(0).setCellValue("學(xué)號(hào)");
row.createCell(1).setCellValue("姓名");
row.createCell(2).setCellValue("手機(jī)號(hào)碼");

最后獲取所有的數(shù)據(jù),對應(yīng)的填寫到單元格中:

int i = 1;
for (Student student : studentList) {
  row = sheet.createRow(i);
  row.createCell(0).setCellValue(student.getStudentNumber());
  row.createCell(1).setCellValue(student.getName());
  row.createCell(2).setCellValue(student.getPhoneNumber());
  i++;
}

輸出

這部分是糾結(jié)比較久的,反復(fù)試了很多次。

一開始是直接以文件輸出流的形式輸出的:

FileOutputStream output = new FileOutputStream("test.xlsx");
workbook.write(output);

這樣可以正確生成文件,但是問題是,它會(huì)生成在項(xiàng)目的根目錄下。

而我們想要的效果是,下載在本地自己的文件夾中。

要解決這個(gè)問題,需要添加相應(yīng)信息,返回給瀏覽器:

OutputStream fos = response.getOutputStream();
response.reset();
String fileName = "test";
fileName = URLEncoder.encode(fileName, "utf8");
response.setHeader("Content-disposition", "attachment;filename="+ fileName+".xlsx");

response.setCharacterEncoding("UTF-8");
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
workbook.write(fos);
fos.close();

后臺(tái)代碼:

public void batchExport(HttpServletResponse response) {
  logger.debug("創(chuàng)建工作表");
  Workbook workbook = new XSSFWorkbook();
  Sheet sheet = workbook.createSheet("new sheet");

  logger.debug("獲取所有學(xué)生");
  List<Student> studentList = (List<Student>) studentRepository.findAll();

  logger.debug("建立表頭");
  Row row = sheet.createRow(0);
  row.createCell(0).setCellValue("學(xué)號(hào)");
  row.createCell(1).setCellValue("姓名");
  row.createCell(2).setCellValue("手機(jī)號(hào)碼");

  logger.debug("將學(xué)生信息寫入對應(yīng)單元格");
  int i = 1;
  for (Student student : studentList) {
    row = sheet.createRow(i);
    row.createCell(0).setCellValue(student.getStudentNumber());
    row.createCell(1).setCellValue(student.getName());
    row.createCell(2).setCellValue(student.getPhoneNumber()); 
    i++;
  }

  OutputStream fos;
  try {
    fos = response.getOutputStream();
    response.reset();
    String fileName = "test";
    fileName = URLEncoder.encode(fileName, "utf8");
    response.setHeader("Content-disposition", "attachment;filename="+ fileName+".xlsx");

    response.setCharacterEncoding("UTF-8");
    response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");// 設(shè)置contentType為excel格式
    workbook.write(fos);
    fos.close();

  } catch (Exception e) {
      e.printStackTrace();
  }
}

前臺(tái)實(shí)現(xiàn)

在前臺(tái)調(diào)用的時(shí)候,也經(jīng)歷了多次失敗,google了很多篇文章,各種各樣的寫法都有,自己也是試了試,前臺(tái)后臺(tái)都對照做了很多嘗試,但基本都是有問題的。這里我值給出我最后選擇配套后臺(tái)的方法。

// 后臺(tái)導(dǎo)出路由
const exportUrl = '/api/student/batchExport';

// 創(chuàng)建a標(biāo)簽,并點(diǎn)擊
let a = document.createElement('a');
document.body.appendChild(a);
a.setAttribute('style', 'display:none');
a.setAttribute('href', exportUrl);
a.click();
URL.revokeObjectURL(exportUrl);

最后的實(shí)現(xiàn)還是一種比較簡單的方法,創(chuàng)建了一個(gè)a標(biāo)簽,然后隱式點(diǎn)擊。

注意到這里我沒有使用http請求,主要是他并不能觸發(fā)瀏覽器的下載,在發(fā)起請求后,并沒有正確的生成文件,具體是什么還不清楚。后面弄明白后我會(huì)再更新這篇文章。

升級(jí)

上面的形式,在導(dǎo)出所有的數(shù)據(jù)的時(shí)候是沒有問題的,但是如果我想帶一些參數(shù)呢?

另外,我們的項(xiàng)目是建立在nginx同源的基礎(chǔ)上,一旦出現(xiàn)跨域問題,前臺(tái)向后臺(tái)請求,瀏覽器是不會(huì)默認(rèn)攜帶Cookie的,每次請求都將會(huì)被看作是一個(gè)新的請求。

所以上面的解決辦法有所限制。

那么,還可以怎么寫呢?

file-saver

這里我將借助FileSaver來幫助我在前臺(tái)生成excel文件。

this.http.get('student/batchExport', { responseType: 'blob'})
  .subscribe(data => {
    let blob = new Blob([data], {type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8'});
    saveAs(blob, 'test.xlsx');
  });

用httpClient發(fā)起get請求,聲明:響應(yīng)類型為blob。

blob是一個(gè)用來存儲(chǔ)二進(jìn)制文件的對象。

然后創(chuàng)建一個(gè)blob對象,類型為excel格式。

最后,利用file-saver中的saveAs函數(shù),將blob對象生成文件名為'test.xlsx'的excel文件。

調(diào)整后臺(tái)

這里后臺(tái)大部分和前面的是一樣的,但是明眼人會(huì)發(fā)現(xiàn),前臺(tái)使用后面的方法后,下面的代碼就多余了:

String fileName = "test";
fileName = URLEncoder.encode(fileName, "utf8");
response.setHeader("Content-disposition", "attachment;filename="+ fileName+".xlsx");

response.setCharacterEncoding("UTF-8");
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");

是的,我們將這一部分交由前臺(tái)負(fù)責(zé),所以后臺(tái)對應(yīng)的這部分就可以刪除了,只使用response獲取輸出流就可以了:

OutputStream fos = response.getOutputStream();
workbook.write(fos);
fos.close();

好了,使用這種方法,我們就可以在發(fā)起http請求的時(shí)候,添加我們想要的參數(shù)了。

總結(jié)

我們在google的時(shí)候,很多時(shí)候,我們并不能一下子就找到我們想要的東西,但是并不是說這在做無用功,因?yàn)槲覀兺鶗?huì)在一些類似的文章中找到靈感。

所以,當(dāng)我們沒有直接找到我們想要的結(jié)果的時(shí)候,不妨大膽的做一些嘗試,因?yàn)槲覀儠?huì)在一次又一次失敗的嘗試中,慢慢的了解問題的原理到底是怎么回事。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • angular學(xué)習(xí)之從零搭建一個(gè)angular4.0項(xiàng)目

    angular學(xué)習(xí)之從零搭建一個(gè)angular4.0項(xiàng)目

    本篇文章主要介紹了從零搭建一個(gè)angular4.0項(xiàng)目,主要用到的工具angular4.0、angular-cli、npm(v3.10.8)、node(v6.2.0),有興趣的可以了解一下
    2017-07-07
  • AngularJS中實(shí)現(xiàn)動(dòng)畫效果的方法

    AngularJS中實(shí)現(xiàn)動(dòng)畫效果的方法

    本文主要介紹AngularJS 動(dòng)畫,這里對動(dòng)畫的資料詳細(xì)介紹并附有效果圖和代碼實(shí)例,有需要的小伙伴參考下
    2016-07-07
  • AngularJS自定義指令實(shí)現(xiàn)面包屑功能完整實(shí)例

    AngularJS自定義指令實(shí)現(xiàn)面包屑功能完整實(shí)例

    這篇文章主要介紹了AngularJS自定義指令實(shí)現(xiàn)面包屑功能,結(jié)合完整實(shí)例形式分析了AngularJS自定義指令的定義、調(diào)用及面包屑功能的具體實(shí)現(xiàn)技巧,需要的朋友可以參考下
    2017-05-05
  • 詳解angular應(yīng)用容器化部署

    詳解angular應(yīng)用容器化部署

    這篇文章主要介紹了詳解angular應(yīng)用容器化部署,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-08-08
  • Angular彈出模態(tài)框的兩種方式

    Angular彈出模態(tài)框的兩種方式

    這篇文章主要介紹了Angular彈出模態(tài)框的兩種方式,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2017-10-10
  • Angularjs整合微信UI(weui)

    Angularjs整合微信UI(weui)

    本文給大家推薦的是使用angularjs實(shí)現(xiàn)整合微信新推出的UI(weui)的全部過程,有相同需求的小伙伴可以參考下
    2016-03-03
  • Angular.JS中指令ng-if的注意事項(xiàng)小結(jié)

    Angular.JS中指令ng-if的注意事項(xiàng)小結(jié)

    這篇文章主要給大家分享了關(guān)于Angular.JS中指令ng-if的一點(diǎn)注意事項(xiàng),分享出來供大家參考學(xué)習(xí),文中介紹的還是相對來說比較詳細(xì),對大家具有一定的參考借鑒價(jià)值,需要的朋友們下面來一起看看吧。
    2017-06-06
  • angular實(shí)現(xiàn)商品篩選功能

    angular實(shí)現(xiàn)商品篩選功能

    這篇文章主要為大家詳細(xì)介紹了angular實(shí)現(xiàn)商品篩選功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-02-02
  • angular雙向綁定模擬探索

    angular雙向綁定模擬探索

    這篇文章主要和大家一起探索模擬angular的雙向綁定,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-12-12
  • 使用angularjs.foreach時(shí)return的問題解決

    使用angularjs.foreach時(shí)return的問題解決

    這篇文章主要介紹了使用angularjs.foreach時(shí)return的問題解決,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-09-09

最新評論

辽阳县| 澄迈县| 乌兰县| 绥棱县| 重庆市| 曲水县| 论坛| 安泽县| 黄骅市| 台中市| 石柱| 科尔| 那坡县| 镇江市| 陈巴尔虎旗| 额尔古纳市| 阜阳市| 时尚| 桐梓县| 建湖县| 林西县| 普定县| 镶黄旗| 内黄县| 特克斯县| 交城县| 信宜市| 香港| 沙雅县| 益阳市| 阿鲁科尔沁旗| 平安县| 微山县| 江川县| 吉林省| 武城县| 华蓥市| 台南市| 金平| 吴江市| 德阳市|