ExcelExportUtil.java 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. package com.repair.common.utils;
  2. import org.apache.poi.hpsf.Decimal;
  3. import org.apache.poi.hssf.usermodel.HSSFWorkbook;
  4. import org.apache.poi.ss.usermodel.Cell;
  5. import org.apache.poi.ss.usermodel.Row;
  6. import org.apache.poi.ss.usermodel.Sheet;
  7. import org.apache.poi.ss.usermodel.Workbook;
  8. import org.apache.poi.xssf.usermodel.*;
  9. import javax.servlet.http.HttpServletResponse;
  10. import java.io.IOException;
  11. import java.io.OutputStream;
  12. import java.lang.reflect.Field;
  13. import java.lang.reflect.InvocationTargetException;
  14. import java.math.BigDecimal;
  15. import java.time.LocalDate;
  16. import java.util.*;
  17. /**
  18. * @Author: binguo
  19. * @Date: 2023/7/19 星期三 9:38
  20. * @Description: com.chuanghai.attendance.utils.excel
  21. * @Version: 1.0
  22. */
  23. public class ExcelExportUtil {
  24. /**
  25. * 将 List<Map<String,Object>> 类型的数据导出为 Excel
  26. */
  27. public static void createExcel(List<Map<String, Object>> mapList, String filename, String title, HttpServletResponse response) {
  28. //获取数据源的 key, 用于获取列数及设置标题
  29. Map<String, Object> map = mapList.get(0);
  30. Set<String> stringSet = map.keySet();
  31. ArrayList<String> headList = new ArrayList<>(stringSet);
  32. //定义一个新的工作簿
  33. XSSFWorkbook wb = new XSSFWorkbook();
  34. //创建一个Sheet页
  35. XSSFSheet sheet = wb.createSheet(title);
  36. //设置行高
  37. sheet.setDefaultRowHeight((short) (2 * 256));
  38. //为有数据的每列设置列宽
  39. for (int i = 0; i < headList.size(); i++) {
  40. sheet.setColumnWidth(i, 8000);
  41. }
  42. //设置单元格字体样式
  43. XSSFFont font = wb.createFont();
  44. font.setFontName("等线");
  45. font.setFontHeightInPoints((short) 16);
  46. //在sheet里创建第一行,并设置单元格内容为 title (标题)
  47. // XSSFRow titleRow = sheet.createRow(0);
  48. // XSSFCell titleCell = titleRow.createCell(0);
  49. // titleCell.setCellValue(title);
  50. //合并单元格CellRangeAddress构造参数依次表示起始行,截至行,起始列, 截至列
  51. // sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, headList.size() - 1));
  52. // // 创建单元格文字居中样式并设置标题单元格居中
  53. // XSSFCellStyle cellStyle = wb.createCellStyle();
  54. // cellStyle.setAlignment(HorizontalAlignment.CENTER);
  55. // titleCell.setCellStyle(cellStyle);
  56. //获得表格第二行
  57. XSSFRow row = sheet.createRow(0);
  58. //根据数据源信息给第二行每一列设置标题
  59. for (int i = 0; i < headList.size(); i++) {
  60. XSSFCell cell = row.createCell(i);
  61. cell.setCellValue(headList.get(i));
  62. }
  63. XSSFRow rows;
  64. XSSFCell cells;
  65. //循环拿到的数据给所有行每一列设置对应的值
  66. for (int i = 0; i < mapList.size(); i++) {
  67. //在这个sheet页里创建一行
  68. rows = sheet.createRow(i + 1);
  69. //给该行数据赋值
  70. for (int j = 0; j < headList.size(); j++) {
  71. String value;
  72. if (mapList.get(i).get(headList.get(j)) !=null){
  73. value = mapList.get(i).get(headList.get(j)).toString();
  74. }else {
  75. value = "";
  76. }
  77. cells = rows.createCell(j);
  78. cells.setCellValue(value);
  79. }
  80. }
  81. try {
  82. response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");//application/vnd.ms-excel");
  83. response.setHeader("Content-Disposition", "attachment;filename=".concat(filename));
  84. OutputStream out = response.getOutputStream();
  85. wb.write(out);
  86. wb.close();
  87. out.close();;
  88. } catch (IOException e) {
  89. e.printStackTrace();
  90. }
  91. }
  92. /**
  93. * @description 考虑到下载方式的不同 这里细化成只获取一个workBook 格式为默认 无格式
  94. * @param list 需要存储为excel的对象集合
  95. * @param map 键值对映射 属性 - 表头字段 类似于: name - 姓名
  96. * @param type 生成workbook的类型
  97. * @param tableName 生成Sheet的名称
  98. * @param orderList 表头顺序对应的属性list
  99. * @return org.apache.poi.ss.usermodel.Workbook
  100. **/
  101. public static <T> Workbook createWorkbook(
  102. List<T> list , //数据库查询的返回List
  103. Map<String , String> map , //表头映射
  104. Integer type , //生成workbook的类型 0 - xls 其他-xlsx
  105. String tableName , //表名
  106. List<String> orderList //排序的List 为空 则使用默认的顺序
  107. ) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException {
  108. //工作簿
  109. Workbook workbook = getWorkbookByType(type);
  110. //单个表
  111. Sheet sheet = workbook.createSheet(tableName);
  112. //orderList 表头顺序,可以为空
  113. if(orderList == null || orderList.size() == 0) {
  114. orderList = new ArrayList<>();
  115. //获取map映射的顺序
  116. for (Map.Entry<String, String> mapEntry : map.entrySet()) {
  117. orderList.add(mapEntry.getKey());
  118. }
  119. }
  120. //每列对应的属性参数
  121. List<Class> typeClassList = getParamsType(list.get(0).getClass(), orderList);
  122. //设置表头的值
  123. Row headRow = sheet.createRow(0);
  124. for (int i = 0; i < orderList.size(); i++) {
  125. Cell cell = headRow.createCell(i);
  126. //设置单元格的属性
  127. cell.setCellValue(map.get(orderList.get(i)));
  128. }
  129. int index = 1;
  130. //单元行
  131. Row dataRow = null;
  132. //单元格
  133. Cell dataCell = null;
  134. //遍历List
  135. for (T t : list) {
  136. //获取一行
  137. dataRow = sheet.createRow(index);
  138. //遍历表头对应属性,给一行数据设置值
  139. for (int j = 0; j < orderList.size(); j++) {
  140. //获取一个单元格
  141. dataCell = dataRow.createCell(j);
  142. //根据对应列的属性 设置对应的值类型及值
  143. setCellValueTypeAndValue(dataCell , typeClassList.get(j) ,
  144. t.getClass().getMethod(getGetterMethodName(orderList.get(j)) , new Class[]{})
  145. .invoke(t , new Class[]{}));
  146. }
  147. //行下标后移
  148. index++;
  149. }
  150. //设置值
  151. return workbook;
  152. }
  153. /**
  154. * @description 根据所给的type获取对应的工作簿 0-HSSFWorkbook 其他-XSSFWorkbook
  155. * @author 三文鱼先生
  156. * @date 10:41 2022/8/26
  157. * @param type 类型
  158. * @return org.apache.poi.ss.usermodel.Workbook
  159. **/
  160. public static Workbook getWorkbookByType(Integer type) {
  161. if(type == null || type == 0)
  162. return new HSSFWorkbook();
  163. else
  164. return new XSSFWorkbook();
  165. }
  166. /**
  167. * @description 根据属性的List获取对应的类型List
  168. * @author 三文鱼先生
  169. * @date 10:37 2022/8/26
  170. * @param cs 对应的类
  171. * @param paramsList 对应的属性list
  172. * @return java.util.List<java.lang.Class>
  173. **/
  174. public static List<Class> getParamsType(Class cs , List<String> paramsList) {
  175. List<Class> typeClass = new ArrayList<>();
  176. //对象的所有属性
  177. Field[] fields = cs.getDeclaredFields();
  178. //临时的属性 - 类型映射
  179. Map<String , Class> map = new HashMap();
  180. //获取属性名称及类型
  181. for (Field field : fields) {
  182. map.put(field.getName(), field.getType());
  183. }
  184. //遍历属性List获取对应的类型List
  185. for (String s : paramsList) {
  186. typeClass.add(map.get(s));
  187. }
  188. return typeClass;
  189. }
  190. /**
  191. * @description 根据对应的类型 给单元格设置类型和值
  192. * @author 三文鱼先生
  193. * @date 10:32 2022/8/26
  194. * @param cell 单元格
  195. * @param cs 属性的类型
  196. * @param o get方法获取到的对象
  197. * @return void
  198. **/
  199. public static void setCellValueTypeAndValue(Cell cell , Class cs , Object o) {
  200. if(Boolean.class.equals(cs) || boolean.class.equals(cs)) {
  201. //boolean类型
  202. cell.setCellValue((Boolean) o);
  203. } else if (int.class.equals(cs) || Integer.class.equals(cs)) {
  204. //int类型
  205. cell.setCellValue((Integer) o);
  206. } else if(double.class.equals(cs) || Double.class.equals(cs)) {
  207. //浮点数类型 也可以是float类型什么的
  208. cell.setCellValue((Double) o);
  209. }else if(BigDecimal.class.equals(cs) || Decimal.class.equals(cs)){
  210. //金钱类型
  211. cell.setCellValue(((BigDecimal) o).toString());
  212. } else if(LocalDate.class.equals(cs) || Date.class.equals(cs)){
  213. //日期类型
  214. cell.setCellValue(((LocalDate) o).toString());
  215. } else {
  216. //默认为字符串类型
  217. cell.setCellValue((String) o);
  218. }
  219. }
  220. /**
  221. * @description 根据属性名称获取对应的get方法
  222. * @author 三文鱼先生
  223. * @date 10:38 2022/8/26
  224. * @param param 属性名称
  225. * @return java.lang.String
  226. **/
  227. public static String getGetterMethodName(String param) {
  228. char[] chars = param.toCharArray();
  229. //首字母大写
  230. if(Character.isLowerCase(chars[0])) {
  231. chars[0] -= 32;
  232. }
  233. //拼接get方法
  234. return "get" + new String(chars);
  235. }
  236. }