springboot + poi 导出excel 通用版

1.导入依赖包

		<!-- poi导入导出 -->
		<dependency>
			<groupId>org.apache.poi</groupId>
			<artifactId>poi</artifactId>
			<version>3.13</version>
		</dependency>
		
		<dependency>
			<groupId>org.apache.poi</groupId>
			<artifactId>poi-ooxml</artifactId>
			<version>3.13</version>
		</dependency>
		
		<!-- 工具类中引入到了apache中的字符操作类-->
		<dependency>
			<groupId>commons-lang</groupId>
			<artifactId>commons-lang</artifactId>
			<version>2.6</version>
		</dependency>
		<!-- 工具类中对html进行解析-->
		<dependency>
			<groupId>org.jsoup</groupId>
			<artifactId>jsoup</artifactId>
			<version>1.11.3</version>
		</dependency>

2.创建单元个类

package com.iflytek.edu.hnezzhxy.util.htmToExcel;

/**
 * excel Td 单元格类
 * 
 * @author mingtao
 * @time 2017年9月14日10:24:32
 */
class ExcelTd {
	// 横向区域
	private int rowspan = 1;
	// 纵向区域
	private int colspan = 1;
	// 横向坐标
	private int x;
	// 纵向坐标
	private int y;
	// 内容
	private String content;

	public int getRowspan() {
		return rowspan;
	}

	public void setRowspan(int rowspan) {
		this.rowspan = rowspan;
	}

	public int getColspan() {
		return colspan;
	}

	public void setColspan(int colspan) {
		this.colspan = colspan;
	}

	public String getContent() {
		return content;
	}

	public void setContent(String content) {
		this.content = content;
	}

	public int getX() {
		return x;
	}

	public void setX(int x) {
		this.x = x;
	}

	public int getY() {
		return y;
	}

	public void setY(int y) {
		this.y = y;
	}
}

3.传入html代码字符串,返回POI的工作簿对象HSSFWorkbook,工具类

package com.iflytek.edu.hnezzhxy.util.htmToExcel;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.*;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;

/**
 * @ClassName:HtmlToExcelUtils
 * @Description: 传入html代码字符串,返回POI的工作簿对象HSSFWorkbook,工具类
 * @date 2017年9月14日10:51:42
 */
public class HtmlToExcelUtils {
	/** 表格的列数 */
	private int columnSize;
	/** 表格的行数 */
	private int rowSize;
	/** 数据的行数,不含表头 */
	private int rowSize_data;
	/** 标题所占行数 */
	private int rowSize_title = 2;
	/** 表头所占行数 */
	private int rowSize_header;
	/** 工作表名称 */
	private String sheetName;

	/**
	 * 日志记录
	 */
	private static Logger logger=LoggerFactory.getLogger(HtmlToExcelUtils.class);
	
	//构造函数,初始化参数
	public HtmlToExcelUtils(int rowSize_title, String sheetName) {
		this.rowSize_title = rowSize_title;
		this.sheetName = sheetName;
	}

	/**
	 * @Title : readHtmlStr
	 * @Description : 使用jsoup解析html,得到表头数据List,表体数据String[][]
	 * @author : Qin
	 * @date : 2014年12月13日 下午6:32:55
	 * @return
	 * @throws Exception
	 */
	public LinkedHashMap<String,Object> readHtmlStr(String htmlStr) throws Exception {
		Document doc = Jsoup.parseBodyFragment(htmlStr, "utf-8");
		doc.select("input[type$=hidden]").remove();// 删除所有input隐藏域
		doc.select("tr[style*=none]").remove();// 删除隐藏的tr

		Elements captions = doc.getElementsByTag("caption");// 查找表头
		String tableTitle = "";// 保存表头标题
		if (captions != null && captions.size() > 0) {
			Element caption = captions.get(0);
			tableTitle = caption.text();
		} else {
			rowSize_title = 0;// 表示,没有表头
		}

		Elements trs_data = doc.getElementsByTag("tr");// 获取所有tr
		rowSize = trs_data.size() + rowSize_title;// 获取表格的行数,外加标题行数

		Elements theads = doc.getElementsByTag("thead");// 表头thead标签

		List<ExcelTd> finalHeaderList = new ArrayList<ExcelTd>();// 存放推导完毕的正确数据

		List<ExcelTd> dataList = new ArrayList<ExcelTd>();// 表头1单元格List
		if (theads != null && theads.size() > 0) {// 表示有表头
			Elements thead_trs = theads.get(0).getElementsByTag("tr");// 表头中的tr
			rowSize_header = thead_trs.size();
			trs_data.removeAll(thead_trs);// 移除表头中的的tr元素,trs中剩下数据行

			List<ExcelTd> headerList = new ArrayList<ExcelTd>();// 表头1单元格List
			// 构造表头
			// 将表头数据存到List中。x、y坐标从0开始
			// 确定x坐标之1:横向推导
			int basicY_thead = rowSize_title;
			for (int i = 0; i < thead_trs.size(); i++) {
				Element thead_tr = thead_trs.get(i);
				Elements thead_tr_ths = thead_tr.getElementsByTag("th");
				for (int j = 0; j < thead_tr_ths.size(); j++) {
					Element e = thead_tr_ths.get(j);
					ExcelTd td = new ExcelTd();
					td.setContent(e.text());
					if (StringUtils.isNotBlank(e.attr("colspan"))) {
						td.setColspan(Integer.valueOf(e.attr("colspan").trim()));
					}
					if (StringUtils.isNotBlank(e.attr("rowspan"))) {
						td.setRowspan(Integer.valueOf(e.attr("rowspan").trim()));
					}
					td.setX(HorizontalDeduction_th(e));// 步骤1:横向推导,但这个坐标并不是最终坐标,需要进行纵向推导
					td.setY(i + basicY_thead);// y坐标很简单,就是tr的值
					headerList.add(td);
				}
			}
			// 确定x坐标之2:纵向推导
			finalHeaderList = verticalDeduction(headerList);

			if (trs_data.size() > 0) {// 表示有表格内容数据
				rowSize_data = trs_data.size();
			} else {// 表示只有表头数据,没有表格内容数据
				rowSize_data = 0;
			}

		} else {// 表示没有表头
			rowSize_header = 0;
		}
		// 循环每一个数据单元格
		int basicY_data = rowSize_title + rowSize_header;
		for (int i = 0; i < trs_data.size(); i++) {
			Element tr = trs_data.get(i);
			Elements tds = tr.getElementsByTag("td");
			// 循环每一行的所有列
			for (int j = 0; j < tds.size(); j++) {
				Element e = tds.get(j);
				Elements inp = e.getElementsByTag("input");
				ExcelTd td = new ExcelTd();
				if (StringUtils.isNotBlank(e.attr("colspan"))) {
					td.setColspan(Integer.valueOf(e.attr("colspan").trim()));
				}
				if (StringUtils.isNotBlank(e.attr("rowspan"))) {
					td.setRowspan(Integer.valueOf(e.attr("rowspan").trim()));
				}
				if (inp != null && inp.size() > 0) {// 表示td中嵌套input
					td.setContent(inp.get(0).val());
				} else {// 表示td中没有嵌套input
					td.setContent(e.text().trim());
				}
				td.setX(HorizontalDeduction_td(e));// 步骤1:横向推导,但这个坐标并不是最终坐标,需要进行纵向推导
				td.setY(i + basicY_data);// y坐标很简单,就是tr的值
				dataList.add(td);
			}
		}
		// 步骤2:纵向推导
		dataList = verticalDeduction(dataList);

		// 表头和表内容合并为一个List
		finalHeaderList.addAll(dataList);

		// 对列进行赋值,找到第一个单元格计算列宽
		ExcelTd lastTd = finalHeaderList.get(finalHeaderList.size() - 1);
		columnSize = 0;
		for(int i = 0; i<finalHeaderList.size();i++){
			ExcelTd td = finalHeaderList.get(i);
			if(columnSize < td.getX()){
				columnSize = td.getX();
			}
		}
		columnSize = /*lastTd.getX()*/columnSize + lastTd.getColspan();

		int[][] contextSizeArr = new int[rowSize][columnSize];// 记录内容单元格内容长度,便于进行列宽自适应调整
		String[][] dataArr = new String[rowSize_data][columnSize];
		// 将表格的长度按照该单元格的位置填入字符串长度
		// 不能使用普通下标方式赋值,因为如果有合并单元格的情况,数组的位置就会错位,使用坐标保证不会错位
		for (int i = 0; i < finalHeaderList.size(); i++) {
			ExcelTd td = finalHeaderList.get(i);
			contextSizeArr[td.getY()][td.getX()] = getStringLength(td.getContent()) + 1;
		}
		int[] maxLengthArr = getMaxLength(contextSizeArr);

		// 根据解析到的数据返回POI的Excel对象
		LinkedHashMap<String,Object> map = new LinkedHashMap<>();
		map.put("tableTitle",tableTitle);
		map.put("finalHeaderList",finalHeaderList);
		map.put("dataArr",dataArr);
		map.put("maxLengthArr",maxLengthArr);
		return map;
	}

	/**
	 * @Title : getStringLength
	 * @Description : 中文字符与非中文字符长度计算
	 * @time 2017年9月14日10:52:41
	 * @param s
	 * @return
	 */
	private int getStringLength(String s) {
		double valueLength = 0;
		String chinese = "[\u4e00-\u9fa5]";
		// 获取字段值的长度,如果含中文字符,则每个中文字符长度为2,否则为1
		for (int i = 0; i < s.length(); i++) {
			// 获取一个字符
			String temp = s.substring(i, i + 1);
			// 判断是否为中文字符
			if (temp.matches(chinese)) {
				// 中文字符长度为1
				valueLength += 1;
			} else {
				// 其他字符长度为0.5
				valueLength += 0.5;
			}
		}
		// 进位取整
		return (int) Math.ceil(valueLength);
	}

	/**
	 * @Title : getMaxLength
	 * @Description : 竖向遍历二维数组,找到每一列的最大值
	 * @time 2017年9月14日10:52:59
	 * @param contextSizeArr
	 * @return
	 */
	private int[] getMaxLength(int[][] contextSizeArr) {
		int[] maxArr = new int[columnSize];
		for (int i = 0; i < columnSize; i++) {
			int basic = 0;
			for (int j = 0; j < rowSize; j++) {
				if (contextSizeArr[j][i] > basic) {// 注意下标的写法
					basic = contextSizeArr[j][i];
				}
			}
			maxArr[i] = basic;
		}
		return maxArr;
	}

	/**
	 * @Title : HorizontalDeduction
	 * @Description : 使用递归,进行横坐标的第一步推导,横向推导,同时删除多余的非td元素
	 * @time : 2017年9月14日10:53:16
	 * @param e
	 * @return
	 */
	private int HorizontalDeduction_td(Element e) {
		Element preElement = e.previousElementSibling();
		if (preElement != null) {
			if (!preElement.tagName().equals("td")) {// 表示td的上一个兄弟节点不是td,则删除这个多余的元素
				preElement.remove();
			} else {
				int nColSpan = 1;// 默认为1
				if (StringUtils.isNotBlank(preElement.attr("colspan"))) {
					nColSpan = Integer.valueOf(preElement.attr("colspan").trim());// 前一个元素的列合并情况
				}
				return HorizontalDeduction_td(preElement) + nColSpan;
			}
		}
		return 0;
	}

	/**
	 * @Title : HorizontalDeduction
	 * @Description : 使用递归,进行横坐标的第一步推导,横向推导,同时删除多余的非td元素
	 * @time : 2017年9月14日10:53:34
	 * @param e
	 * @return
	 */
	private int HorizontalDeduction_th(Element e) {
		Element preElement = e.previousElementSibling();
		if (preElement != null) {
			if (!preElement.tagName().equals("th")) {// 表示td的上一个兄弟节点不是td,则删除这个多余的元素
				preElement.remove();
			} else {
				int nColSpan = 1;// 默认为1
				if (StringUtils.isNotBlank(preElement.attr("colspan"))) {
					nColSpan = Integer.valueOf(preElement.attr("colspan").trim());// 前一个元素的列合并情况
				}
				return HorizontalDeduction_th(preElement) + nColSpan;
			}
		}
		return 0;
	}

	/**
	 * @Title : verticalDeduction
	 * @Description : 纵向推导
	 * @time 2017年9月14日10:54:01
	 * @param headerList
	 * @return
	 */
	private List<ExcelTd> verticalDeduction(List<ExcelTd> headerList) {
		int headerSize = headerList.size();
		for (int i = 0; i < headerSize; i++) {
			ExcelTd tdA = headerList.get(i);
			boolean flag = true;
			while (flag) {// 不断排列当前节点的位置,直到它的位置绝对正确
				flag = false;// 不需要移位
				for (int j = i - 1; j >= 0; j--) {// 找到之前与td的横坐标相等的值
					ExcelTd tdB = headerList.get(j);
					if (tdA.getX() == tdB.getX()) {// A找到与其X坐标相等的B
						if (tdB.getRowspan() > tdA.getY() - tdB.getY()) {// 如果B单元格“挡住”了A单元格,才进行移位操作。即:只有B占的行数大于或等于A、B之间的距离,那么B才会挡住A
							flag = true;// 如果存在移位单元格,则仍然需要重新判断当前的位置是否正确。需要移位
							tdA.setX(tdA.getX() + tdB.getColspan());// A的X坐标向后推B.colspan的位置
							int YA = tdA.getY();
							for (int m = i + 1; m < headerSize; m++) {// 同时,与A同处一tr但在其后边的td节点均应向后推B.colspan个位移
								ExcelTd td = headerList.get(m);
								if (td.getY() == YA) {
									td.setX(td.getX() + tdB.getColspan());
								}
							}
						}
					}
				}
			}
		}
		return headerList;
	}

	/**
	 * @Title : buildExcel
	 * @Description : 依据传入的数据生成Excel文件
	 * @time : 2017年9月14日10:54:24
	 * @return
	 * @throws Exception
	 */
	private XSSFWorkbook buildExcel(XSSFWorkbook wb,String htmlStr,String sheetName)
			throws Exception {
		
		LinkedHashMap map =this.readHtmlStr(htmlStr);
		String title = map.get("tableTitle").toString();
		List<ExcelTd> finalHeaderList = (List<ExcelTd>)map.get("finalHeaderList");
		int[] maxLengthArr = (int[])map.get("maxLengthArr");
		
		wb =this.createSheet(wb,title,finalHeaderList,maxLengthArr,sheetName);
		return wb;
	}

