java的(SXSSF)EasyExcel阿里開源excel導出和XSSF導出簡單示例


一、EasyExcel阿里開源excel導出(SXSSF)

參考鏈接:EasyExcel阿里開源excel導出

 1、建立映射到excel文件的映射類,然后get和set

import com.alibaba.excel.annotation.ExcelProperty;

public class DownloadAjgl {
 
         
    @HeadStyle(horizontalAlignment = HorizontalAlignment.CENTER)//表頭樣式
@ContentStyle(horizontalAlignment = HorizontalAlignment.CENTER)//內容樣式
    @ColumnWidth(20)//表頭寬度
@ExcelProperty(value
= "賬套編碼", index = 0)//可以只寫列名,不寫index會默認按照這個類的屬性順序來寫到excel private String ztCode; @ExcelProperty(value = {"賬套名稱(一級表頭)","二級表頭","三級表頭"}, index = 1) private String ztName; @ExcelProperty("年份") private int year; @ExcelProperty("部門編碼") private String bmCode; @ExcelProperty("部門名稱") private String bmName; public String getZtCode() { return ztCode; } public void setZtCode(String ztCode) { this.ztCode = ztCode; } public String getZtName() { return ztName; } public void setZtName(String ztName) { this.ztName = ztName; } public int getYear() { return year; } public void setYear(int year) { this.year = year; } public String getBmCode() { return bmCode; } public void setBmCode(String bmCode) { this.bmCode = bmCode; } public String getBmName() { return bmName; } public void setBmName(String bmName) { this.bmName = bmName; } }

2、controller里面

@GetMapping("/exportExcel")
    public void exportExcel(@RequestParam(value = "ztId") int ztId, HttpServletResponse response) throws IOException {

        List<Ajgl> ajglList =ajglRepository.findAllByZtId(ztId);
       
      
            response.setHeader("Content-Disposition", "attachment; filename=Ajgl.xlsx");
            // 響應類型,編碼
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");

 EasyExcel.write(response.getOutputStream(), DownloadAjgl.class).sheet("案卷導出模板").doWrite(data(ajglList));//data是把數據封裝成映射類的自定義方法
            

        
    }

3、前端跟下面  “二、XSSF導出。”一樣

4、這點比較重要,如果不做的話會報錯
Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is com.alibaba.excel.exception.ExcelGenerateException: Can not close IO.] with root
cause
java.net.SocketTimeoutException: null

(我公司用window10的子系統ubuntu編譯運行的)

需要在ubuntu運行幾個命令

$ sudo apt-get update
$ sudo apt-get upgrade
$ sudo apt-get install build-essential git unzip zip curl wget vim fontconfig ttf-dejavu fonts-dejavu

主要是第三個命令,只要第三個命令運行成功之后就不會報錯了。

二、XSSF導出。

java代碼

@GetMapping("/exportExcel")
    public void exportExcel(@RequestParam(value = "ztId") int ztId,
                            HttpServletResponse response) throws IOException {
   
    XSSFWorkbook xssfWorkbook = new XSSFWorkbook();
    XSSFSheet sheet = xssfWorkbook.createSheet("測試");
    XSSFRow row0 = sheet.createRow(0);
    row0.createCell(0).setCellValue("編碼");
    row0.createCell(1).setCellValue("名稱");
    List<Ce> ces = ceRepository.findAllByZtId(ztId);
    int num=0;
    for(var it : ces){
      num++;
      XSSFRow row = sheet.createRow(num);
      row.createCell(0).setCellValue(it.getCode());
      row.createCell(1).setCellValue(it.getName());
    }
   response.setHeader("Content-Disposition", "attachment; filename=Cs.xlsx");
     // 響應類型,編碼
    response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
    // 將指定的字節寫入此輸出流
    xssfWorkbook.write(response.getOutputStream());
    response.flushBuffer();
    xssfWorkbook.close();
}

在自定義的request.js中導出download

export const download = (path, name) => {
  const data = options('GET');
  fetch(backend(path), data)
    .then(response => response.blob())
    .then(blob => {
      var url = window.URL.createObjectURL(blob);
      var a = document.createElement('a');
      a.href = url;
      a.download = name;
      document.body.appendChild(a); // for firefox
      a.click();
      a.remove();
    });
};

 

前端代碼:

<el-button type="warning" size="small" @click="exportExcel">導出</el-button>

.........

<script>
import {
  download as httpDownload,//封裝好的請求
  upload as uploadHeaders,
  get as httpGet,
  delete_ as httpDelete,
  PAGE_SIZE
} from "@/request";
.............

  methods: {
    exportExcel() {
       httpDownload(`/exportExcel/?ztId=${this.ztId}`, "Ajgl.xlsx");
    }
}
.....

 三、HSSFworkbook、XSSFworkbook、SXSSFworkbook區別總結

