一、概述
在工作過程中,都會遇到這樣一個需求,就是將相關的數據列表導出成excel,這裏寫成通用的導出Excel的工具。
二、項目實現
1、構建pom.xml
我的工程是利用Maven來構建的,這裏僅給出最核心的包
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-scratchpad</artifactId>
<version>3.11-beta2</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.11-beta2</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-schemas</artifactId>
<version>3.11-beta2</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-excelant</artifactId>
<version>3.11-beta2</version>
</dependency>
<!--jxi導出-->
<dependency>
<groupId>net.sourceforge.jexcelapi</groupId>
<artifactId>jxl</artifactId>
<version>2.6.12</version>
</dependency>
2、編寫PoiUtils類
這個類是整個工具的核心,它實現了Excel文件的導出功能,具體代碼如下:
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.apache.poi.xssf.usermodel.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.Map;
/**
* @Auther: admin
* @Date: 2018/10/4 12:54
* @Description: 導出excel 2003和2007通用工具類
*/
public class ExcelUtils {
/**
* 2003 導出Excel
*
* @param fileName 文件名
* @param titles 導出excel標題
* @param data 需要顯示的數據集合
* @param hashMapKeys 導出excel顯示的列頭(對應pojo裏面的屬性)
* @Description: 2003版本最大支持65536行
*/
public static void exportExcel2003(String fileName, String[] titles, String[] hashMapKeys,
List<Map> data, HttpServletResponse response) throws IOException{
// 1.創建工作簿
HSSFWorkbook workbook = new HSSFWorkbook();
// 2.在workbook中添加一個sheet,對應Excel文件中的fileName
HSSFSheet sheet = workbook.createSheet(fileName);
//樣式1:定義列寬
// for (int i = 0; i < 12; i++) {
// sheet.setColumnWidth(i, 4000);
// }
//樣式2:定義第一行單元格樣式
HSSFCellStyle cellStyle = workbook.createCellStyle();
// 設置字體
HSSFFont font = workbook.createFont();
font.setFontName("微軟雅黑");
font.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL);
// 字體大小
font.setFontHeightInPoints((short) 12);
cellStyle.setFont(font);
//設置單元格居中
cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);// 左右居中
cellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 上下居中
//樣式3:定義標題欄單元格樣式
HSSFCellStyle cellStyle1 = workbook.createCellStyle();
//設置字體,第一行
HSSFFont font1 = workbook.createFont();
// font1.setFontName("微軟雅黑");
// font1.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL);
// // 字體大小
// font1.setFontHeightInPoints((short) 12);
// cellStyle1.setFont(font1);
//設置單元格居中
cellStyle1.setAlignment(HSSFCellStyle.ALIGN_CENTER);// 左右居中
cellStyle1.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 上下居中
//設置邊框
cellStyle1.setBorderBottom(HSSFCellStyle.BORDER_THIN); //下邊框
cellStyle1.setBorderLeft(HSSFCellStyle.BORDER_THIN); //左邊框
cellStyle1.setBorderTop(HSSFColor.BLACK.index); //上邊框
cellStyle1.setBorderRight(HSSFColor.WHITE.index); //右邊框
//設置自動換行
cellStyle1.setWrapText(true);
//樣式4:定義內容欄單元格樣式
HSSFCellStyle cellStyle2 = workbook.createCellStyle();
HSSFFont font2 = workbook.createFont();
font2.setFontName("宋體");
font2.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL);
// 字體大小
font2.setFontHeightInPoints((short) 12);
cellStyle2.setFont(font2);
//設置單元格內容居左和居上
cellStyle2.setAlignment(HSSFCellStyle.ALIGN_LEFT);
cellStyle2.setVerticalAlignment(HSSFCellStyle.VERTICAL_TOP);
//設置邊框
cellStyle2.setBorderBottom(HSSFCellStyle.BORDER_THIN); //下邊框
cellStyle2.setBorderLeft(HSSFCellStyle.BORDER_THIN); //左邊框
cellStyle2.setBorderTop(HSSFColor.BLACK.index); //上邊框
cellStyle2.setBorderRight(HSSFColor.WHITE.index); //右邊框
//設置自動換行
cellStyle2.setWrapText(true);
//樣式5:定義尾部欄註釋單元格樣式
HSSFCellStyle cellStyle3 = workbook.createCellStyle();
HSSFFont font3 = workbook.createFont();
font3.setFontName("楷體");
font3.setFontHeightInPoints((short) 12);// 字體大小
font3.setColor(HSSFColor.RED.index);//設置紅色
cellStyle3.setFont(font3);
//樣式6:合併第一行單元格
// Region region1 = new Region(0, (short) 0, 0, (short) (titles.length - 1));
// sheet.addMergedRegion(region1);
//2.創建頂行
// HSSFRow rowhead = sheet.createRow(0);
// rowhead.setHeight((short) 700);
// HSSFCell cellhead = rowhead.createCell(0);
// cellhead.setCellValue(fileName.substring(0, fileName.lastIndexOf(".")));
// cellhead.setCellStyle(cellStyle);
//3.創建標題行
HSSFRow row = sheet.createRow(0);
// row.setHeight((short) 550);
for (int i = 0; i < titles.length; i++) {
HSSFCell cell = row.createCell(i);
cell.setCellValue(titles[i]);
cell.setCellStyle(cellStyle1);
}
//4.創建內容
for (int i = 0; i < data.size(); i++) {
HSSFRow rowi = sheet.createRow(i + 1);
// row.setHeight((short) 550);
for (int j = 0; j < hashMapKeys.length; j++) {
HSSFCell celli = rowi.createCell(j);
celli.setCellStyle(cellStyle2);
if (data.get(i).get(hashMapKeys[j]) == null) {
celli.setCellValue("/");
} else {
celli.setCellValue(data.get(i).get(hashMapKeys[j]).toString());
}
}
}
//5.創建尾部行
HSSFRow rowtail = sheet.createRow(data.size() + 4);
SimpleDateFormat formater = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
HSSFCell celltaill = rowtail.createCell(0);
// celltaill.setCellValue("文檔創建時間" + formater.format(new Date()));
celltaill.setCellStyle(cellStyle3);
//6.輸出到Excel表格
//設置響應頭
if (fileName.endsWith("xlsx")) {
// response.setContentType("application/vnd.ms-excel");
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
} else {
response.setContentType("application/vnd.ms-excel");
}
response.setHeader("content-disposition", "attachment; fileName=" + URLEncoder.encode(fileName, "UTF-8"));
OutputStream out = response.getOutputStream();
workbook.write(out);
out.flush();
out.close();
}
2007Excel工具類
/**
* @param fileName 表格的名稱
* @param titles 標題名稱(表格第一行中文標題)
* @param data 需要顯示的數據集合
* @param hashMapKeys 導出excel顯示的列頭(對應pojo裏面的屬性)
* @Description: 2007導出excel通用工具類
*/
public static void exportExcel2007(String fileName, String[] titles, String[] hashMapKeys, List<Map> data, HttpServletResponse response) {
// 聲明一個工作薄
XSSFWorkbook workbook = new XSSFWorkbook();
// 生成一個表格
XSSFSheet sheet = workbook.createSheet(fileName);
// 設置表格默認列寬度爲15個字節
sheet.setDefaultColumnWidth(15);
// 生成表格中非標題欄的樣式
XSSFCellStyle style = workbook.createCellStyle();
// 設置這些樣式
style.setFillForegroundColor(HSSFColor.WHITE.index);//背景色
style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
style.setBorderBottom(BorderStyle.THIN);
style.setBorderLeft(BorderStyle.THIN);
style.setBorderRight(BorderStyle.THIN);
style.setBorderTop(BorderStyle.THIN);
style.setAlignment(HorizontalAlignment.CENTER);
// 生成表格中非標題欄的字體
XSSFFont font = workbook.createFont();
font.setColor(HSSFColor.BLACK.index);
font.setFontHeightInPoints((short) 12);
font.setBold(true);
// 把字體應用到當前的樣式
style.setFont(font);
// 設置表格標題欄的樣式
XSSFCellStyle titleStyle = workbook.createCellStyle();
titleStyle.setFillForegroundColor(HSSFColor.BLUE_GREY.index);
titleStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
titleStyle.setBorderBottom(BorderStyle.THIN);
titleStyle.setBorderLeft(BorderStyle.THIN);
titleStyle.setBorderRight(BorderStyle.THIN);
titleStyle.setBorderTop(BorderStyle.THIN);
titleStyle.setAlignment(HorizontalAlignment.CENTER);
titleStyle.setVerticalAlignment(VerticalAlignment.CENTER);
// 設置標題欄字體
XSSFFont titleFont = workbook.createFont();
titleFont.setColor(HSSFColor.WHITE.index);
titleFont.setFontHeightInPoints((short) 12);
titleFont.setBold(true);
// 把字體應用到當前的樣式
titleStyle.setFont(titleFont);
// 產生表格標題行
XSSFRow row = sheet.createRow(0);
for (short i = 0; i < titles.length; i++) {
XSSFCell cell = row.createCell(i);
cell.setCellStyle(titleStyle);
XSSFRichTextString text = new XSSFRichTextString(titles[i]);
cell.setCellValue(text);
}
//4.遍歷集合數據,產生數據行
for (int i = 0; i < data.size(); i++) {
XSSFRow rowi = sheet.createRow(i + 1);
// row.setHeight((short) 550);
for (int j = 0; j < hashMapKeys.length; j++) {
XSSFCell celli = rowi.createCell(j);
celli.setCellStyle(style);
if (data.get(i).get(hashMapKeys[j]) == null) {
// celli.setCellValue("/");
} else {
celli.setCellValue(data.get(i).get(hashMapKeys[j]).toString());
}
}
}
//5.創建尾部行
XSSFRow rowtail = sheet.createRow(data.size() + 4);
SimpleDateFormat formater = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
XSSFCell celltaill = rowtail.createCell(0);
// celltaill.setCellValue("文檔創建時間" + formater.format(new Date()));
celltaill.setCellStyle(style);
//6.輸出到Excel表格
//設置響應頭
if (fileName.endsWith("xlsx")) {
//response.setContentType("application/vnd.ms-excel");
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
} else {
response.setContentType("application/vnd.ms-excel");
}
try {
response.setHeader("content-disposition", "attachment; fileName=" + URLEncoder.encode(fileName, "UTF-8"));
OutputStream out = response.getOutputStream();
workbook.write(out);
out.flush();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
2007動態導出Excel工具類
/**
* @param : response
* @param : data 數據源
* @param : filename 文件名,如20150703.xls
* @param : columns 列名稱集合,例如(姓名,年齡)
* @return : void
* @date : 2018/12/11 20:52
* @Description: 2007動態導出excel工具類
*/
public static void publicExportExcel2007(HttpServletResponse response, List<Map<String, Object>> data, String filename, List<String> columns) {
// 聲明一個工作薄
XSSFWorkbook workbook = new XSSFWorkbook();
// 生成一個表格
XSSFSheet sheet = workbook.createSheet(filename);
// 設置表格默認列寬度爲15個字節
sheet.setDefaultColumnWidth(15);
// 生成表格中非標題欄的樣式
XSSFCellStyle style = workbook.createCellStyle();
// 設置這些樣式
style.setFillForegroundColor(HSSFColor.WHITE.index);// 背景色
style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
style.setBorderBottom(BorderStyle.THIN);
style.setBorderLeft(BorderStyle.THIN);
style.setBorderRight(BorderStyle.THIN);
style.setBorderTop(BorderStyle.THIN);
style.setAlignment(HorizontalAlignment.CENTER);
// 生成表格中非標題欄的字體
XSSFFont font = workbook.createFont();
font.setColor(HSSFColor.BLACK.index);
font.setFontHeightInPoints((short) 12);
font.setBold(true);
// 把字體應用到當前的樣式
style.setFont(font);
// 設置表格標題欄的樣式
XSSFCellStyle titleStyle = workbook.createCellStyle();
titleStyle.setFillForegroundColor(HSSFColor.BLUE_GREY.index);
titleStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
titleStyle.setBorderBottom(BorderStyle.THIN);
titleStyle.setBorderLeft(BorderStyle.THIN);
titleStyle.setBorderRight(BorderStyle.THIN);
titleStyle.setBorderTop(BorderStyle.THIN);
titleStyle.setAlignment(HorizontalAlignment.CENTER);
titleStyle.setVerticalAlignment(VerticalAlignment.CENTER);
// 設置標題欄字體
XSSFFont titleFont = workbook.createFont();
titleFont.setColor(HSSFColor.WHITE.index);
titleFont.setFontHeightInPoints((short) 12);
titleFont.setBold(true);
// 把字體應用到當前的樣式
titleStyle.setFont(titleFont);
// 產生表格標題行
XSSFRow row = sheet.createRow(0);
if (columns != null && columns.size() > 0) {
for (short i = 0; i < columns.size(); i++) {
XSSFCell cell = row.createCell(i);
cell.setCellStyle(titleStyle);
XSSFRichTextString text = new XSSFRichTextString(columns.get(i));
cell.setCellValue(text);
}
}
// 4.遍歷集合數據,產生數據行
if (data != null && data.size() > 0) {
for (int i = 0; i < data.size(); i++) {
XSSFRow rowi = sheet.createRow(i + 1);
for (int j = 0; j < columns.size(); j++) {
XSSFCell celli = rowi.createCell(j);
celli.setCellStyle(style);
if (data.get(i).get(columns.get(j)) == "") {
// celli.setCellValue("/");
} else {
celli.setCellValue(data.get(i).get(columns.get(j)).toString());
}
}
}
}
// 5.輸出Excel表格,設置響應頭
if (filename.endsWith("xlsx")) {
response.setContentType("application/msexcel");
} else {
response.setContentType("application/vnd.ms-excel");
}
OutputStream out = null;
try {
response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8"));
out = response.getOutputStream();
workbook.write(out);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (out != null) {
try {
out.flush();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* @param : [result, map]
* @return : java.util.List<java.util.Map<java.lang.String,java.lang.Object>>
* @date : 2018/12/11 20:55
* @exception:
* @Description: 2007動態導出excel工具類數據封裝
*/
public static List<Map<String, Object>> assembelDats(List<Map> result, LinkedHashMap map) {
// 整合內容
List<Map<String, Object>> daList = new ArrayList<>();
for (int i = 0; i < result.size(); i++) {
Map<String, Object> tempMap = new HashMap();
for (Object key : result.get(i).keySet()) {
tempMap.put((String) map.get(key), result.get(i).get(key));
}
daList.add(tempMap);
}
return daList;
}
三,Controller
/**
* @param : [map, response]
* @return : void
* @date : 2018/10/26 20:25
* @exception:
* @Description: ExcelUtils通用導出測試
*/
@RequestMapping("/export.do")
public void export( HttpServletResponse response) throws Exception {
//獲取數據
String[] titles = new String[]{"名稱", "性別", "年齡", "學校", "班級"};
String[] hashMapKeys = new String[]{"name", "sex", "age", "school", "grade"};
String fileName = "報表.xlsx";
List<Map> data = new ArrayList<>();
//使用LinkedHashMap保證有序,即標題和數據對應上
Map<String, Object> maps = new LinkedHashMap();
maps.put("name", "張三");
maps.put("sex", "男");
maps.put("age", 23);
maps.put("school", "清華");
maps.put("grade", "51155");
data.add(maps);
try {
ExcelUtils.exportExcel2003(fileName,titles,hashMapKeys,data,response);
response.getOutputStream().close();
} catch (IOException e) {
e.printStackTrace();
}
}
4.效果如下