	/**
	 * 工作表创建及数据写入
	 *  @param title
	 * @param finalHeaderList
	 *        表格表头数据
	 */
	private XSSFWorkbook createSheet(XSSFWorkbook wb,String title,List<ExcelTd> finalHeaderList, int[] maxLengthArr,String sheetName){

		XSSFSheet sheet = null;
		if (StringUtils.isNotBlank(sheetName)) {
			sheet = wb.createSheet(this.removeStr(sheetName));
		} else if (StringUtils.isNotBlank(title)) {
			sheet = wb.createSheet("title");
		} else {
			sheet = wb.createSheet("Sheet1");
		}

		// 表格样式
		// 1、基础样式
		XSSFCellStyle basicStyle = wb.createCellStyle();
		basicStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);// 设置水平居中
		basicStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER); // 设置垂直居中

		basicStyle.setBorderBottom(HSSFCellStyle.BORDER_THIN);// 下边框
		basicStyle.setBorderLeft(HSSFCellStyle.BORDER_THIN);// 左边框
		basicStyle.setBorderTop(HSSFCellStyle.BORDER_THIN);// 上边框
		basicStyle.setBorderRight(HSSFCellStyle.BORDER_THIN);// 右边框
		// 2、标题样式
		XSSFCellStyle titleStyle = wb.createCellStyle();
		titleStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);// 设置水平居中
		titleStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER); // 设置垂直居中

		XSSFFont headerFont1 = (XSSFFont) wb.createFont();
		headerFont1.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);// 设置字体加粗
		headerFont1.setFontHeightInPoints((short) 14);// 设置字体大小
		titleStyle.setFont(headerFont1);
		// 3、偶数行样式
		XSSFCellStyle evenStyle = wb.createCellStyle();
		evenStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
		evenStyle.setFillForegroundColor(HSSFColor.WHITE.index);
		evenStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);

		XSSFCellStyle oldStyle = wb.createCellStyle();
		oldStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
		oldStyle.setFillForegroundColor(HSSFColor.GREY_25_PERCENT.index);
		oldStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);

		// 构建基本空白表格
		for (int i = 0; i < rowSize; i++) {
			sheet.createRow(i);
			for (int j = 0; j < columnSize; j++) {
				sheet.getRow(i).createCell(j).setCellStyle(basicStyle);
			}
		}
		// 填充数据
		if (rowSize_title != 0) {
			// 1、标题
			XSSFCell cell = sheet.getRow(0).getCell(0);
			cell.setCellStyle(titleStyle);
			cell.setCellValue(title);
			// 单元格合并
			sheet.addMergedRegion(new CellRangeAddress(0, rowSize_title - 1, 0, columnSize - 1));// 起始行,终止行,起始列,终止列
		}
		// 2、表头、单元格数据内容写入
		for (int i = 0; i < finalHeaderList.size(); i++) {
			ExcelTd td = finalHeaderList.get(i);
			sheet.getRow(td.getY()).getCell(td.getX()).setCellValue(td.getContent());
			// 单元格合并
			sheet.addMergedRegion(new CellRangeAddress(// 起始行,终止行,起始列,终止列
					td.getY(), td.getY() + (td.getRowspan() - 1), td.getX(), td.getX() + (td.getColspan() - 1)));
		}
		// 3、设置每一列宽度以该列的最长内容为准
		for (int i = 0; i < maxLengthArr.length; i++) {
			if(maxLengthArr[i] * 2<255){
				sheet.setColumnWidth(i, maxLengthArr[i] * 2 * 256<3000?3000:maxLengthArr[i] * 2 * 256);
			}else {
				sheet.setColumnWidth(i,6000);
			}
		}

		for (int i = 0; i < rowSize; i++) {
			XSSFRow row = sheet.getRow(i);
			row.setHeightInPoints(row.getHeightInPoints() + 3);
		}
		
		return wb;
	}

	/**
	 * 导出多个sheet工作表excel
	 * @Description html转换成excel
	 * @param title_size 表头所占行数
	 * @param htmlStr
	 * @param fileName
	 * @param sheets 工作表名称数组
	 * @param response
	 * @throws Exception
	 */
	public static void htmlToExcels(int title_size, String[] htmlStr, String fileName,String[] sheets, HttpServletResponse response,HttpServletRequest request)
			throws Exception {
		if ( htmlStr !=null && htmlStr.length>0) {
			try {
				HtmlToExcelUtils htmlToExcel = new HtmlToExcelUtils(title_size, fileName);
				XSSFWorkbook wb = new XSSFWorkbook();
				for (int i=0;i<htmlStr.length;i++){
					wb = htmlToExcel.buildExcel(wb,htmlStr[i],sheets[i]);
				}

				String agent = (String) request.getHeader("USER-AGENT");
				if(agent != null && agent.toLowerCase().indexOf("firefox") > 0)
				{
					fileName = "=?UTF-8?B?" + (new String(Base64.encodeBase64(fileName.getBytes("UTF-8")))) + "?=";
				}
				else
				{
					fileName =  java.net.URLEncoder.encode(fileName, "UTF-8");
				}
				
				response.reset();
				response.setCharacterEncoding("UTF-8");
				response.setContentType("application/octet-stream; charset=utf-8");
				response.setHeader("Content-Disposition",
						"attachment; filename=" + fileName + ".xlsx");
				ServletOutputStream fOut = response.getOutputStream();

				wb.write(fOut);
				fOut.flush();
				fOut.close();
				wb.close();
			} catch (Exception e) {
				logger.error("创建excel文件失败:参数:"+Arrays.asList(htmlStr),e);
			}
		}
	}

	/**
	 * @Description html转换成excel
	 * @param title_size 表头所占行数
	 * @param htmlStr
	 * @param fileName
	 * @param response
	 * @throws Exception
	 */
	public static void htmlToExcel(int title_size, String htmlStr, String fileName, HttpServletResponse response,HttpServletRequest request)
			throws Exception {
		if (StringUtils.isNotBlank(htmlStr)) {
			try {
				HtmlToExcelUtils htmlToExcel = new HtmlToExcelUtils(title_size, fileName);
				XSSFWorkbook wb = new XSSFWorkbook ();
				wb = htmlToExcel.buildExcel(wb,htmlStr,fileName);

				String agent = (String) request.getHeader("USER-AGENT");
				if(agent != null && agent.toLowerCase().indexOf("firefox") > 0)
				{
					fileName = "=?UTF-8?B?" + (new String(Base64.encodeBase64(fileName.getBytes("UTF-8")))) + "?=";
				}
				else
				{
					fileName =  java.net.URLEncoder.encode(fileName, "UTF-8");
				}
				
				response.reset();
				response.setCharacterEncoding("UTF-8");
				response.setContentType("application/octet-stream; charset=utf-8");
				response.setHeader("Content-Disposition",
						"attachment; filename=" + fileName + ".xlsx");
				ServletOutputStream fOut = response.getOutputStream();

				wb.write(fOut);
				fOut.flush();
				fOut.close();
				wb.close();
			} catch (Exception e) {
				logger.error("创建excel文件失败:参数:"+htmlStr,e);
			}
		}
	}

	/**
	 * @Description html转换成excel 输出至服务器目标目录
	 * @param title_size 表头所占行数
	 * @param htmlStr
	 * @param fileName
	 * @param response
	 * @throws Exception
	 */
	public static void htmlToExcelToDir(int title_size, String htmlStr, String fileName, HttpServletResponse response,HttpServletRequest request,String aimDir)
			throws Exception {
		if (StringUtils.isNotBlank(htmlStr)) {
			try {
				HtmlToExcelUtils htmlToExcel = new HtmlToExcelUtils(title_size, fileName);
				XSSFWorkbook wb = new XSSFWorkbook ();
				wb = htmlToExcel.buildExcel(wb,htmlStr,fileName);

				//目标文件路径
				File pathFile = new File(aimDir);
				if (!pathFile.exists()) {
					boolean t = pathFile.mkdirs();
				}
				
				FileOutputStream out = new FileOutputStream(new File(aimDir+fileName+".xlsx"));
				
				wb.write(out);
				out.flush();
				out.close();
				wb.close();
			} catch (Exception e) {
				logger.error("创建excel文件失败:参数:"+htmlStr,e);
			}
		}
	}
   
	public static void htmlToExcelsToDir(int title_size, String[] htmlStrs,String[] sheetNames, String fileName, HttpServletResponse response,HttpServletRequest request,String aimDir)
			throws Exception {
		if (htmlStrs!=null&&htmlStrs.length>0) {
			try {
				HtmlToExcelUtils htmlToExcel = new HtmlToExcelUtils(title_size, fileName);
				XSSFWorkbook wb = new XSSFWorkbook ();
				for (int i=0;i<htmlStrs.length;i++){
					wb = htmlToExcel.buildExcel(wb,htmlStrs[i],sheetNames[i]);
				}
				//目标文件路径
				File pathFile = new File(aimDir);
				if (!pathFile.exists()) {
					boolean t = pathFile.mkdirs();
				}
				
				FileOutputStream out = new FileOutputStream(new File(aimDir+fileName+".xlsx"));
				
				wb.write(out);
				out.flush();
				out.close();
				wb.close();
			} catch (Exception e) {
				logger.error("创建excel文件失败:参数:"+htmlStrs,e);
			}
		}
	}
	
	/**
	 * 去除sheet中不能包含的字符
	 */
	private String removeStr(String str){
		str = str.replace(":", "");
		str = str.replace(":", "");
		str = str.replace("\\", "");
		str = str.replace("/", "");
		str = str.replace("?", "");
		str = str.replace("*", "");
		str = str.replace("[", "");
		str = str.replace("]", "");
		str = str.replace("'", "");
		return str;
	}
}