參考連接:HSSFworkbook,XSSFworkbook,SXSSFworkbook區別總結

1、HSSFWorkbook:是操作Excel2003以前(包括2003)的版本,擴展名是.xls;

poi導出excel最常用的方式;但是此種方式的局限就是導出的行數至多為65535行,超出65536條后系統就會報錯。此方式因為行數不足七萬行所以一般不會發生內存不足的情況(OOM:OutOfMemoryError)。

2、XSSFWorkbook:是操作Excel2007后的版本,擴展名是.xlsx;

這種形式的出現是為了突破HSSFWorkbook的65535行局限。其對應的是excel2007(1048576行,16384列)擴展名為“.xlsx”,最多可以導出104萬行,不過這樣就伴隨着一個問題---OOM內存溢出,原因是你所創建的book sheet row cell等此時是存在內存的並沒有持久化。

3、SXSSFWorkbook:是操作Excel2007后的版本,擴展名是.xlsx;

從POI 3.8版本開始,提供了一種基於XSSF的低內存占用的SXSSF方式。對於大型excel文件的創建,一個關鍵問題就是,要確保不會內存溢出。其實,就算生成很小的excel(比如幾Mb),它用掉的內存是遠大於excel文件實際的size的。如果單元格還有各種格式(比如,加粗,背景標紅之類的),那它占用的內存就更多了。對於大型excel的創建且不會內存溢出的,就只有SXSSFWorkbook了。它的原理很簡單,用硬盤空間換內存(就像hash map用空間換時間一樣)。

 

SXSSFWorkbook是streaming版本的XSSFWorkbook,它只會保存最新的excel rows在內存里供查看,在此之前的excel rows都會被寫入到硬盤里(Windows電腦的話,是寫入到C盤根目錄下的temp文件夾)。被寫入到硬盤里的rows是不可見的/不可訪問的。只有還保存在內存里的才可以被訪問到。

SXSSF與XSSF的對比:

a. 在一個時間點上,只可以訪問一定數量的數據

b. 不再支持Sheet.clone()

c. 不再支持公式的求值

d. 在使用Excel模板下載數據時將不能動態改變表頭,因為這種方式已經提前把excel寫到硬盤的了就不能再改了

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

(無關)(額外)請求導出示例:

import {
  get as getToken
} from './token';

export const PAGE_SIZE = 20;

export const backend = (u) => `${process.env.VUE_APP_BASE_API}${u}`;

export const upload = () => {
  return {
    'Authorization': `Bearer ${getToken()}`
  }
}

export const options = (method) => {
  return {
    credentials: 'include',
    headers: {
      'Authorization': `Bearer ${getToken()}`,
      'Content-Type': 'application/json; charset=utf-8'
    },
    method
  };
};

export const get = (path) => fetch(backend(path), options('GET')).then((res) => res.status === 200 ?
  res.json() :
  res.json().then(err => {
    throw err;
  }));

export const delete_ = (path) => fetch(backend(path), options('DELETE')).then((res) => res.status === 200 ?
  res.json() :
  res.json().then(err => {
    throw err;
  }));

// https://github.github.io/fetch/#options
export const post = (path, body) => {
  const data = options('POST');
  data.body = JSON.stringify(body);
  return fetch(backend(path), data).then((res) => res.status === 200 ?
    res.json() :
    res.json().then(err => {
      throw err;
    }));
};

export const patch = (path, body) => {
  const data = options('PATCH');
  data.body = JSON.stringify(body);
  return fetch(backend(path), data).then((res) => res.status === 200 ?
    res.json() :
    res.json().then(err => {
      throw err;
    }));
};

export const put = (path, body) => {
  const data = options('PUT');
  data.body = JSON.stringify(body);
  return fetch(backend(path), data).then((res) => res.status === 200 ?
    res.json() :
    res.json().then(err => {
      throw err;
    }));
};


export const download = (path, name) => {
  const data = options('GET');
  fetch(backend(path), data)
    .then(response => response.blob())
    .then(blob => {
      var url = window.URL.createObjectURL(blob);
      var a = document.createElement('a');
      a.href = url;
      a.download = name;
      document.body.appendChild(a); // for firefox
      a.click();
      a.remove();
    });
};

使用例子:

.........
<script>
import {
  download as httpDownload,
  upload as uploadHeaders,
  get as httpGet,
  delete_ as httpDelete,
  PAGE_SIZE
} from "@/request";
...................

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM