在spring boot 的项目经常碰到将数据导出到Excel表格的需求,而POI技术则对于java操作Excel表格提供了API,POI中对于多种类型的文档都提供了操作的接口,但是其对于Excel表格的操作无疑是最强大的。
1.POI简介
Apache POI 是用 Java 编写的免费开源的跨平台的 Java API,Apache POI 提供 API 给 Java 程式对 Microsoft Office(Excel、WORD、PowerPoint、Visio 等,主要实现用于 Excel)格式档案读和写的功能,POI 为 “ Poor Obfuscation Implementation ” 的首字母缩写,意为简洁版的模糊实现。
POI结构:
1
2
3
4
5
6
7
8
|
HSSF - 提供读写Microsoft Excel XLS格式档案的功能。 XSSF - 提供读写Microsoft Excel OOXML XLSX格式档案的功能。 HWPF - 提供读写Microsoft Word DOC97格式档案的功能。 XWPF - 提供读写Microsoft Word DOC2003格式档案的功能。 HSLF - 提供读写Microsoft PowerPoint格式档案的功能。 HDGF - 提供读Microsoft Visio格式档案的功能。 HPBF - 提供读Microsoft Publisher格式档案的功能。 HSMF - 提供读Microsoft Outlook格式档案的功能。 |
因为使用的是POI对Excel的操作,所以先介绍一下HSSF中的常用类:
类名 说明 HSSFWorkbook Excel的文档对象 HSSFSheet Excel的表单 HSSFRow Excel的行 HSSFCell Excel的格子单元 HSSFFont Excel字体 HSSFDataFormat 格子单元的日期格式 HSSFHeader Excel文档Sheet的页眉 HSSFFooter Excel文档Sheet的页脚 HSSFCellStyle 格子单元样式 HSSFDateUtil 日期 HSSFPrintSetup 打印 HSSFErrorConstants 错误信息表
2.在项目中导入POI的依赖
<!-- https://mvnrepository.com/artifact/org.apache.poi/poi --> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>4.1.1</version> </dependency>
3.controller层
@GetMapping("/export") public ResponseEntity<byte[]> exportEmp(){ List list = 数据库查询到所有要导出的数据; return EmpUtils.exportEmp(employeeList); }
首先从数据库查询到具体的要导出到Excel的数据,controller层的返回值为ResponseEntity<byte[]>。
4.Java使用poi的构建Excel表格
public class EmpUtils { public static ResponseEntity<byte[]> exportEmp(List<Employee> employeeList) { //1.创建一个excel文档 HSSFWorkbook hssfWorkbook = new HSSFWorkbook(); //2.创建文档摘要 hssfWorkbook.createInformationProperties(); //3.获取并配置文档摘要信息 DocumentSummaryInformation docInfo = hssfWorkbook.getDocumentSummaryInformation(); //文档类别 docInfo.setCategory("XXX信息"); //文档管理员 docInfo.setManager("hope"); //文档所属公司 docInfo.setCompany("xxxx"); //文档版本 docInfo.setApplicationVersion(1); //4.获取文档摘要信息 SummaryInformation summaryInformation = hssfWorkbook.getSummaryInformation(); //文档标题 summaryInformation.setAuthor("hopec"); //文档创建时间 summaryInformation.setCreateDateTime(new Date()); //文档备注 summaryInformation.setComments("文档备注"); //5.创建样式 //创建标题行的样式 HSSFCellStyle headerStyle = hssfWorkbook.createCellStyle(); //设置该样式的图案颜色为黄色 // headerStyle.setFillForegroundColor(IndexedColors.GREEN.index);//设置图案颜色 // headerStyle.setFillBackgroundColor(IndexedColors.RED.index);//设置图案背景色 headerStyle.setFillForegroundColor(IndexedColors.YELLOW.index); //设置图案填充的样式 headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); //设置日期相关的样式 HSSFCellStyle dateCellStyle = hssfWorkbook.createCellStyle(); //这里的m/d/yy 相当于yyyy-MM-dd dateCellStyle.setDataFormat(HSSFDataFormat.getBuiltinFormat("m/d/yy")); HSSFSheet sheet = hssfWorkbook.createSheet("xxx信息表"); //设置每一列的宽度 sheet.setColumnWidth(0,5*256); sheet.setColumnWidth(1,12*256); sheet.setColumnWidth(2,10*256); sheet.setColumnWidth(3,5*256); sheet.setColumnWidth(4,16*256); sheet.setColumnWidth(5,20*256); sheet.setColumnWidth(6,10*256); sheet.setColumnWidth(7,10*256); sheet.setColumnWidth(8,18*256); sheet.setColumnWidth(9,12*256); //6.创建标题行 HSSFRow r0 = sheet.createRow(0); HSSFCell c0 = r0.createCell(0); c0.setCellValue("编号"); c0.setCellStyle(headerStyle); HSSFCell c1 = r0.createCell(1); c1.setCellStyle(headerStyle); c1.setCellValue("姓名"); HSSFCell c2 = r0.createCell(2); c2.setCellStyle(headerStyle); c2.setCellValue("工号"); HSSFCell c3 = r0.createCell(3); c3.setCellStyle(headerStyle); c3.setCellValue("性别"); HSSFCell c4 = r0.createCell(4); c4.setCellStyle(headerStyle); c4.setCellValue("出生日期"); HSSFCell c5 = r0.createCell(5); c5.setCellStyle(headerStyle); c5.setCellValue("身份证号码"); HSSFCell c6 = r0.createCell(6); c6.setCellStyle(headerStyle); c6.setCellValue("婚姻状况"); HSSFCell c7 = r0.createCell(7); c7.setCellStyle(headerStyle); c7.setCellValue("民族"); HSSFCell c8 = r0.createCell(8); c8.setCellStyle(headerStyle); c8.setCellValue("籍贯"); HSSFCell c9 = r0.createCell(9); c9.setCellStyle(headerStyle); c9.setCellValue("政治面貌"); HSSFCell c10 = r0.createCell(10); for (int i = 0; i < employeeList.size(); i++) { Employee employee= employeeList.get(i); HSSFRow row = sheet.createRow(i+1); row.createCell(0).setCellValue(employee.getId()); row.createCell(1).setCellValue(employee.getName()); row.createCell(2).setCellValue(employee.getWorkID()); row.createCell(3).setCellValue(employee.getGender()); HSSFCell cell4 = row.createCell(4); //单独设置日期的样式 cell4.setCellStyle(dateCellStyle); cell4.setCellValue(employee.getBirthday()); row.createCell(5).setCellValue(employee.getIdCard()); row.createCell(6).setCellValue(employee.getWedlock()); row.createCell(7).setCellValue(employee.getNation().getName()); row.createCell(8).setCellValue(employee.getNativePlace()); row.createCell(9).setCellValue(employee.getPoliticsstatus().getName()); } ByteArrayOutputStream stream = new ByteArrayOutputStream(); HttpHeaders headers = new HttpHeaders(); try { //将数据表这几个中文的字转码 防止导出后乱码 headers.setContentDispositionFormData("attachment", new String("数据表.xls".getBytes("UTF-8"),"ISO-8859-1")); headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); hssfWorkbook.write(stream); } catch (IOException e) { e.printStackTrace(); } return new ResponseEntity<byte[]>(stream.toByteArray(),headers, HttpStatus.CREATED); } }
5.页面调用
exportEmp(){ this.$confirm(\'此操作将导出员工数据, 是否继续?\', \'提示\', { confirmButtonText: \'确定\', cancelButtonText: \'取消\', type: \'warning\' }).then(() => { window.open(\'/employee/basic/export\',\'_parent\') }).catch(() => { this.$message({ type: \'info\', message: \'已取消导出\' }); }); },
其中/employee/basic/export为后台接口的restfulAPI地址。