可以直接復制拿來用喲,(#^.^#)
目錄
一、pom.xml依賴
二、代碼大致流程是這樣的
三、后端工具類
四、基于vue,使用axios呼叫后端介面,實作下載檔案的方法
五、看效果
一、pom.xml依賴
<!--poi檔案處理-->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.17</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.17</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-schemas</artifactId>
<version>3.17</version>
</dependency>
二、代碼大致流程是這樣的
- 創建Excle檔案物件
- 根據創建的Excle檔案物件創建Sheet頁
- 在根據sheet頁設定里面的內容
- 把檔案流物件通過HttpServletResponse回傳
- 前端模擬a標簽,獲取流資料,達到下載檔案功能,
三、后端工具類
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.apache.poi.ss.util.CellRangeAddress;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.List;
/**
* @program: zy
* @description: Excel工具類
* @author: zhang yi
* @create: 2020-08-28 11:08
*/
public class ExcelUtil {
/**
* Excel表格匯出模板類
* @param response response物件,回傳的是流資料
* @param list 資料源物件,這里就是最后的串列
* @param filename 自己定義的檔案名,(前后端分離時,無法回傳正確的檔案名,這里的檔案名一般是前端寫好傳遞過來的)
* @throws IOException
*/
public static void exportExcelUtil(HttpServletResponse response, List<LinkedHashMap<String,Object>> list, String filename) throws IOException {
/**創建Excel檔案*/
HSSFWorkbook sxssfWorkbook = new HSSFWorkbook ();
/**創建sheet頁*/
HSSFSheet sheet = sxssfWorkbook.createSheet(filename);
/**設定每一列單元格的寬度,因為一個單元格寬度定了,那么下面多有的單元格高度都確定了,所以這個方法是sheet的*/
int z=0;
sheet.setColumnWidth((short)z++, 10*256);//第一列
sheet.setColumnWidth((short)z++, 12*256);//第二列
sheet.setColumnWidth((short)z++, 10*256);//第三列
sheet.setColumnWidth((short)z++, 13*256);//第四列
/**有得時候你想設定統一單元格的高度,就用這個方法*/
// sheet.setDefaultRowHeight((short)400);
/**自適應列寬(不合適,資料量大會卡,1000條2分鐘)*/
// sheet.autoSizeColumn(1, true);//設定第一列單元格寬度自適應
/**設定樣式,獨立的一個CellStyle物件,在后面可以把這個CellStyle物件添加到單元格中,就實作了單元格樣式*/
CellStyle style = sxssfWorkbook.createCellStyle();//創建CellStyle物件
style.setAlignment(HorizontalAlignment.CENTER);//水平居中
style.setVerticalAlignment(VerticalAlignment.CENTER);//垂直居中
/**字體樣式*/
HSSFFont font = sxssfWorkbook.createFont();//內容樣式
font.setFontHeightInPoints((short)15);//字體大小
font.setFontName("Courier New");//字體
// font.setItalic(true);//是否傾斜
font.setBold(true);//是否加粗
/**將字體樣式加入CellStyle物件中*/
style.setFont(font);
/**樣式2(按照同樣的方法,可以設定多個CellStyle樣式物件,這樣你哪里需要用到這個樣式,就直接添加進來,這些樣式可以封裝起來,便于單獨呼叫)*/
CellStyle style2 = sxssfWorkbook.createCellStyle();
// style2.setAlignment(HorizontalAlignment.CENTER);//水平居中
// style2.setVerticalAlignment(VerticalAlignment.CENTER);//垂直居中
/**字體樣式*/
HSSFFont font2 = sxssfWorkbook.createFont();//內容樣式
font2.setColor(HSSFFont.COLOR_RED);
font2.setBold(false);//是否加粗
/**將字體樣式加入Style中*/
style2.setFont(font2);
/**合并單元格,四個引數依次為:起始行,終止行,起始列,終止列*/
CellRangeAddress region1 = new CellRangeAddress(0, 1, (short) 0, (short) 8);
/**把合并后的單元格添加進sheet物件*/
sheet.addMergedRegion(region1);
/**創建 行 物件*/
HSSFRow headTitle = sheet.createRow(0);//起始行數為0
headTitle.setHeightInPoints(25);//高度
/**創建 列 物件*/
HSSFCell cell = headTitle.createCell(0);//起始列數為0
/**設定單元格的內容*/
cell.setCellValue(filename);
/**設定設定樣式*/
cell.setCellStyle(style);
String[] head={"標題1","標題2","標題3","標題4","標題5"};//標題集合
/**繼續創建 行 物件*/
HSSFRow headRow = sheet.createRow(2);//起始行數為2,因為之前我們合并單元格占用了2行,所以這里從第三行開始,索引就是2
/**繼續創建 列 物件*/
for (int i = 0; i < head.length; i++) {
headRow.createCell(i).setCellValue(head[i]);//把標題添加到列里面
}
/**前面的標題渲染好了后,這里就開始渲染實際資料了,資料一般放在List集合中,進行遍歷渲染*/
for (LinkedHashMap<String, Object> a : list) {
int j=0;
/**創建 行 物件*/
HSSFRow dataRow = sheet.createRow(sheet.getLastRowNum() + 1);//起始位置就是當前sheet最后一行+1開始
/**根據行物件,創建列物件*/
HSSFCell cell1 = dataRow.createCell(j++);
cell1.setCellValue("我是內容1");
cell1.setCellStyle(style2);//把之前創建的樣式物件CellStyle添加到這個單元格中,這樣單元格就有了樣式
dataRow.createCell(j++).setCellValue("我是內容1");
dataRow.createCell(j++).setCellValue("我是內容1");
dataRow.createCell(j++).setCellValue("我是內容1");
dataRow.createCell(j++).setCellValue("我是內容1");
}
/****************Excle表格渲染完成后,開始回傳流資料*****************/
/**設定頭資訊*/
response.setCharacterEncoding("UTF-8");
response.setContentType("application/vnd.ms-excel");
/**一定要設定成xlsx格式*/
response.setHeader("Content-disposition", "attachment;filename=" + filename);
/**創建一個輸出流*/
ServletOutputStream outputStream = response.getOutputStream();
/**寫入資料*/
sxssfWorkbook.write(outputStream);
/**關閉流*/
outputStream.close();
sxssfWorkbook.close();
System.out.println("匯出完成");
}
}
注意:spring mvc中的注解必須是@Controller,不能添加@ResponseBody,因為這里回傳的是流,而不是JSON
四、基于vue,使用axios呼叫后端介面,實作下載檔案的方法
/**
* 匯出Excle通用
* @param filename 檔案名,前后端分離后,后端回傳的是流資料,檔案名會失效,所以需要前端指定
* @param res 后端回傳的流資料,直接把axios回傳的流資料塞進來
*/
exportExcel(filename,res){
const link = document.createElement('a');
let blob = new Blob([res.data], {type: 'application/vnd.ms-excel'});
link.style.display = 'none';
link.href = URL.createObjectURL(blob);
let num = '';
for (let i = 0; i < 10; i++) {
num += Math.ceil(Math.random() * 10)
}
link.setAttribute('download', filename + '.xls');
document.body.appendChild(link);
link.click();
document.body.removeChild(link)
}
五、看效果
當通過后端呼叫工具類后,會回傳一個檔案流輸入,如下
前端通過axios呼叫介面,獲取到流資料后,塞入到工具類中的變數里,就可以下載檔案啦,
具體效果參考如下:
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/33131.html
標籤:其他


