此例为maven项目,实现学生模块列表信息的导出Excel操作。所用框架为SSM框架。
工具类 ExportExcelUtil.java 中均为公用方法,无论任何框架项目都可直接调用类中方法,只需将对应的参数传到方法中即可。
1.jar包
在maven项目中增加如下配置即可。若非maven项目,将jar包下载后导入项目中。
org.apache.poi
poi
3.16
org.apache.poi
poi-ooxml
3.16
2.JSP
注意:类似于导出、下载的功能,均需要response实现输出,ajax不支持文件输出流,所以导出、下载功能均不能够利用ajax的方式实现。一般采取超链接或构造表单提交form实现。
在正常的业务中,一般规则为“所见及所得”,所以导出Excel时需要关联查询区域的查询条件进行导出,所以在此例中,利用基本的查询表单实现导出Excel的功能。
3.JS
/**
* 页面初始化
*/
$(document).ready(function () {
$("#exportExcelStudent").on("click",exportExcelStudent); //导出Excel按钮绑定事件
});
/**
* 导出Excel
* @returns
*/
function exportExcelStudent(){
//定义URL为导出Excel的后台请求地址
var url = "../file/demoStudentFile/exportExcel";
//将URL加至form的action中
$("#search-form").attr("action",url);
//提交form表单
$("#search-form").form('submit',{});
}
4.实体类 DemoStudent.java
package com.project.entity.demo;
import com.project.entity.BaseEntity;
/**
* @author hmz 2017年12月25日 下午5:05:03 学生实体类
*/
@SuppressWarnings("serial")
public class DemoStudent extends BaseEntity {
private String stuId;// 学生id
private String name;// 学生姓名
private String sex;// 学生性别
private String phone;// 学生电话
private String address;// 学生地址
private String message;// 学生自我评价
private String fkFileId;// 附件ID
private String fkFileName;// 附件名称
public String getStuId() {
return stuId;
}
public void setStuId(String stuId) {
this.stuId = stuId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getFkFileId() {
return fkFileId;
}
public void setFkFileId(String fkFileId) {
this.fkFileId = fkFileId;
}
public String getFkFileName() {
return fkFileName;
}
public void setFkFileName(String fkFileName) {
this.fkFileName = fkFileName;
}
}
5.Controller层 DemoStudentFileController.java 主要用于获取前台参数并调用Service中方法
package com.project.controller.demo;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
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.ResponseBody;
import com.project.entity.demo.DemoStudent;
import com.project.service.demo.DemoStudentService;
import com.project.util.cipher.CipherTransport;
/**
* @ClassName: DemoStudentFileController
* @Description: TODO
* @author: HeMengZhu
* @date: 2018年2月28日 下午3:49:22
*/
@Controller
@CipherTransport
@RequestMapping("/file/demoStudentFile")
public class DemoStudentFileController {
@Autowired
private DemoStudentService demoStudentService;
/**
* 导出Excel
* @Title: exportExcel
* @Description: TODO
* @param param 查询参数
* @param response
* @throws IOException
* @return: void
*/
@ResponseBody
@RequestMapping(value = "/exportExcel", method = RequestMethod.POST)
public void exportExcel(DemoStudent stu, HttpServletResponse response) throws IOException {
demoStudentService.exportExcel(stu, response);
}
}
6.Service层 DemoStudentService.java 主要处理业务逻辑并访问公用方法将数据写入Excel并导出
package com.project.service.demo;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.activiti.engine.impl.util.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.project.entity.demo.DemoStudent;
import com.project.mapper.demo.DemoStudentMapper;
import com.project.util.ConstUtil;
import com.project.util.file.ExportExcelUtil;
import com.project.util.file.FileConstUtil;
import com.project.util.file.FileValidateUtil;
import com.project.util.file.ImportExcelUtil;
/**
* @ClassName: DemoStudentService
* @Description: TODO
* @author: HeMengZhu
* @date: 2018年2月28日 下午3:52:03
*/
@Service
public class DemoStudentService {
@Autowired
private DemoStudentMapper demoStudentMapper;
@Autowired
private DemoFileService demoFileService;
/**
* 导出表格
* @Title: exportExcel
* @Description: TODO
* @param stu
* @param response
* @return
* @throws IOException
* @return: boolean
*/
@Transactional
public void exportExcel(DemoStudent stu, HttpServletResponse response) throws IOException {
try {
// 获取要导出的数据集合
List list = demoStudentMapper.excelList(stu);
// 组装数据格式
List> tableList = new ArrayList<>();
// 示例中只导出一个sheet页
List tableList_1 = new ArrayList();
int tableNum_1 = 1;
for (DemoStudent demoStudent : list) {
// 数组长度要与FileConstUtil.DemoStudentMessage.EXCEL_HEADER常量类中对应的各个sheet页的标题行长度一致,否则报空指针错误
String[] s = new String[FileConstUtil.DemoStudentMessage.EXCEL_HEADER.get(0).length];
s[0] = tableNum_1++ + "";
s[1] = demoStudent.getName() == null ? "" : demoStudent.getName(); // 姓名
s[2] = demoStudent.getSex() == null ? "" : demoStudent.getSex(); // 性别
s[3] = demoStudent.getPhone() == null ? "" : demoStudent.getPhone(); // 电话
tableList_1.add(s);
}
// 将第一个sheet页数据放在集合中
tableList.add(tableList_1);
// 调用导出Excel工具类
ExportExcelUtil util = new ExportExcelUtil();
util.exportExcelsUtil(FileConstUtil.DemoStudentMessage.EXCEL_NAME, FileConstUtil.DemoStudentMessage.EXCEL_SHEET_NAME, FileConstUtil.DemoStudentMessage.EXCEL_TITLE,
FileConstUtil.DemoStudentMessage.EXCEL_HEADER, tableList, response);
} catch (Exception e) {
e.printStackTrace();
}
}
}
7.Mapper层 DemoStudentMapper.java 接口,与XML文件相对应,实现对数据库的访问和操作
package com.project.mapper.demo;
import java.util.List;
import java.util.Map;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import com.project.entity.demo.DemoStudent;
/**
* @author hmz 2018年02月27日 下午8:01:00 示例-测试学生Mapper
*/
@Repository
public interface DemoStudentMapper {
/**
* 获取导出表格数据集合
* @Title: excelList
* @Description: TODO
* @param stu
* @return
* @return: List
*/
List excelList(DemoStudent stu);
}
8.Mapper层 DemoStudentMapper.xml 主要包含数据库字段和实体类的映射关系和对数据库执行的SQL语句
9.常量类 FileConstUtil.java 主要定义导出表格中的一些常量,比如标题、表头等等
package com.project.util.file;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* @ClassName: FileConstUtil
* @Description: TODO文件信息常量类
* @author: HeMengZhu
* @date: 2018年2月28日 下午4:23:43
*/
public class FileConstUtil {
/**
* 导出表格信息
* @ClassName: DemoStudentMessage
* @Description: TODO
* @author: HeMengZhu
* @date: 2018年2月28日 下午4:24:24
*/
public static class DemoStudentMessage {
/**
* 导出表格名称
*/
public static final String EXCEL_NAME = "学生信息.xlsx";
/**
* 导出表格sheet页名称
*/
public static final List EXCEL_SHEET_NAME = Arrays.asList("学生信息");
/**
* 导出表格sheet页标题
*/
public static final List EXCEL_TITLE = Arrays.asList("学生信息");
/**
* 导出表格sheet页标题行
*/
public static final List EXCEL_HEADER = getExcelHeader();
/**
* 组装各个sheet页标题行为一个list,各个标题行单元格以数组形式组装
* @Title: getExcelHeader
* @Description: TODO
* @return
* @return: List
*/
public static List getExcelHeader() {
List excelHeader = new ArrayList<>();
String[] title_1 = new String[] { "序号", "姓名", "性别", "电话" };
excelHeader.add(title_1);
return excelHeader;
}
}
}
10.工具类 ExportExcelUtil.java 主要为导出Excel的数据写入及输出文件流等操作;包括导出单个Sheet页和多个Sheet页的方法。此例为调用多个Sheet页方法
package com.project.util.file;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.List;
import java.util.UUID;
import javax.servlet.http.HttpServletResponse;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
* @ClassName: ExportExcelUtil
* @Description: TODO
* @author: HeMengZhu
* @date: 2018年2月28日 下午5:01:15
*/
@Service
public class ExportExcelUtil {
private final static String excel2003L = ".xls"; // 2003- 版本的excel
private final static String excel2007U = ".xlsx"; // 2007+ 版本的excel
/**
* 导出Excel:单个sheet页
* @param fileName 默认导出Excel文件名(带后缀格式)
* @param title 表标题:可传Null
* @param titleList 表头
* @param tableList 数据
* @param response
* @throws IOException
*/
@Transactional
public void exportExcelUtil(String fileName, String title, List titleList, List tableList, HttpServletResponse response) throws IOException {
OutputStream os = null;
XSSFWorkbook wb = new XSSFWorkbook();
try {
String name = UUID.randomUUID().toString() + fileName.substring(0, fileName.lastIndexOf("."));
String ext = fileName.substring(fileName.lastIndexOf("."));
// 生成临时文件
File file = File.createTempFile(name, ext);
XSSFSheet sheet = wb.createSheet(fileName.substring(0, fileName.lastIndexOf(".")));
XSSFRow row = null;
XSSFCell cell = null;
CellStyle css = setTitleStyle(wb); // Excel标题样式
CellStyle cs = setSimpleCellStyle(wb); // Excel单元格样式
int row_index = 0;
// 插入标题
if (title != null && title.trim().length() != 0) {
row = sheet.createRow(row_index++);
cell = row.createCell(0);
cell.setCellValue(title);
cell.setCellStyle(css);
}
if (titleList != null && title != null && title.trim().length() != 0) {
sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, titleList.size() - 1));// 横向:合并第一行的第2列到第4列
}
// 插入表头
if (titleList != null) {
row = sheet.createRow(row_index++);
for (int i = 0; i < titleList.size(); i++) {
cell = row.createCell(i);
cell.setCellValue(titleList.get(i));
cell.setCellStyle(css);
// 自动适应列宽
sheet.autoSizeColumn(i);
}
}
// 插入数据
for (String[] item : tableList) {
row = sheet.createRow(row_index++); // 创建新的ROW,用于数据插入
// 将对象数据插入到Excel中
if (null == item || item.length == 0) {
break;
}
// Cell赋值开始
for (int i = 0; i < item.length; i++) {
cell = row.createCell(i);
cell.setCellValue(item[i]);
cell.setCellStyle(cs);
}
}
response.setContentType("application/vnd.ms-excel;charset=UTF-8");
response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "utf-8"));
os = response.getOutputStream();
wb.write(os);
file.delete();
} catch (Exception e) {
e.printStackTrace();
} finally {
os.flush();
os.close();
wb.close();
}
}
/**
* 导出Excel:多个sheet页
* @Title: exportExcelsUtil
* @Description: TODO
* @param fileName 默认导出Excel文件名(带后缀格式)
* @param sheetName 表格多个sheet页名称
* @param titles 表格多个sheet页标题,可传null
* @param headerList 表格多个sheet页标题行数据
* @param tableList 表格多个sheet页表格数据
* @param response
* @throws IOException
* @return: void
*/
@Transactional
public void exportExcelsUtil(String fileName, List sheetName, List titles, List headerList, List> tableList, HttpServletResponse response)
throws IOException {
OutputStream os = null;
XSSFWorkbook wb = new XSSFWorkbook();
try {
String name = UUID.randomUUID().toString() + fileName.substring(0, fileName.lastIndexOf("."));
String ext = fileName.substring(fileName.lastIndexOf("."));
// 生成临时文件
File file = File.createTempFile(name, ext);
// 循环创建Sheet页,插入数据
for (int i = 0; i < sheetName.size(); i++) {
XSSFSheet sheet = wb.createSheet(sheetName.get(i));
XSSFRow row = null;
XSSFCell cell = null;
CellStyle css = setTitleStyle(wb); // Excel标题样式
int row_index = 0;
// 插入标题
if (titles.get(i) != null && titles.get(i).trim().length() != 0) {
row = sheet.createRow(row_index++);
cell = row.createCell(0);
cell.setCellValue(titles.get(i));
cell.setCellStyle(css);
}
String[] headerItem = null;
if (headerList.size() > i && titles.get(i) != null && titles.get(i).trim().length() != 0) {
headerItem = headerList.get(i);
sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, headerItem.length - 1));// 横向:合并第一行的第2列到第4列
}
// 插入表头
if (headerItem != null) {
row = sheet.createRow(row_index++);
for (int j = 0; j < headerItem.length; j++) {
cell = row.createCell(j);
cell.setCellValue(headerItem[j]);
cell.setCellStyle(css);
// 自动适应列宽
sheet.autoSizeColumn(j);
}
}
// 插入数据
List tableItem = null;
if (tableList.size() > i) {
tableItem = tableList.get(i);
}
if (tableItem != null) {
for (String[] item : tableItem) {
row = sheet.createRow(row_index++); // 创建新的ROW,用于数据插入
// 将对象数据插入到Excel中
if (null == item || item.length == 0) {
break;
}
// Cell赋值开始
for (int k = 0; k < item.length; k++) {
CellStyle cs = setSimpleCellStyle(wb); // Excel单元格样式
cell = row.createCell(k);
cell.setCellValue(item[k]);
if (item[k] != null && item[k].length() > 10) {
cs.setAlignment(CellStyle.ALIGN_LEFT); // 居左
} else {
cs.setAlignment(CellStyle.ALIGN_CENTER); // 居中
}
cell.setCellStyle(cs);
}
}
}
}
response.setContentType("application/vnd.ms-excel;charset=UTF-8");
response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "utf-8"));
os = response.getOutputStream();
wb.write(os);
file.delete();
} catch (Exception e) {
e.printStackTrace();
} finally {
os.flush();
os.close();
wb.close();
}
}
/**
* 描述:根据文件路径获取项目中的文件
* @param fileDir 文件路径
* @return
* @throws Exception
*/
public File getExcelDemoFile(String fileDir) throws Exception {
String classDir = null;
String fileBaseDir = null;
File file = null;
classDir = Thread.currentThread().getContextClassLoader().getResource("/").getPath();
fileBaseDir = classDir.substring(0, classDir.lastIndexOf("classes"));
file = new File(fileBaseDir + fileDir);
if (!file.exists()) {
throw new Exception("模板文件不存在!");
}
return file;
}
/**
* 描述:根据文件后缀,自适应模板文件的版本
* @param inStr,fileName
* @return
* @throws Exception
*/
public Workbook getWorkbook(InputStream inStr, String fileName) throws Exception {
Workbook wb = null;
String fileType = fileName.substring(fileName.lastIndexOf("."));
if (excel2003L.equals(fileType)) {
wb = new HSSFWorkbook(inStr);
} else if (excel2007U.equals(fileType)) {
wb = new XSSFWorkbook(inStr);
} else {
throw new Exception("解析的文件格式有误!");
}
return wb;
}
/**
* 描述:设置简单的Cell样式
* @return
*/
public CellStyle setSimpleCellStyle(Workbook wb) {
CellStyle cs = wb.createCellStyle();
cs.setBorderBottom(CellStyle.BORDER_THIN); // 下边框
cs.setBorderLeft(CellStyle.BORDER_THIN);// 左边框
cs.setBorderTop(CellStyle.BORDER_THIN);// 上边框
cs.setBorderRight(CellStyle.BORDER_THIN);// 右边框
cs.setVerticalAlignment(CellStyle.VERTICAL_CENTER);// 垂直居中
cs.setWrapText(true);// 自动换行
return cs;
}
/**
* 描述:设置表头样式
* @param workbook
* @return
*/
public CellStyle setTitleStyle(Workbook workbook) {
CellStyle cs = workbook.createCellStyle();
cs.setBorderBottom(CellStyle.BORDER_THIN); // 下边框
cs.setBorderLeft(CellStyle.BORDER_THIN);// 左边框
cs.setBorderTop(CellStyle.BORDER_THIN);// 上边框
cs.setBorderRight(CellStyle.BORDER_THIN);// 右边框
cs.setVerticalAlignment(CellStyle.VERTICAL_CENTER);// 垂直居中
cs.setAlignment(CellStyle.ALIGN_CENTER); // 居中
// 设置字体:
Font font = workbook.createFont();
font.setFontName("黑体");
font.setFontHeightInPoints((short) 12);// 设置字体大小
font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);// 粗体显示
cs.setFont(font);
return cs;
}
}