package com.meatball.utils;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author 清风怎不知意
* @Title: ExcelExportUtils
* @Package com.meatball.utils
* @Description: TODO(Excel导出工具)
* @date 2018/8/23 9:10
*/
public class ExcelExportUtils {
private static final Logger log = LoggerFactory.getLogger(ExcelImportUtils.class);
//表单标题
private String title;
private Workbook workbook;
private SXSSFSheet sheet;
//表格样式
private Map,CellStyle> styles;
//头部标题
private static List headList;
//获取数据的方法
private List methodList;
//需要导出的内容
private List contents;
//每一列数据最长的字段长度
private List width;
/**
* @Description: TODO(导出Excel)
* @param response
* @param headerList 表头标题列表,按实际顺序传入 eg:["title","name","age","sex"]
* @param methodList 表格对应内容请求方法列表,按表头顺序传入 eg:["标题","姓名","年龄","性别"]
* @param contentList 数据列表,最大支持1000000行
* @param title 表格标题
* @throws
*/
public void exportExcel(HttpServletResponse response, List headerList, List methodList,List contentList,String title){
if(contentList==null || contentList.size()<=0){
try {
response.sendError(500,"没有数据!");
} catch (IOException e) {
e.printStackTrace();
}
return;
}
if(contentList.size()>1000000){
try {
response.sendError(500,"数据量过大,单次导出量不得超过一百万条!");
} catch (IOException e) {
e.printStackTrace();
}
return;
}
this.contents = contentList;
this.headList = headerList;
this.methodList = methodList;
this.title = title;
//初始化表格
initSheet();
//初始化表头
creatSheetHead();
//填充数据
try {
fillSheetData();
} catch (IllegalAccessException e) {
//私有属性或方法不能访问
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
//方法名有错
e.printStackTrace();
} catch (InvocationTargetException e) {
//类实例化失败
e.printStackTrace();
}
//调整列宽
for(int i= 0 ;i;i++){
sheet.setColumnWidth(i,(width.get(i)+4)*256);
}
//导出数据
try {
export(response);
} catch (IOException e) {
//导出失败
e.printStackTrace();
}
}
/**
* @Description: TODO(初始化表单)
* @param
* @throws
*/
private void initSheet(){
//内存写入10000条数据,其余写入磁盘,防止内存溢出
workbook = new SXSSFWorkbook(10000);
styles = createStyles(workbook);
sheet = (SXSSFSheet) workbook.createSheet(title);
sheet.setDisplayGridlines(false);
sheet.setPrintGridlines(false);
sheet.setFitToPage(true);
sheet.setHorizontallyCenter(true);
sheet.createFreezePane(0, 1, 0, 1);
PrintSetup printSetup = sheet.getPrintSetup();
printSetup.setLandscape(true);
}
/**
* @Description: TODO(创建表格样式)
* @param wb
* @throws
*/
private Map,CellStyle> createStyles(Workbook wb){
, CellStyle> styles = new HashMap, CellStyle>();
Font headFont = wb.createFont();
headFont.setFontHeightInPoints((short) 12);
headFont.setColor(IndexedColors.BLACK.getIndex());
Font cellFont = wb.createFont();
cellFont.setFontHeightInPoints((short) 10);
cellFont.setColor(IndexedColors.BLACK.getIndex());
CellStyle headCellStyle = createBorderedStyle(wb);
headCellStyle.setWrapText(true);
headCellStyle.setAlignment(HorizontalAlignment.CENTER);
headCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
headCellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT
.getIndex());
headCellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
headCellStyle.setFont(cellFont);
styles.put("head", headCellStyle);
CellStyle headTitleStyle = createBorderedStyle(wb);
headTitleStyle.setWrapText(true);
headTitleStyle.setAlignment(HorizontalAlignment.CENTER);
headTitleStyle.setVerticalAlignment(VerticalAlignment.CENTER);
headTitleStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT
.getIndex());
headTitleStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
headTitleStyle.setFont(headFont);
styles.put("headTitle", headTitleStyle);
CellStyle cellStyle = createBorderedStyle(wb);
cellStyle.setWrapText(true);
cellStyle.setAlignment(HorizontalAlignment.CENTER);
cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
cellStyle.setFont(cellFont);
styles.put("cell", cellStyle);
CellStyle urlStyle = createBorderedStyle(wb);
Font urlFont = wb.createFont();
urlFont.setColor(IndexedColors.BLUE.getIndex());
urlFont.setUnderline(HSSFFont.U_SINGLE);
urlStyle.setFont(urlFont);
cellStyle.setWrapText(true);
cellStyle.setAlignment(HorizontalAlignment.CENTER);
cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
styles.put("urlStyle", urlStyle);
return styles;
}
/**
* @Description: TODO(创建边框样式)
* @param wb
* @throws
*/
private CellStyle createBorderedStyle(Workbook wb) {
CellStyle style = wb.createCellStyle();
style.setBorderRight(BorderStyle.THIN);
style.setRightBorderColor(IndexedColors.BLACK.getIndex());
style.setBorderBottom(BorderStyle.THIN);
style.setBottomBorderColor(IndexedColors.BLACK.getIndex());
style.setBorderLeft(BorderStyle.THIN);
style.setLeftBorderColor(IndexedColors.BLACK.getIndex());
style.setBorderTop(BorderStyle.THIN);
style.setTopBorderColor(IndexedColors.BLACK.getIndex());
return style;
}
/**
* @Description: TODO(创建表头)
* @param
* @throws
*/
private void creatSheetHead(){
Row headRow = sheet.createRow(0);
CellStyle headCellStyle = styles.get("head");
for(int i = 0;i<headList.size();i++){
Cell headCell = headRow.createCell(i);
headCell.setCellValue(headList.get(i));
headCell.setCellStyle(headCellStyle);
}
}
/**
* @Description: TODO(填充数据 )
* @param
* @throws
*/
private void fillSheetData() throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
int rowNum = 1;
width = new ArrayList<>();
CellStyle cellStyle = styles.get("cell");
Class clazz = contents.get(0).getClass();
for(int i = 0;i<contents.size();i++){
Object obj = contents.get(i);
Row row = sheet.createRow(i+rowNum);
row.setHeightInPoints(2*sheet.getDefaultRowHeightInPoints());
for(int j= 0;j<methodList.size();j++){
if(methodList.get(j)==null || "".equalsIgnoreCase(methodList.get(j)))
continue;
Method method = clazz.getMethod(methodList.get(j));
Cell itemCell = row.createCell(j);
String s = method.invoke(obj) == null ? "" : String.valueOf(method.invoke(obj));
if(width.size()>=(j+1)){
width.set(j,width.get(j)>s.length() ? width.get(j) : s.length());
}else {
width.add(s.length());
}
itemCell.setCellValue(s);
itemCell.setCellStyle(cellStyle);
}
}
}
/**
* @Description: TODO(导出数据)
* @param response
* @throws
*/
private void export(HttpServletResponse response) throws IOException {
response.setContentType("application/vnd.ms-excel");
String excelFileName = title + ".xlsx";
response.addHeader("Content-Disposition", "attachment;filename="
+ new String(excelFileName.getBytes("GB2312"), "iso8859-1"));
OutputStream ouputStream = response.getOutputStream();
workbook.write(ouputStream);
ouputStream.flush();
ouputStream.close();
}
}