4.控制层的代码

package com.iflytek.edu.hnezzhxy.controller;

import com.iflytek.edu.hnezzhxy.common.config.ExportStudentModel;
import com.iflytek.edu.hnezzhxy.common.config.PdfEntity;
import com.iflytek.edu.hnezzhxy.common.config.ViewPDF;
import com.iflytek.edu.hnezzhxy.model.ZsbmSubject;
import com.iflytek.edu.hnezzhxy.service.ExportService;
import com.iflytek.edu.hnezzhxy.util.htmToExcel.HtmlToExcelUtils;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
 * @version 1.0
 * @description
 * @create 2020/07/06 20:46
 */
@RestController
public class ExportController {

    @Autowired
    private ExportService exportService;

	/**
	 * 导出报名明细
	 * @param req
	 * @param resp
	 * @throws Exception
	 */
    @RequestMapping(value = "/exportExcel", method = RequestMethod.GET)
	public void exportExcel(HttpServletRequest req, HttpServletResponse resp) throws Exception {
		//查询要导出的数据【如何查询此处略】
        List<ExportStudentModel> list = exportService.getZbsmStudent();
        //拼接html标签,让工具类去解析html标签,创建excel单元格数据
        StringBuilder excelHtml = new StringBuilder();
        excelHtml.append("<table cellspacing=\"\" cellpadding=\"\" border=\"\">");
        excelHtml.append("<tbody><tr><td colspan=\"11\">淮南二中自主招生报名明细表</td></tr>");
        excelHtml.append("<tr><td>序号</td><td>姓名</td><td>性别</td><td>选考科目</td><td>毕业学校</td><td>身份证号</td>");
        excelHtml.append("<td>中考考号</td><td>报名手机号</td><td>考场座位号</td><td>审核结果</td><td>审核意见</td></tr>");
        if(!CollectionUtils.isEmpty(list)){
            String mainTableHtml="";
            for (int i=0;i<list.size();i++) {
                ExportStudentModel bean=(ExportStudentModel)list.get(i);
                mainTableHtml+="<tr><td>"+(i+1)+"</td>";
                mainTableHtml+="<td>"+(bean.getName()==null?"":bean.getName())+"</td>";
                mainTableHtml+="<td>"+(bean.getSex()==1?"女":"男")+"</td>";
               List<ZsbmSubject> subjects=exportService.getZsbmSubjectBySid(bean.getSid());
                mainTableHtml+="<td>";
               if(!CollectionUtils.isEmpty(subjects)){
                   bean.setZsbmSubjects(subjects);
                   for (int j=0;j<subjects.size();j++) {
                       ZsbmSubject item=(ZsbmSubject)subjects.get(j);
                       if(j!=subjects.size()-1){
                           mainTableHtml+=(item.getName()==null?"":item.getName())+",";
                       }else{
                           mainTableHtml+=(item.getName()==null?"":item.getName());
                       }
                   }

               }
                mainTableHtml+="</td>";
                mainTableHtml+="<td>"+(bean.getGraduateSchool()==null?"":bean.getGraduateSchool())+"</td>";
                mainTableHtml+="<td>"+(bean.getIdcardNum()==null?"":bean.getIdcardNum())+"</td>";
                mainTableHtml+="<td>"+(bean.getAdmissionNo()==null?"":bean.getAdmissionNo())+"</td>";
                mainTableHtml+="<td>"+(bean.getStuPhoneNum()==null?"":bean.getStuPhoneNum())+"</td>";
                mainTableHtml+="<td>"+(bean.getStuSeatNum()==null?"":bean.getStuSeatNum())+"</td>";
                mainTableHtml+="<td>"+(bean.getStatusName()==null?"":bean.getStatusName())+"</td>";
                mainTableHtml+="<td>"+(bean.getExamineReason()==null?"":bean.getExamineReason())+"</td>";
                mainTableHtml+="</tr>";
            }
            excelHtml.append(mainTableHtml);

        }
        excelHtml.append("</tbody></table>") ;
        HtmlToExcelUtils.htmlToExcel(10, excelHtml.toString(), "淮南二中自主招生报名明细表", resp, req);
	}
}

5.导出的数据实体类

package com.iflytek.edu.hnezzhxy.common.config;

import com.iflytek.edu.hnezzhxy.model.ZsbmSubject;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;

/**
 * @version 1.0
 * @description
 * @create 2020/07/08 14:28
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ExportStudentModel {
    /** 学生id **/
    private String sid;
    /** 学生姓名 **/
    private String name;
    /** 学生性别 **/
    private byte sex;
    /** 毕业学校 **/
    private String graduateSchool;
    /** 身份证号码 **/
    private String idcardNum;
    /** 手机号 **/
    private String stuPhoneNum;
    /** 中考准考证号码 **/
    private String admissionNo;
    /** 审核状态 **/
    private byte status;
    /** 审核不通过原因 **/
    private String examineReason;
    /** 座位号 **/
    private String stuSeatNum;
    /** 审核状态中文 **/
    private String statusName;
    /** 学科科目 **/
    private List<ZsbmSubject> zsbmSubjects;

}

6.浏览器请求http://localhost:8081/hnezzsbm/exportExcel测试
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_40974235/article/details/107219751
今日推荐