在实际工作中 有时候我们经常需要将各种数据从数据库中查出来后,封装成excel文件供用户下载使用,特别是很多后台管理系统.但是其实这些代码其实基本都是固定的,那么我们不妨把它整理出来,当下次需要用到的时候直接Copy,大大提高我们的开发效率
使用下面模板时如果你是maven项目,需要导入apache POI依赖
<!-- 版本属性配置 -->
<properties>
<poi.version>3.11</poi.version>
</properties>
<!-- Excel解析工具类 -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>${poi.version}</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>${poi.version}</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-schemas</artifactId>
<version>${poi.version}</version>
</dependency>
其他Java项目需要导入poi jar包
@Override
public void exportXls() throws IOException {
// 先查询分区数据
List<SubArea> listSubarea = subAreaDao.findAll();
if (listSubarea != null && listSubarea.size() > 0) {
// 通过poi导出到页面 xls 2003
HSSFWorkbook hs = new HSSFWorkbook();// 创建一个文件对象
HSSFSheet createSheet = hs.createSheet();// sheet页对象
// 创建excel数据标题
HSSFRow titleRow = createSheet.createRow(0);// 创建行下标从0开始
titleRow.createCell(0).setCellValue("编号");
titleRow.createCell(1).setCellValue("关键字");
titleRow.createCell(2).setCellValue("辅助关键字");
titleRow.createCell(3).setCellValue("省市区");
titleRow.createCell(4).setCellValue("定区名称");
// 创建excel数据行
for (SubArea subArea : listSubarea) {
//创建数据行的编号是动态获取的
int lastRowNum = createSheet.getLastRowNum();
//创建数据行 从第2行开始
HSSFRow dataRow = createSheet.createRow(lastRowNum+1);
dataRow.createCell(0).setCellValue(subArea.getId());
dataRow.createCell(1).setCellValue(subArea.getKeyWords());
dataRow.createCell(2).setCellValue(subArea.getAssistKeyWords());
dataRow.createCell(3).setCellValue(subArea.getArea().getName());
dataRow.createCell(4).setCellValue(subArea.getFixedArea().getFixedAreaName());
}
//获取一个输出流 给HSSFWorkbook中write 一个流 两个头
ServletOutputStream outputStream = ServletActionContext.getResponse().getOutputStream();
String fileName = "分区数据.xls";
//获取当前浏览器
String agent = ServletActionContext.getRequest().getHeader("User-Agent");
//将文件名称转成浏览器认识编码方式
String newFileName = FileUtils.encodeDownloadFilename(fileName, agent);
//1.文件名称 setHeader:让浏览器识别当前下载是excel文件
ServletActionContext.getResponse().setHeader("content-disposition", "filename="+newFileName);
//2.文件后缀
ServletActionContext.getResponse().setContentType("application/vnd.ms-excel;charset=UTF-8");
hs.write(outputStream);
}
}
其中用到的将文件名称转成浏览器认识编码方式(解决中文文件名乱码问题)的根据类
public class FileUtils {
/**
* 下载文件时,针对不同浏览器,进行附件名的编码
*
* @param filename
* 下载文件名
* @param agent
* 客户端浏览器
* @return 编码后的下载附件名
* @throws IOException
*/
public static String encodeDownloadFilename(String filename, String agent)
throws IOException {
if (agent.contains("Firefox")) { // 火狐浏览器
filename = "=?UTF-8?B?"
+ new BASE64Encoder().encode(filename.getBytes("utf-8"))
+ "?=";
filename = filename.replaceAll("\r\n", "");
} else { // IE及其他浏览器
filename = URLEncoder.encode(filename, "utf-8");
filename = filename.replace("+"," ");
}
return filename;
}
}