前言:

本工具类经过PostMan和web页面严格测试可用,经过了多个版本迭代优化,可以直接使用,也方便大家根据自己的业务需求,修改定制自己的导出工具。
市面上有很多封装好的导出工具(如:阿里的easyExcel,GitHub上xxl-excel等),但如果直接引用依赖,扩展性和定制性比较差,所以博主通过apache.poi,自己实现一款Excel导出工具,方便定制使用。本工具类支持SpringMVC等主流的Java框架,支持RESTful接口,代码全部通过测试。

一.功能介绍:

  • 支持List实体类导出
  • 支持List列数不固定的数据导出
  • 支持多Sheet页导出
  • 支持导出文件名为URL编码,防止乱码
  • 支持文件名、sheet名特殊字符自动替换
  • 支持Excel2007以上版本
  • 支持有数据的文本框描边
  • 支持表头字体加大
  • 表头数据单元格内换行
  • 支持标题栏
  • 支持选择null空字段是否导出
  • 支持将日期格式数据转换为自定义格式的时间字符串
  • 支持单元格类型区分数值、字符串,单元格对齐方式不同对待
  • 支持将Excel导出到HttpServletResponse流中(用做对外提供接口)

二.导出工具类源码:

注: 此代码可直接在项目中使用。

package com.excel.util;import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFColor;
import org.apache.poi.xssf.usermodel.XSSFFont;
import org.apache.poi.xssf.usermodel.XSSFRichTextString;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;/*** 导出Excel工具类** @author 大脑补丁* */
public class ExportExcelUtil<T> {/*** 导出多Sheet的Excel到HttpServletResponse流中** @param fileName*            另存为文件名* @param sheetName*            工作簿中的多张Sheet工作表的名称列表* @param titleName*            表格的标题名称(没有标题,则传null)* @param headers*            表头列表* @param dataList*            要导出的数据源* @param HttpServletResponse*            Http响应* @param pattern*            时间类型数据的格式,默认UTC格式* @param isExportNullField*            空字段是否导出(true:导出,false:不导出)* @see 导出Excel格式:表头内容居中,字体略大于正文,颜色深灰色。正文文本类型对齐方式居左,数字类型对齐方式居右。仅有数据* 的单元格,有边框环绕,实体类的属性顺序即为表头顺序*/public static <T> void exportExcel(String fileName, List<String> sheetNames, String titleName, List<String> headers,List<List<T>> dataLists, HttpServletResponse response, String pattern, boolean isExportNullField) {XSSFWorkbook wb = exportAllExcel(sheetNames, titleName, headers, dataLists, pattern, isExportNullField);setResponseHeader(response, replaceSpecStr(fileName));ServletOutputStream out = null;try {out = response.getOutputStream();wb.write(out);} catch (IOException e) {e.printStackTrace();} finally {try {out.flush();out.close();wb.close();} catch (IOException e) {e.printStackTrace();}}}/*** 导出多Sheet动态列的Excel到HttpServletResponse流中** @param fileName*            另存为文件名* @param sheetName*            工作簿中的多张Sheet工作表的名称列表* @param titleName*            表格的标题名称(没有标题,则传null)* @param headers*            表头列表* @param dataList*            要导出的数据源* @param HttpServletResponse*            Http响应* @param pattern*            时间类型数据的格式,默认UTC格式* @param isExportNullField*            空字段是否导出(true:导出,false:不导出)*/public static void exportDynamicExcel(String fileName, List<String> sheetNames, String titleName,List<String> headers, List<List<Map<String, Object>>> dataLists, HttpServletResponse response,String pattern, boolean isExportNullField) {XSSFWorkbook wb = exportDynamicExcelImpl(sheetNames, titleName, headers, dataLists, pattern, isExportNullField);setResponseHeader(response, replaceSpecStr(fileName));ServletOutputStream out = null;try {out = response.getOutputStream();wb.write(out);} catch (IOException e) {e.printStackTrace();} finally {try {out.flush();out.close();wb.close();} catch (IOException e) {e.printStackTrace();}}}/*** 设置响应的类型、编码和文件名称** @param response* @param fileName*/public static void setResponseHeader(HttpServletResponse response, String fileName) {try {response.reset();response.setContentType("application/msexcel");// 设置生成的文件类型response.setCharacterEncoding("UTF-8");// 设置文件头编码方式和文件名// 在浏览器中测试生效,postman中文件名为response,无法修改response.setHeader("Content-disposition", "attachment;filename=".concat(String.valueOf(URLEncoder.encode(replaceSpecStr(fileName) + ".xlsx", "UTF-8"))));// 此设置,可保证web端可以取到文件名response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");} catch (Exception ex) {ex.printStackTrace();}}/*** 设置响应的类型、编码和文件名称** @param response* @param fileName*/public static void setResponseHeader(HttpServletResponse response, String fileName, boolean urlEncode) {try {String downloadName = urlEncode == true? String.valueOf(URLEncoder.encode(replaceSpecStr(fileName) + ".xlsx", "UTF-8")): String.valueOf(replaceSpecStr(fileName) + ".xlsx");response.reset();response.setContentType("application/msexcel");// 设置生成的文件类型response.setCharacterEncoding("UTF-8");// 设置文件头编码方式和文件名// 在浏览器中测试生效,postman中文件名为response,无法修改response.setHeader("Content-Disposition", "attachment;filename=".concat(downloadName));response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");} catch (Exception ex) {ex.printStackTrace();}}/*** 多Sheet导出实现** @param sheetNames* @param titleName* @param headers* @param dataLists* @param pattern* @param isExportNullField* @return*/private static <T> XSSFWorkbook exportAllExcel(List<String> sheetNames, String titleName, List<String> headers,List<List<T>> dataLists, String pattern, boolean isExportNullField) {// 创建一个工作薄XSSFWorkbook workbook = new XSSFWorkbook();for (int i = 0; i < dataLists.size(); i++) {// 创建一个工作表XSSFSheet sheet = workbook.createSheet(replaceSpecStr(sheetNames.get(i)));// 设置单元格列宽度为16个字节sheet.setDefaultColumnWidth((short) 16);// 创建表头样式XSSFCellStyle headersStyle = workbook.createCellStyle();headersStyle.setBorderTop(BorderStyle.THIN);headersStyle.setBorderBottom(BorderStyle.THIN);headersStyle.setBorderLeft(BorderStyle.THIN);headersStyle.setBorderRight(BorderStyle.THIN);// 表头内容对齐方式:居中headersStyle.setAlignment(HorizontalAlignment.CENTER);XSSFFont headersFont = workbook.createFont();// 设置字体格式headersFont.setColor(new XSSFColor(java.awt.Color.DARK_GRAY));headersFont.setFontHeightInPoints((short) 14);// 表头样式应用生效headersStyle.setFont(headersFont);XSSFCellStyle dataSetStyle = workbook.createCellStyle();// 正文单元格边框样式dataSetStyle.setBorderBottom(BorderStyle.THIN);dataSetStyle.setBorderRight(BorderStyle.THIN);dataSetStyle.setBorderLeft(BorderStyle.THIN);// 数据内容对齐方式:居左// dataSetStyle.setAlignment(HorizontalAlignment.CENTER_SELECTION);XSSFFont dataSetFont = workbook.createFont();// 正文字体颜色dataSetFont.setColor(new XSSFColor(java.awt.Color.BLACK));// 为正文设置样式dataSetStyle.setFont(dataSetFont);if (titleName != null && titleName != "") {XSSFCellStyle titleStyle = workbook.createCellStyle();// 将首行合并居中作为标题栏sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, headers.size() - 1));XSSFFont titleFont = workbook.createFont();// 设置标题字体大小titleFont.setFontHeightInPoints((short) 20);// 设置标题字体样式titleStyle.setFont(titleFont);// 创建标题行并设置样式XSSFRow titleRow = sheet.createRow(0);XSSFCell titleCell = titleRow.createCell(0);titleCell.setCellStyle(titleStyle);titleCell.setCellValue(titleName);}int index = titleName == null || titleName.equals("") ? 0 : 1;// 创建表头并设置样式XSSFRow row = sheet.createRow(index);for (short j = 0; j < headers.size(); j++) {XSSFCell cell = row.createCell(j);cell.setCellStyle(headersStyle);XSSFRichTextString text = new XSSFRichTextString(headers.get(j));cell.setCellValue(text);}// 导出正文数据,并设置其样式Iterator<?> it = dataLists.get(i).iterator();while (it.hasNext()) {index++;row = sheet.createRow(index);Object entity = it.next();// 利用反射,根据实体类属性的先后顺序,动态调用其getXxx()方法,得到属性值Field[] fields = entity.getClass().getDeclaredFields();for (short k = 0; k < fields.length; k++) {XSSFCell cell = row.createCell(k);Field field = fields[k];String fieldName = field.getName();String getMethodName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);try {@SuppressWarnings("rawtypes")Class entityClass = entity.getClass();@SuppressWarnings("unchecked")Method getMethod = entityClass.getMethod(getMethodName, new Class[] {});Object value = getMethod.invoke(entity, new Object[] {});String textValue = null;// 如果是时间类型,格式化if (value instanceof Date) {Date date = (Date) value;pattern = pattern == null || pattern.equals("") ? "yyyy-MM-dd'T'HH:mm:ss'Z'" : pattern;SimpleDateFormat sdf = new SimpleDateFormat(pattern);textValue = sdf.format(date);} else {// 若字段为空且允许导出空字段,则将null导出为""textValue = value == null && isExportNullField ? "" : value.toString();}if (!textValue.equals("")) {// 有数据时边框环绕cell.setCellStyle(dataSetStyle);// 正则判断是否为数值Pattern p = Pattern.compile("^\\d+(\\.\\d+)?$");Matcher matcher = p.matcher(textValue);if (matcher.matches()) {// 是数字当作double处理,整型也不会补充小数点cell.setCellValue(Double.parseDouble(textValue));} else {// 不是数字类型作为文本输出cell.setCellValue(textValue);}}} catch (SecurityException e) {e.printStackTrace();} catch (NoSuchMethodException e) {e.printStackTrace();} catch (IllegalArgumentException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();}}}}return workbook;}/*** 多Sheet导出动态列到Excel实现** @param sheetNames* @param titleName* @param headers* @param dataLists* @param pattern*            时间格式* @param isExportNullField*            是否导出空字段* @return*/private static XSSFWorkbook exportDynamicExcelImpl(List<String> sheetNames, String titleName, List<String> headers,List<List<Map<String, Object>>> dataLists, String pattern, boolean isExportNullField) {// 创建一个工作薄XSSFWorkbook workbook = new XSSFWorkbook();for (int i = 0; i < dataLists.size(); i++) {// 创建一个工作表XSSFSheet sheet = workbook.createSheet(replaceSpecStr(sheetNames.get(i)));// 设置单元格列宽度为16个字节sheet.setDefaultColumnWidth((short) 16);// 创建表头样式XSSFCellStyle headersStyle = workbook.createCellStyle();headersStyle.setBorderTop(BorderStyle.THIN);headersStyle.setBorderBottom(BorderStyle.THIN);headersStyle.setBorderLeft(BorderStyle.THIN);headersStyle.setBorderRight(BorderStyle.THIN);// 表头内容对齐方式:居中headersStyle.setAlignment(HorizontalAlignment.CENTER);XSSFFont headersFont = workbook.createFont();// 设置字体格式headersFont.setColor(new XSSFColor(java.awt.Color.DARK_GRAY));headersFont.setFontHeightInPoints((short) 12);// 表头样式应用生效headersStyle.setFont(headersFont);// 设置单元格内内容换行headersStyle.setWrapText(true);XSSFCellStyle dataSetStyle = workbook.createCellStyle();// 正文单元格边框样式dataSetStyle.setBorderBottom(BorderStyle.THIN);dataSetStyle.setBorderRight(BorderStyle.THIN);dataSetStyle.setBorderLeft(BorderStyle.THIN);// 数据内容对齐方式:居左// dataSetStyle.setAlignment(HorizontalAlignment.CENTER_SELECTION);XSSFFont dataSetFont = workbook.createFont();// 正文字体颜色dataSetFont.setColor(new XSSFColor(java.awt.Color.BLACK));// 为正文设置样式dataSetStyle.setFont(dataSetFont);if (titleName != null && titleName != "") {XSSFCellStyle titleStyle = workbook.createCellStyle();// 将首行合并居中作为标题栏sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, headers.size() - 1));XSSFFont titleFont = workbook.createFont();// 设置标题字体大小titleFont.setFontHeightInPoints((short) 20);// 设置标题字体样式titleStyle.setFont(titleFont);// 创建标题行并设置样式XSSFRow titleRow = sheet.createRow(0);XSSFCell titleCell = titleRow.createCell(0);titleCell.setCellStyle(titleStyle);titleCell.setCellValue(titleName);}int index = titleName == null || titleName.equals("") ? 0 : 1;// 创建表头并设置样式XSSFRow row = sheet.createRow(index);for (short j = 0; j < headers.size(); j++) {XSSFCell cell = row.createCell(j);cell.setCellStyle(headersStyle);XSSFRichTextString text = new XSSFRichTextString(headers.get(j));cell.setCellValue(text);}// 导出正文数据,并设置其样式ListIterator<Map<String, Object>> it = dataLists.get(i).listIterator();while (it.hasNext()) {try {index++;row = sheet.createRow(index);Map<String, Object> map = it.next();headers = new ArrayList<String>(map.keySet());List<Object> values = new ArrayList<Object>(map.values());for (int k = 0; k < map.keySet().size(); k++) {try {XSSFCell cell = row.createCell(k);String textValue = null;Object value = values.get(k);// 如果是时间类型,格式化if (value instanceof Date) {Date date = (Date) value;pattern = pattern == null || pattern.equals("") ? "yyyy-MM-dd'T'HH:mm:ss'Z'" : pattern;SimpleDateFormat sdf = new SimpleDateFormat(pattern);textValue = sdf.format(date);} else {// 若字段为空且允许导出空字段,则将null导出为""textValue = value == null && isExportNullField ? "" : value.toString();}if (!textValue.equals("")) {// 有数据时边框环绕cell.setCellStyle(dataSetStyle);// 正则判断是否为数值Pattern p = Pattern.compile("^\\d+(\\.\\d+)?$");Matcher matcher = p.matcher(textValue);if (matcher.matches()) {// 是数字当作double处理,整型也不会补充小数点cell.setCellValue(Double.parseDouble(textValue));} else {// 不是数字类型作为文本输出cell.setCellValue(textValue);}}} catch (Exception e) {e.printStackTrace();}}} catch (Exception e) {e.printStackTrace();}}}return workbook;}/*** 导出Excel到HttpServletResponse流中** @param fileName*            另存为文件名* @param sheetName*            工作簿中的一张工作表的名称* @param titleName*            表格的标题名称(无需创建,则传null)* @param headers*            表头列表* @param dataList*            要导出的数据源* @param response*            Http响应* @param pattern*            时间类型数据的格式,默认UTC格式* @param isExportNullField*            空字段是否导出(true:导出,false:不导出)*/@Deprecatedpublic static void exportOneSheetExcel(String fileName, String sheetName, String titleName, List<String> headers,Collection<Collection<? extends Object>> dataList, HttpServletResponse response, String pattern,boolean isExportNullField) {XSSFWorkbook wb = exportExcelToWorkbook(sheetName, titleName, headers, dataList, pattern, isExportNullField);setResponseHeader(response, replaceSpecStr(fileName));ServletOutputStream out = null;try {out = response.getOutputStream();wb.write(out);} catch (IOException e) {e.printStackTrace();} finally {try {out.flush();out.close();wb.close();} catch (IOException e) {e.printStackTrace();}}}/*** 导出核心实现** @param sheetName* @param titleName* @param headers* @param dataList* @param pattern* @param isExportNullField* @return XSSFWorkbook*/@Deprecatedprivate static XSSFWorkbook exportExcelToWorkbook(String sheetName, String titleName, List<String> headers,Collection<?> dataList, String pattern, boolean isExportNullField) {// 创建一个工作薄XSSFWorkbook workbook = new XSSFWorkbook();// 创建一个工作表XSSFSheet sheet = workbook.createSheet(replaceSpecStr(sheetName));// 设置单元格列宽度为16个字节sheet.setDefaultColumnWidth((short) 16);// 创建表头样式XSSFCellStyle headersStyle = workbook.createCellStyle();headersStyle.setBorderTop(BorderStyle.THIN);headersStyle.setBorderBottom(BorderStyle.THIN);headersStyle.setBorderLeft(BorderStyle.THIN);headersStyle.setBorderRight(BorderStyle.THIN);// 表头内容对齐方式:居中headersStyle.setAlignment(HorizontalAlignment.CENTER);XSSFFont headersFont = workbook.createFont();// 设置字体格式headersFont.setColor(new XSSFColor(java.awt.Color.DARK_GRAY));headersFont.setFontHeightInPoints((short) 14);// 表头样式应用生效headersStyle.setFont(headersFont);XSSFCellStyle dataSetStyle = workbook.createCellStyle();// 正文单元格边框样式dataSetStyle.setBorderBottom(BorderStyle.THIN);dataSetStyle.setBorderRight(BorderStyle.THIN);dataSetStyle.setBorderLeft(BorderStyle.THIN);// 数据内容对齐方式:居左// dataSetStyle.setAlignment(HorizontalAlignment.CENTER_SELECTION);XSSFFont dataSetFont = workbook.createFont();// 正文字体颜色dataSetFont.setColor(new XSSFColor(java.awt.Color.BLACK));// 为正文设置样式dataSetStyle.setFont(dataSetFont);if (titleName != null && titleName != "") {XSSFCellStyle titleStyle = workbook.createCellStyle();// 将首行合并居中作为标题栏sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, headers.size() - 1));XSSFFont titleFont = workbook.createFont();// 设置标题字体大小titleFont.setFontHeightInPoints((short) 20);// 设置标题字体样式titleStyle.setFont(titleFont);// 创建标题行并设置样式XSSFRow titleRow = sheet.createRow(0);XSSFCell titleCell = titleRow.createCell(0);titleCell.setCellStyle(titleStyle);titleCell.setCellValue(titleName);}int index = titleName == null || titleName.equals("") ? 0 : 1;// 创建表头并设置样式XSSFRow row = sheet.createRow(index);for (short i = 0; i < headers.size(); i++) {XSSFCell cell = row.createCell(i);cell.setCellStyle(headersStyle);XSSFRichTextString text = new XSSFRichTextString(headers.get(i));cell.setCellValue(text);}// 导出正文数据,并设置其样式Iterator<?> it = dataList.iterator();while (it.hasNext()) {index++;row = sheet.createRow(index);Object entity = it.next();// 利用反射,根据实体类属性的先后顺序,动态调用其getXxx()方法,得到属性值Field[] fields = entity.getClass().getDeclaredFields();for (short i = 0; i < fields.length; i++) {XSSFCell cell = row.createCell(i);Field field = fields[i];String fieldName = field.getName();String getMethodName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);try {@SuppressWarnings("rawtypes")Class entityClass = entity.getClass();@SuppressWarnings("unchecked")Method getMethod = entityClass.getMethod(getMethodName, new Class[] {});Object value = getMethod.invoke(entity, new Object[] {});String textValue = null;// 如果是时间类型,格式化if (value instanceof Date) {Date date = (Date) value;pattern = pattern == null || pattern.equals("") ? "yyyy-MM-dd'T'HH:mm:ss'Z'" : pattern;SimpleDateFormat sdf = new SimpleDateFormat(pattern);textValue = sdf.format(date);} else {// 若字段为空且允许导出空字段,则将null导出为""textValue = value == null && isExportNullField ? "" : value.toString();}if (!textValue.equals("")) {// 有数据时边框环绕cell.setCellStyle(dataSetStyle);// 正则判断是否为数值Pattern p = Pattern.compile("^\\d+(\\.\\d+)?$");Matcher matcher = p.matcher(textValue);if (matcher.matches()) {// 是数字当作double处理,整型也不会补充小数点cell.setCellValue(Double.parseDouble(textValue));} else {// 不是数字类型作为文本输出cell.setCellValue(textValue);}}} catch (SecurityException e) {e.printStackTrace();} catch (NoSuchMethodException e) {e.printStackTrace();} catch (IllegalArgumentException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();}}}return workbook;}/*** 正则替换所有特殊字符** @param orgStr* @return*/public static String replaceSpecStr(String orgStr) {if (null != orgStr && !"".equals(orgStr.trim())) {String regEx = "[\\\\|:/\"<>?*\\[\\] ]";Pattern p = Pattern.compile(regEx);Matcher m = p.matcher(orgStr);return m.replaceAll("_");}return null;}}

三.数据源数据结构解释:

1.导出方法参数数据源:List<List<T>> dataLists

第一层List:多个sheet页。
第二层List:一个Sheet页下的多条数据。
T:实体类,对应一个Sheet页下的一行数据。

2.导出方法参数数据源:List<List<Map<String, Object>>> dataLists

第一层List:多个Sheet页数据。
第二层List:一个Sheet页下的多条数据
Map<String, Object>:一个Sheet页下的一行数据,其中key:表头,value:对应单元格的值。

四.功能和使用方法:

1.导出实体类方式

使用场景: 适合Excel列的名称顺序和列数是固定的业务场景。

注意事项: 实体类的属性声明的顺序,即为Excel导出后列的顺序,想调整列的顺序,需调整实体类属性声明的顺序即可。

导出方法:

/*** 导出多Sheet的Excel到HttpServletResponse流中** @param fileName*            另存为文件名* @param sheetName*            工作簿中的多张Sheet工作表的名称列表* @param titleName*            表格的标题名称(没有标题,则传null)* @param headers*            表头列表* @param dataList*            要导出的数据源* @param HttpServletResponse*            Http响应* @param pattern*            时间类型数据的格式,默认UTC格式* @param isExportNullField*            空字段是否导出(true:导出,false:不导出)*/public static <T> void exportExcel(String fileName, List<String> sheetNames, String titleName, List<String> headers,List<List<T>> dataLists, HttpServletResponse response, String pattern, boolean isExportNullField){……}

使用示例:

实体类示例:

package com.entity.dto;import java.io.Serializable;/*** 数据转Excel对象 注:属性名的顺序和Excel列顺序必须相同*/
@SuppressWarnings("serial")
public class EventDTO implements Serializable {// 列字段1private String name;// 列字段2private String code;public String getName() {return name;}public void setName(String name) {this.name = name;}public String getCode() {return code;}public void setCode(String code) {this.code = code;}
}

注: 文件名和sheet名:注意不要含有Excel不支持的特殊字符。

使用示例:
在SpringMVC的RESTful接口中,控制器中调用示例

<code>@GetMapping(value = "/myevent/export/{code}")public void exportEvent(HttpServletResponse response, @PathVariable("code") String code) {List<List<EventDTO>> dataLists = eventService.exportEvent(stationCode);if (dataLists != null && dataLists.size() > 0) {try {List<String> sheetNames = new ArrayList<String>(Arrays.asList("sheet页1, "sheet页2", "sheet页3"));List<String> headers = new ArrayList<String>(Arrays.asList("类型", "型号", "编号", "参数", "描述", "级别"));String excelName = "你的Excel名称";ExportExcelUtil.exportExcel(excelName, sheetNames, null, headers, dataLists, response, null, true);} catch (Exception e) {log.info("导出Excel出错", e);}}}
code>

2.导出Map对象的方式

使用场景: 适合Excel列的名称和顺序和列数是不固定的,如每次导出的列数可能不一致的场景。

注意事项: Excel导出后列的顺序,为Map中的键值对加入的顺序,要想导出后列的顺序固定,可将Map实例化为LinkedHashMap即可使导出后的列顺序不会改变。

例: 如下方式缓存导出数据,导出后的“名称”列,会在“类型”列的左侧。

Map<String, Object> tempMap = new LinkedHashMap<String, Object>();tempMap.put("名称", device.getName());tempMap.put("类型", device.getDeviceType());
/*** 导出多Sheet动态列的Excel到HttpServletResponse流中** @param fileName*            另存为文件名* @param sheetName*            工作簿中的多张Sheet工作表的名称列表* @param titleName*            表格的标题名称(没有标题,则传null)* @param headers*            表头列表* @param dataList*            要导出的数据源* @param HttpServletResponse*            Http响应* @param pattern*            时间类型数据的格式,默认UTC格式* @param isExportNullField*            空字段是否导出(true:导出,false:不导出)*/public static void exportDynamicExcel(String fileName, List<String> sheetNames, String titleName,List<String> headers, List<List<Map<String, Object>>> dataLists, HttpServletResponse response,String pattern, boolean isExportNullField) {……}

使用示例:
在SpringMVC的RESTful接口中,控制器中调用示例:

@PostMapping(value = "/history/export")public void exportHistory(HttpServletResponse response, @RequestBody Params params) {List<List<Map<String, Object>>> datalists = deviceService.exportHistory(params);if (!datalists.isEmpty()) {try {List<String> headers = new ArrayList<String>("表头列名1","表头列名2","表头列名3");String fileName ="你的文件名,若包含Excel不支持的特殊字符,会自动处理成下划线";ExportExcelUtil.exportDynamicExcel(fileName, Arrays.asList("用户历史数据"), null, headers, datalists, response,null, true);} catch (Exception e) {e.printStackTrace();}}}

Java之Excel导出工具类使用教程相关推荐

  1. Excel导出工具类

    前言 相信不少同学在开发中都会遇到导出excel这种需求,今天将Excel的导出工具和大家进行一个分享,如有错误还请大佬们批评指正.该工具类可以实现自定义列宽,自定义表头样式,实现了多sheet页合并 ...

  2. java Excel导出工具类

    Excel工具类 一.开发原因 最近工作的时候,正在写关于Excel导出功能,由于当前使用的工具类不太灵活和不易看懂,自己从头写又很浪费时间等原因,我决定自己写一款很简单的Excel导出的工具类,仅仅 ...

  3. 自己写的java excel导出工具类

    最近项目要用到excel导出功能,之前也写过类似的代码.因为这次项目中多次用到excel导出.这次长了记性整理了一下 分享给大伙 欢迎一起讨论 生成excel的主工具类: public class E ...

  4. Poi excel 导出 工具类参考

    public void poiCreateExcel(HttpServletResponse response, Map<String, Object> map) {// 下载文件信息St ...

  5. Java导入Excel工具类使用教程

    前言: 本工具类提供了Excel导入功能,通过反射机制将Excel中数据映射到实体类中,从而获取Excel数据,工具类依赖org.apache.poi包.支持RESTful API,支持Spring ...

  6. java读写excel文件poi_Java利用POI读写Excel文件工具类

    本文实例为大家分享了Java读写Excel文件工具类的具体代码,供大家参考,具体内容如下 package com.test.app.utils; import java.io.File; import ...

  7. esayExcel导出工具类

    依赖 <dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artif ...

  8. javaExcel 导出(基于POI的复杂表格导出工具类)

    我的需求: 项目中有一些工程表格需要导出,设计到行列合并,定制样式,原有工具类冗余,内聚性强.所以想写一个可以随意定制excel的工具类,工具类满足需求: 对于常用的工程表格有模板格式,可以任意插拔. ...

  9. Java操作百万数据量Excel导入导出工具类(程序代码教程)

    Java操作百万数据量Excel导入导出工具类(程序代码教程): # 功能实现1.自定义导入数据格式,支持配置时间.小数点类型(支持单/多sheet)(2种方式:本地文件路径导入(只支持xls.xls ...

最新文章

  1. Mac MySQL配置环境变量的两种方法
  2. ASP.NET返回上一页面的实现方法
  3. Chapter 1 快速搭建-服务的注册与发现(Eureka)
  4. java gui 结构_java gui教学图形界面的层次结构.ppt
  5. 重温强化学习之深度强化学习
  6. struts2框架下的一个简单的ajax例子
  7. vux 修改 设置 主题 颜色
  8. python空集合_python空集合
  9. jmeter正则中常见的转义字符-笔记三
  10. 第六次团队作业+登录界面
  11. 大作业---Android本地音乐播放器开发知识点19145120
  12. KVM的vCPU算法和Xen的Credit算法对比
  13. 移动硬盘驱动怎么修复_为什么您的新硬盘驱动器未在Windows中显示(以及如何修复)...
  14. macOS Big Sur 11.7.2 (20G1020) 正式版 ISO、PKG、DMG、IPSW 下载
  15. PAC学习理论:机器学习那些事
  16. opencv处理函数记录_转自opencv中文网站
  17. css中div的意思是什么
  18. 智慧路灯点亮新型城市
  19. java实现汉字判断+中文符号判断
  20. 改善内部客户服务的 3 个技巧

热门文章

  1. Service pack
  2. Win64位系统安装Codewarrior 6.3
  3. Xilinx官网大全__PowerPC 架构
  4. 第一次亲密接触Python
  5. Azure VM加速网络
  6. 打算抽时间自学一下游戏制作,做一款Mud文字游戏
  7. 绿色astah简体中文版6.8
  8. 2020华数杯C题脱贫帮扶绩效评价你怕了吗?
  9. 一亩三分地新手上路答案
  10. 基于snownlp及朴素贝叶斯的情感分析——以大众点评网评论为例