前言
在系统中,数据库的excel文件导出是一项及为基础的功能。此篇文章将通过实例利用poi实现excel文件导出。
一、POI、HFFS是什么?
POI
Jakarta POI 是apache的子项目,目标是处理ole2对象。它提供了一组操纵Windows文档的Java API 。目前比较成熟的是HSSF接口,处理MS Excel(97-2002)对象。它不象我们仅仅是用csv生成的没有格式的可以由Excel转换的东西,而是真正的Excel对象,你可以控制一些属性如sheet,cell等等。
HFFS
HSSF 是Horrible SpreadSheet Format的缩写,也即“讨厌的电子表格格式”。 也许HSSF的名字有点滑稽,就本质而言它是一个非常严肃、正规的API。通过HSSF,你可以用纯Java代码来读取、写入、修改Excel文件。 HSSF 为读取操作提供了两类API:usermodel和eventusermodel,即“用户模型”和“事件-用户模型”。前者很好理解,后者比较抽象,但操作效率要高得多。
参考文档
POI 主页:http://jakarta.apache.org/poi/ 初学者如何快速上手使用POI HSSF:http://jakarta.apache.org/poi/hssf/quick-guide.html
二、使用步骤
1.引入poi依赖包
<!--读取excel文件的包-->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.16</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.16</version>
</dependency>
2.创建工具类ExportExcel、ClassUtils
ExportExcel.java
public class ExportExcel<T> {
public static boolean flag = true;
public static void exportExcel(List dataList, ServletOutputStream out) throws IllegalAccessException, IOException {
if (dataList.isEmpty()) {
return;
}
List<String> fieldList = ClassUtils.getFields(dataList.get(0).getClass());
List<String> fieldNameList = ClassUtils.getFieldNames(dataList.get(0).getClass());
HSSFWorkbook workbook = new HSSFWorkbook();
HSSFSheet sheet = workbook.createSheet();
HSSFRow row = sheet.createRow(0);
HSSFCellStyle hssfCellStyle = workbook.createCellStyle();
hssfCellStyle.setAlignment(HorizontalAlignment.CENTER);
HSSFCell hssfCell;
for (int i = 0; i < fieldNameList.size(); i++) {
hssfCell = row.createCell(i);
hssfCell.setCellValue(fieldNameList.get(i));
hssfCell.setCellStyle(hssfCellStyle);
}
Map<String, Object> dataMap;
for (int i = 0; i < dataList.size(); i++) {
row = sheet.createRow(i + 1);
dataMap = ClassUtils.getFieldOfValue(dataList.get(i));
for (int j = 0; j < fieldList.size(); j++) {
row.createCell(j).setCellValue("" + dataMap.get(fieldList.get(j)));
}
}
workbook.write(out);
out.flush();;
out.close();
}
}
ClassUtils.java
public class ClassUtils {
public static List<String> getFields(Class<?> target) {
List<String> fieldList = new ArrayList<>();
Field[] declaredFields = target.getDeclaredFields();
for(Field field : declaredFields) {
fieldList.add(field.getName());
}
return fieldList;
}
public static List<String> getFieldNames(Class<?> target) {
List<String> fieldList = new ArrayList<>();
Field[] declaredFields = target.getDeclaredFields();
for(Field field : declaredFields) {
fieldList.add(field.getAnnotation(FieldName.class).value());
}
return fieldList;
}
public static <T> Map<String, Object> getFieldOfValue(T data) throws IllegalAccessException {
Field[] declaredFields = data.getClass().getDeclaredFields();
Map<String, Object> fieldMap = new HashMap<>(declaredFields.length);
for (Field field : declaredFields) {
field.setAccessible(true);
fieldMap.put(field.getName(), field.get(data));
}
return fieldMap;
}
}
3.通过例子实现文件导出
3.1 创建导出实体类 ImportTemplate
@Data
public class ImportTemplate {
@FieldName("ID")
private Integer ID;
@FieldName("标题")
private String task;
@FieldName("需求")
private String demand;
@FieldName("迭代")
private String iteration;
@FieldName("处理人")
private String member;
@FieldName("项目名称")
private String project;
@FieldName("需求ID")
private Integer demandID;
}
3.2 创建导出文件导出方法与实现
void downloadTemplate(ServletOutputStream out) throws IOException, IllegalAccessException;
@Override
public void downloadTemplate(ServletOutputStream out) throws IOException, IllegalAccessException {
List<ImportTemplate> resultList = new ArrayList<>();
ImportTemplate template = new ImportTemplate();
template.setID(1013516);
template.setTask("这里是任务名称");
template.setDemand("这里是需求名称");
template.setIteration("这里是迭代名");
template.setMember("李四");
template.setProject("这里是项目名");
template.setDemandID(1023123);
resultList.add(template);
ExportExcel.exportExcel(resultList, out);
if (ExportExcel.flag == false){
System.out.println("数据表导入模板导出出错×");
}
}
3.3 创建文件导出接口
@GetMapping("/downloadTemplate")
@ApiOperation(value="下载数据表导入模板", notes="详细描述")
@ResponseBody
public void downloadTemplate(HttpServletResponse response) throws IOException, IllegalAccessException {
response.setContentType("application/binary;charset=UTF-8");
response.setHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode("数据表导入模板"+".xls", "UTF-8"));
ServletOutputStream out = response.getOutputStream();
rawdataService.downloadTemplate(out);
}
后话
以上只是通过一个简单的案例实现数据库数据封装信息的文件导出,poi对excel文件的处理还有很多有意思的地方,对报表业务的功能大有建树,属于比较底层的excel文件处理插件,用于此功能阿里也有一套EasyExcel poi插件,主要解决poi框架使用复杂,sax解析模式不容易操作,数据量大起来容易OOM,解决了POI并发造成的报错。
|