From d7476276f079f2c31d4f974b686307e750cb5fba Mon Sep 17 00:00:00 2001 From: xiangwb Date: Mon, 20 Nov 2017 17:46:27 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0excel=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- boot-service/pom.xml | 13 + .../com/xwbing/constant/CommonConstant.java | 8 + .../com/xwbing/domain/entity/dto/UserDto.java | 19 ++ .../xwbing/service/sys/SysUserService.java | 60 +++- .../main/java/com/xwbing/util/ExcelUtil.java | 293 ++++++++++++++++++ .../xwbing/controller/sys/SysUserControl.java | 8 + 6 files changed, 400 insertions(+), 1 deletion(-) create mode 100644 boot-service/src/main/java/com/xwbing/domain/entity/dto/UserDto.java create mode 100644 boot-service/src/main/java/com/xwbing/util/ExcelUtil.java diff --git a/boot-service/pom.xml b/boot-service/pom.xml index 7543839..06169f7 100644 --- a/boot-service/pom.xml +++ b/boot-service/pom.xml @@ -72,6 +72,19 @@ bcprov-jdk16 1.45 + + + org.apache.poi + poi + 3.14 + + + org.apache.poi + poi-ooxml + 3.14 + + + javax.servlet diff --git a/boot-service/src/main/java/com/xwbing/constant/CommonConstant.java b/boot-service/src/main/java/com/xwbing/constant/CommonConstant.java index 3edfe5c..890200a 100644 --- a/boot-service/src/main/java/com/xwbing/constant/CommonConstant.java +++ b/boot-service/src/main/java/com/xwbing/constant/CommonConstant.java @@ -40,4 +40,12 @@ public class CommonConstant { * 权限树 */ public static final String AUTHORITY_THREE = "authority_three"; + /** + * 导出报表文件名称 + */ + public static final String USER_REPORT_FILE_NAME = "人员统计报表.xls"; + /** + * 导出报表列名称 + */ + public static final String[] USER_REPORT_COLUMNS = new String[]{" 名字", "用户名", "性别", "邮箱", "是否为管理员"}; } diff --git a/boot-service/src/main/java/com/xwbing/domain/entity/dto/UserDto.java b/boot-service/src/main/java/com/xwbing/domain/entity/dto/UserDto.java new file mode 100644 index 0000000..91b200e --- /dev/null +++ b/boot-service/src/main/java/com/xwbing/domain/entity/dto/UserDto.java @@ -0,0 +1,19 @@ +package com.xwbing.domain.entity.dto; + +import lombok.Data; + +/** + * 项目名称: boot-module-demo + * 创建时间: 2017/11/20 17:18 + * 作者: xiangwb + * 说明: + */ +@Data +public class UserDto { + //excel导出字段的顺序 + private String name; + private String userName; + private String sex; + private String mail; + private String isAdmin; +} diff --git a/boot-service/src/main/java/com/xwbing/service/sys/SysUserService.java b/boot-service/src/main/java/com/xwbing/service/sys/SysUserService.java index 0a1d517..f4064ae 100644 --- a/boot-service/src/main/java/com/xwbing/service/sys/SysUserService.java +++ b/boot-service/src/main/java/com/xwbing/service/sys/SysUserService.java @@ -3,16 +3,21 @@ package com.xwbing.service.sys; import com.alibaba.fastjson.JSONObject; import com.xwbing.constant.CommonConstant; import com.xwbing.constant.CommonEnum; +import com.xwbing.domain.entity.dto.UserDto; import com.xwbing.domain.entity.model.EmailModel; import com.xwbing.domain.entity.sys.*; -import com.xwbing.exception.BusinessException; import com.xwbing.domain.repository.sys.SysUserRepository; +import com.xwbing.exception.BusinessException; import com.xwbing.util.*; import org.apache.commons.collections.CollectionUtils; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.springframework.stereotype.Service; import javax.annotation.Resource; +import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.BufferedOutputStream; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; @@ -328,6 +333,59 @@ public class SysUserService { return list; } + /** + * 导出excel + */ + public void exportReport(HttpServletResponse response) { + String fileName = CommonConstant.USER_REPORT_FILE_NAME;//文件名 + try { + ServletOutputStream outputStream = response.getOutputStream(); + BufferedOutputStream bufferedOutPut = new BufferedOutputStream(outputStream); + fileName = new String(fileName.getBytes("GBK"), "ISO8859-1"); + response.reset(); + response.setHeader("Content-Disposition", "attachment;filename=" + fileName);// 指定下载的文件名 + response.setContentType("application/vnd.ms-excel"); + response.setHeader("Pragma", "no-cache"); + response.setHeader("Cache-Control", "no-cache"); + response.setDateHeader("Expires", 0); + List listDto = getReportList();//内容list + if (CollectionUtils.isEmpty(listDto)) { + return; + } + List list = ExcelUtil.convert2List(listDto); + String title = CommonConstant.USER_REPORT_FILE_NAME; + String[] columns = CommonConstant.USER_REPORT_COLUMNS; + bufferedOutPut.flush(); + HSSFWorkbook wb = ExcelUtil.Export(title, columns, list); + wb.write(bufferedOutPut); + bufferedOutPut.close(); + } catch (Exception e) { + throw new BusinessException("导出excel错误"); + } + } + + /** + * 获取excel导出列表所需数据 + * + * @return + */ + private List getReportList() { + List listDto = new ArrayList<>(); + List list = sysUserRepository.findAll(); + if (CollectionUtils.isNotEmpty(list)) { + for (SysUser info : list) { + UserDto temp = new UserDto(); + temp.setIsAdmin(CommonEnum.YesOrNoEnum.YES.getCode().equals(info.getAdmin()) ? "是" : "否"); + temp.setMail(info.getMail()); + temp.setName(info.getName()); + temp.setSex(Integer.valueOf(info.getSex()) == 1 ? "男" : "女"); + temp.setUserName(info.getUserName()); + listDto.add(temp); + } + } + return listDto; + } + /** * 根据用户名查找用户 * diff --git a/boot-service/src/main/java/com/xwbing/util/ExcelUtil.java b/boot-service/src/main/java/com/xwbing/util/ExcelUtil.java new file mode 100644 index 0000000..a0dbf91 --- /dev/null +++ b/boot-service/src/main/java/com/xwbing/util/ExcelUtil.java @@ -0,0 +1,293 @@ +package com.xwbing.util; + +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.io.FilenameUtils; +import org.apache.poi.hssf.usermodel.*; +import org.apache.poi.ss.usermodel.*; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +/** + * 项目名称: boot-module-demo + * 创建时间: 2017/11/20 17:07 + * 作者: xiangwb + * 说明: excel导出工具类 + */ +public class ExcelUtil { + /** + * Excel 2003 + */ + public final static String XLS = "xls"; + /** + * Excel 2007 + */ + public final static String XLSX = "xlsx"; + /** + * 分隔符 + */ + public final static String SEPARATOR = ";"; + + /** + * 由Excel文件的Sheet导出至List + * + * @param file + * @param sheetNum + * @return + */ + private static List exportListFromExcel(File file, int sheetNum) throws IOException { + return exportListFromExcel(new FileInputStream(file), FilenameUtils.getExtension(file.getName()), sheetNum); + } + + /** + * 由Excel流的Sheet导出至List + * + * @param is + * @param extensionName + * @param sheetNum + * @return + * @throws IOException + */ + private static List exportListFromExcel(InputStream is, String extensionName, int sheetNum) throws IOException { + Workbook workbook = null; + if (extensionName.toLowerCase().equals(XLS)) { + workbook = new HSSFWorkbook(is); + } else if (extensionName.toLowerCase().equals(XLSX)) { + workbook = new XSSFWorkbook(is); + } + return exportListFromExcel(workbook, sheetNum); + } + + /** + * 由指定的Sheet导出至List + * + * @param workbook + * @param sheetNum + * @return + * @throws IOException + */ + private static List exportListFromExcel(Workbook workbook, int sheetNum) { + Sheet sheet = workbook.getSheetAt(sheetNum); + // 解析公式结果 + FormulaEvaluator evaluator = workbook.getCreationHelper().createFormulaEvaluator(); + List list = new ArrayList<>(); + int minRowIx = sheet.getFirstRowNum(); + int maxRowIx = sheet.getLastRowNum(); + for (int rowIx = minRowIx; rowIx <= maxRowIx; rowIx++) { + org.apache.poi.ss.usermodel.Row row = sheet.getRow(rowIx); + StringBuilder sb = new StringBuilder(); + short minColIx = row.getFirstCellNum(); + short maxColIx = row.getLastCellNum(); + for (short colIx = minColIx; colIx <= maxColIx; colIx++) { + Cell cell = row.getCell((int) colIx); + CellValue cellValue = evaluator.evaluate(cell); + if (cellValue == null) { + continue; + } + // 经过公式解析,最后只存在Boolean、Numeric和String三种数据类型,此外就是Error了 + // 其余数据类型,根据官方文档,完全可以忽略http://poi.apache.org/spreadsheet/eval.html + switch (cellValue.getCellType()) { + case Cell.CELL_TYPE_BOOLEAN: + sb.append(SEPARATOR + cellValue.getBooleanValue()); + break; + case Cell.CELL_TYPE_NUMERIC: + // 这里的日期类型会被转换为数字类型,需要判别后区分处理 + if (DateUtil.isCellDateFormatted(cell)) { + sb.append(SEPARATOR + cell.getDateCellValue()); + } else { + sb.append(SEPARATOR + cellValue.getNumberValue()); + } + break; + case Cell.CELL_TYPE_STRING: + sb.append(SEPARATOR + cellValue.getStringValue()); + break; + case Cell.CELL_TYPE_FORMULA: + break; + case Cell.CELL_TYPE_BLANK: + break; + case Cell.CELL_TYPE_ERROR: + break; + default: + break; + } + } + list.add(sb.substring(1, sb.length())); + } + return list; + } + + /** + * 将导入的excel文件生成类 + * + * @param file excel文件 + * @param sheetNum excel页签 + * @param classVO 要导出的类型 + * @return + */ + public static List getObjectFromExcel(File file, int sheetNum, Class classVO) { + List resultList = new ArrayList<>(); + T obj; + try { + // 获取解析结果:每行是一个String + // 格式:[Name;Sex;Email;NeedRePswd;Status;UserName;NickName;UnitId;Rank;Office, + // INPUT111;1.0;INPUT111@sss.com;0.0;1.0;INPUT111;INPUT111;asdfasdfasdfasdf;1.0, + // INPUT222;1.0;INPUT111@sss.com;0.0;1.0;INPUT111;INPUT111;asdfasdfasdfasdf;1.0] + List importObjects = exportListFromExcel(file, sheetNum); + if (CollectionUtils.isNotEmpty(importObjects)) { + // Class classVO = obj.getClass(); + Constructor cons[] = classVO.getConstructors(); + // 取出列名称用来设置set方法 + String colNames = importObjects.get(0); + // 解析列名 + String[] colName = colNames.split(";"); + String setMethodStr; + for (int i = 1; i < importObjects.size(); i++) { + // 解析数据 + String[] values = importObjects.get(i).split(SEPARATOR); + // 初始化对象 + try { + obj = (T) cons[0].newInstance(); + } catch (Exception e3) { + e3.printStackTrace(); + return null; + } + for (int j = 0; j < values.length; j++) { + // set方法名 + setMethodStr = "set" + colName[j]; + Method setMethod; + // 尝试调用set方法,因无法确定参数,尝试参数类型,目前只有String和Integer两种 + try { + setMethod = classVO.getMethod(setMethodStr, String.class); + setMethod.invoke(obj, String.valueOf(values[j])); + } catch (Exception e) { + try { + setMethod = classVO.getMethod(setMethodStr, Integer.class); + setMethod.invoke(obj, Double.valueOf(values[j]).intValue()); + } catch (Exception e1) { + // 目前没有bool值参数暂不添加 + // try + // { + // setMethod = + // classVO.getMethod(setMethodStr,Boolean.class); + // setMethod.invoke(obj, + // Boolean.valueOf(values[j])); + // } + // catch (Exception e3) + // { + // } + System.out.println("Exception" + e); + continue; + } + + } + } + resultList.add(obj); + } + } + + } catch (IOException e) { + e.printStackTrace(); + } + return resultList; + } + + /** + * 获取工作簿 + * @param title + * @param columns + * @param list + * @return + * @throws Exception + */ + public static HSSFWorkbook Export(String title, String[] columns, List list) throws Exception { + // 声明一个工作薄 + HSSFWorkbook wb = new HSSFWorkbook(); + // 声明一个单子并命名 + HSSFSheet sheet = wb.createSheet(title); + // 给单子名称一个长度 + sheet.setDefaultColumnWidth((short) 15); + // 生成一个样式 + HSSFCellStyle style = wb.createCellStyle(); + // 创建第一行(也可以称为表头) + HSSFRow row = sheet.createRow(0); + // 样式字体居中 + style.setAlignment(HSSFCellStyle.ALIGN_CENTER); + // 给表头第一行一次创建单元格 + if (null != columns && columns.length > 0) { + for (int i = 0; i < columns.length; i++) { + HSSFCell cell = row.createCell((int) i); + cell.setCellValue(columns[i]); + cell.setCellStyle(style); + } + } + if (CollectionUtils.isNotEmpty(list)) { + // 向单元格里填充数据 + for (int i = 0; i < list.size(); i++) { + row = sheet.createRow(i + 1); + assert columns != null; + for (int j = 0; j < columns.length; j++) { + row.createCell(j).setCellValue(list.get(i)[j]); + } + } + } + return wb; + } + + /** + * 将数据list转换成excel导出的形式 + * + * @param list + * @return + */ + public static List convert2List(List list) { + List result = new ArrayList<>(list.size()); + T obj4Class = list.get(0); + Class classOfT = obj4Class.getClass(); + Field[] declaredFields = classOfT.getDeclaredFields(); + String[] temp; + for (T obj : list) { + temp = new String[declaredFields.length]; + for (int i = 0; i < declaredFields.length; i++) { + String fieldName = declaredFields[i].getName(); + StringBuffer getMethodStr; + // 拼接get方法 + getMethodStr = new StringBuffer(); + getMethodStr.append("get"); + getMethodStr.append(fieldName.substring(0, 1).toUpperCase()); + getMethodStr.append(fieldName.substring(1)); + String value = ""; + Method getMethod; + try { + getMethod = classOfT.getMethod(getMethodStr.toString()); + } catch (NoSuchMethodException e1) { + System.out.println("NoSuchMethodException"); + continue; + } catch (SecurityException e1) { + System.out.println("SecurityException"); + continue; + } + // 执行get方法 + try { + value = String.valueOf(getMethod.invoke(obj, new Object[0])); + value = Objects.equals("null", value) ? null : value; + } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + temp[i] = value; + } + result.add(temp); + } + return result; + } +} diff --git a/boot-web/src/main/java/com/xwbing/controller/sys/SysUserControl.java b/boot-web/src/main/java/com/xwbing/controller/sys/SysUserControl.java index c224ec7..4d33003 100644 --- a/boot-web/src/main/java/com/xwbing/controller/sys/SysUserControl.java +++ b/boot-web/src/main/java/com/xwbing/controller/sys/SysUserControl.java @@ -24,6 +24,7 @@ import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; import javax.validation.Valid; import java.util.ArrayList; import java.util.List; @@ -211,4 +212,11 @@ public class SysUserControl { List list = sysUserService.queryAuthority(userId, enable); return JSONObjResult.toJSONObj(list, true, ""); } + + @LogInfo("导出用户excel表") + @GetMapping("exportReport") + @ApiOperation(value = "导出用户excel表") + public void exportReport(HttpServletResponse response) { + sysUserService.exportReport(response); + } }