一、使用exsyExcel实现
includeColumnFieldNames 方法
导出只包含参数中传入的字段
/**
* 将列表以 Excel 响应给前端(支持勾选列导出)
*
* @param response 响应
* @param filename 文件名
* @param sheetName Excel sheet 名
* @param head Excel head 头
* @param data 数据列表哦
* @param title 需要导出的列
* @param <T> 泛型,保证 head 和 data 类型的一致性
* @throws IOException 写入失败的情况
*/
public static <T> void write(HttpServletResponse response, String filename, String sheetName,
Class<T> head, List<T> data,List<String> title) throws IOException {
// 输出 Excel
EasyExcel.write(response.getOutputStream(), head)
.includeColumnFieldNames(title) //只要导出对象中字段的数据
.autoCloseStream(false) // 不要自动关闭,交给 Servlet 自己处理
.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()) // 基于 column 长度,自动适配。最大 255 宽度
.sheet(sheetName).doWrite(data);
// 设置 header 和 contentType。写在最后的原因是,避免报错时,响应 contentType 已经被修改了
response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8"));
response.setContentType("application/vnd.ms-excel;charset=UTF-8");
}
二、使用poi+反射实现
通过反射获取属性对应的属性名称,设置为表头
再获取属性对应的值
/**
* 支持勾选列进行导出
*
* @param response
* @param fileName 文件名称
* @param title 列对应的属性名称
* @param clazz 数据对应的实体名称
* @param data 导出的数据集合
*
* @return 用户列表
*/
private <T> void exportUtils(HttpServletResponse response,String fileName,List<String> title, Class<T> clazz, List<T> data) throws IOException, IllegalAccessException {
//创建一个工作溥
SXSSFWorkbook workbook = new SXSSFWorkbook();
//创建一个Sheet页
SXSSFSheet sheet = workbook.createSheet();
Font font = workbook.createFont();
font.setFontHeightInPoints((short) 18);
font.setItalic(false);
font.setFontHeightInPoints((short) 16);
font.setFontName("宋体");
font.setBold(true);
CellStyle style = workbook.createCellStyle();
style.setAlignment(HorizontalAlignment.CENTER);
style.setVerticalAlignment(VerticalAlignment.CENTER);
style.setBorderBottom(BorderStyle.THIN);
style.setBorderLeft(BorderStyle.THIN);
style.setBorderTop(BorderStyle.THIN);
style.setBorderRight(BorderStyle.THIN);
style.setFont(font);
//-------------------------------单元格--------------------------------
CellStyle cellStyle = workbook.createCellStyle();
cellStyle.setBorderBottom(BorderStyle.THIN);
cellStyle.setBorderLeft(BorderStyle.THIN);
cellStyle.setBorderTop(BorderStyle.THIN);
cellStyle.setBorderRight(BorderStyle.THIN);
Font cellFont = workbook.createFont();
cellFont.setItalic(false);
cellFont.setFontName("宋体");
cellFont.setBold(true);
cellStyle.setFont(cellFont);
Integer startRow = 0;
List<Field> exportField = new ArrayList<>();
title.forEach(t->{
try {
Field declaredField = clazz.getDeclaredField(t);
declaredField.setAccessible(true);
exportField.add(declaredField);
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
});
exportField.sort(Comparator.comparingInt(f -> f.getAnnotation(ExcelProperty.class).order()));
if(startRow == 0){
SXSSFRow row = sheet.createRow(startRow);
for (int i = 0; i < title.size(); i++) {
SXSSFCell cell = row.createCell(i);
//使用反射根据属性名称获取表头
String column = exportField.get(i).getAnnotation(ExcelProperty.class).value()[0];
cell.setCellValue(column);
cell.setCellStyle(style);
}
startRow++;
}
for (int k = 0; k <data.size(); k++) {
SXSSFRow row = sheet.createRow(startRow);
for (int j = 0; j < title.size(); j++) {
SXSSFCell cell = row.createCell(j);
//通过反射根据属性名称获取对应的值
String value = exportField.get(j).get(data.get(k)).toString();
if(StrUtil.isNotEmpty(value)){
cell.setCellValue(value);
}else{
cell.setCellType(CellType.BLANK);
}
cell.setCellStyle(cellStyle);
}
startRow++;
}
setColumnWidth(sheet);
OutputStream out = response.getOutputStream();
//定义标题以及设置响应头信息
response.setCharacterEncoding("UTF-8");
response.setHeader("content-Type", "application/vnd.ms-excel");
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName + ".xlsx", StandardCharsets.UTF_8.name()));
// 直接整个excel全部写到浏览器
workbook.write(out);
out.flush();
out.close();
workbook.close();
}
//poi设置自适应列宽
private void setColumnWidth(Sheet sheet) {
//sheet的索引从0开始,获取sheet列数
int maxColumn = sheet.getRow(0).getPhysicalNumberOfCells();
for (int columnNum = 0; columnNum <= maxColumn; columnNum++) {
int columnWidth = sheet.getColumnWidth(columnNum) / 256;
// 遍历列的数据,获取这一列的最长字符串
for (int rowNum = 0; rowNum <= sheet.getLastRowNum(); rowNum++) {
Row currentRow;
if (sheet.getRow(rowNum) == null) {
currentRow = sheet.createRow(rowNum);
} else {
currentRow = sheet.getRow(rowNum);
}
if (currentRow.getCell(columnNum) != null) {
Cell currentCell = currentRow.getCell(columnNum);
if (currentCell.getCellType() == CellType.STRING) {
int length = currentCell.getStringCellValue().getBytes().length;
if (columnWidth < length) {
columnWidth = length;
}
}
}
}
//将最长的length*256设为列宽
sheet.setColumnWidth(columnNum, columnWidth * 256);
}
}