查看: 577|回复: 0

[Java代码] java实现数据导出到excel

发表于 2018-2-1 08:00:03

controller层的代码

  1. @RequestMapping(value="")
  2. public void exportDangerInvestigation(HttpServletResponse response) throws com.client.util.ExcelException{
  3. //下面的方法是获得数据
  4. Pagination pg=inspectionInfoService.getdangerInvestigation(inspectionInfo, enterprise, type, PaginationUtil.getPageNo(pageNo),Integer.MAX_VALUE);
  5. //定义一个 fieldMap ,里面存放的key值要和查询出来的数据字段相对应,里面放的数据也是excel展示的数据
  6. Map<String, String> fieldMap = new HashMap<String, String>();
  7. fieldMap.put("UNIT_NAME", "单位名称");
  8. fieldMap.put("CHECK_PLACE", "检查地点");
  9. fieldMap.put("LEGAL_PERSON", "法定代表人");
  10. fieldMap.put("CITIZEN_PHONE", "联系电话");
  11. fieldMap.put("CHECK_LIST_CODE", "检查单号");
  12. fieldMap.put("CHECK_DATE", "检查日期");
  13. fieldMap.put("CHECK_RESULT", "检查结果");
  14. fieldMap.put("CHECK_EXPLAIN", "结果说明");
  15. try {
  16. //调用导出数据的方法
  17. ExcelUtil.listToExcel(pg.getList(), fieldMap, "隐患排查清单", Constans.EXCEL_MAX_ROWS,response);
  18. } catch (Exception e) {
  19. e.printStackTrace();
  20. }
  21. }
复制代码

ExcelUtil里面的方法

  1. public static <T> void listToExcel(List<T> list, Map<String, String> fieldMap, String sheetName, int sheetSize, HttpServletResponse response) throws ExcelException {
  2. if (list == null) {
  3. throw new ExcelException("数据源中没有任何数据");
  4. } else {
  5. if (list.size() == 0) {
  6. throw new ExcelException("数据源中没有任何数据");
  7. }
  8. }
  9. // 设置默认文件名为当前时间:年月日时分秒
  10. String fileName = new SimpleDateFormat("yyyyMMddhhmmss").format(new Date()).toString();
  11. // 设置response头信息
  12. response.reset();
  13. response.setContentType("application/vnd.ms-excel"); // 改成输出excel文件
  14. response.setHeader("Content-disposition", "attachment; filename=" + fileName + ".xls");
  15. // 创建工作簿并发送到浏览器+
  16. OutputStream out = null;
  17. try {
  18. out = response.getOutputStream();
  19. listToExcel(list, fieldMap, sheetName, sheetSize, out);
  20. } catch (Exception e) {
  21. e.printStackTrace();
  22. try {
  23. out.close();
  24. } catch (Exception ee) {
  25. ee.printStackTrace();
  26. // TODO Auto-generated catch block
  27. throw new ExcelException("导出Excel失败");
  28. }
  29. }
  30. }
  31. /**
  32. * @MethodName : listToExcel
  33. * @Description : 导出Excel(可以导出到本地文件系统,也可以导出到浏览器,可自定义工作表大小)
  34. * @param list
  35. * 数据源
  36. * @param fieldMap
  37. * 类的英文属性和Excel中的中文列名的对应关系 如果需要的是引用对象的属性,则英文属性使用类似于EL表达式的格式
  38. * 如:list中存放的都是student,student中又有college属性,而我们需要学院名称,则可以这样写
  39. * fieldMap.put("college.collegeName","学院名称")
  40. * @param sheetName
  41. * 工作表的名称
  42. * @param sheetSize
  43. * 每个工作表中记录的最大个数
  44. * @param out
  45. * 导出流
  46. * @throws ExcelException
  47. */
  48. public static <T> void listToExcel(List<T> list, Map<String, String> fieldMap, String sheetName, int sheetSize, OutputStream out) throws ExcelException {
  49. if (list.size() == 0 || list == null) {
  50. throw new ExcelException("数据源中没有任何数据");
  51. }
  52. if (sheetSize > 65535 || sheetSize < 1) {
  53. sheetSize = 65535;
  54. }
  55. // 创建工作簿并发送到OutputStream指定的地方
  56. WritableWorkbook wwb;
  57. try {
  58. wwb = Workbook.createWorkbook(out);
  59. // 因为2003的Excel一个工作表最多可以有65536条记录,除去列头剩下65535条
  60. // 所以如果记录太多,需要放到多个工作表中,其实就是个分页的过程
  61. // 1.计算一共有多少个工作表
  62. double sheetNum = Math.ceil(list.size() / new Integer(sheetSize).doubleValue());
  63. // 2.创建相应的工作表,并向其中填充数据
  64. for (int i = 0; i < sheetNum; i++) {
  65. // 如果只有一个工作表的情况
  66. if (1 == sheetNum) {
  67. WritableSheet sheet = wwb.createSheet(sheetName, i);
  68. fillSheet(sheet, list, fieldMap, 0, list.size() - 1);
  69. // 有多个工作表的情况
  70. } else {
  71. WritableSheet sheet = wwb.createSheet(sheetName + (i + 1), i);
  72. // 获取开始索引和结束索引
  73. int firstIndex = i * sheetSize;
  74. int lastIndex = (i + 1) * sheetSize - 1 > list.size() - 1 ? list.size() - 1 : (i + 1) * sheetSize - 1;
  75. // 填充工作表
  76. fillSheet(sheet, list, fieldMap, firstIndex, lastIndex);
  77. }
  78. }
  79. wwb.write();
  80. wwb.close();
  81. } catch (Exception e) {
  82. e.printStackTrace();
  83. // 如果是ExcelException,则直接抛出
  84. if (e instanceof ExcelException) {
  85. throw (ExcelException) e;
  86. // 否则将其它异常包装成ExcelException再抛出
  87. } else {
  88. throw new ExcelException("导出Excel失败");
  89. }
  90. }
  91. }
  92. /**
  93. * @MethodName : fillSheet
  94. * @Description : 向工作表中填充数据
  95. * @param sheet
  96. * 工作表
  97. * @param list
  98. * 数据源
  99. * @param fieldMap
  100. * 中英文字段对应关系的Map
  101. * @param firstIndex
  102. * 开始索引
  103. * @param lastIndex
  104. * 结束索引
  105. */
  106. private static <T> void fillSheet(WritableSheet sheet, List<T> list, Map<String, String> fieldMap, int firstIndex, int lastIndex) throws Exception {
  107. // 定义存放英文字段名和中文字段名的数组
  108. String[] enFields = new String[fieldMap.size()];
  109. String[] cnFields = new String[fieldMap.size()];
  110. // 填充数组
  111. int count = 0;
  112. for (Entry<String, String> entry : fieldMap.entrySet()) {
  113. enFields[count] = entry.getKey();
  114. cnFields[count] = entry.getValue();
  115. count++;
  116. }
  117. // 填充表头
  118. for (int i = 0; i < cnFields.length; i++) {
  119. Label label = new Label(i, 0, cnFields[i]);
  120. sheet.addCell(label);
  121. }
  122. // 填充内容
  123. int rowNo = 1;
  124. for (int index = firstIndex; index <= lastIndex; index++) {
  125. // 获取单个对象
  126. T item = list.get(index);
  127. for (int i = 0; i < enFields.length; i++) {
  128. Object objValue = getFieldValueByNameSequence(enFields[i], item);
  129. String fieldValue = objValue == null ? "" : objValue.toString();
  130. Label label = new Label(i, rowNo, fieldValue);
  131. sheet.addCell(label);
  132. }
  133. rowNo++;
  134. }
  135. // 设置自动列宽
  136. setColumnAutoSize(sheet, 5);
  137. }
  138. /**
  139. * @MethodName : getFieldValueByNameSequence
  140. * @Description : 根据带路径或不带路径的属性名获取属性值
  141. * 即接受简单属性名,如userName等,又接受带路径的属性名,如student.department.name等
  142. *
  143. * @param fieldNameSequence
  144. * 带路径的属性名或简单属性名
  145. * @param o
  146. * 对象
  147. * @return 属性值
  148. * @throws Exception
  149. */
  150. private static Object getFieldValueByNameSequence(String fieldNameSequence, Object o) throws Exception {
  151. Object value = null;
  152. if (o instanceof Map) {
  153. value = ((Map) o).get(fieldNameSequence);
  154. } else {
  155. // 将fieldNameSequence进行拆分
  156. String[] attributes = fieldNameSequence.split("\\.");
  157. if (attributes.length == 1) {
  158. value = getFieldValueByName(fieldNameSequence, o);
  159. } else {
  160. // 根据属性名获取属性对象
  161. Object fieldObj = getFieldValueByName(attributes[0], o);
  162. //
  163. if (null == fieldObj) {
  164. return null;
  165. }
  166. String subFieldNameSequence = fieldNameSequence.substring(fieldNameSequence.indexOf(".") + 1);
  167. value = getFieldValueByNameSequence(subFieldNameSequence, fieldObj);
  168. }
  169. }
  170. return value;
  171. }
  172. /**
  173. * @MethodName : setColumnAutoSize
  174. * @Description : 设置工作表自动列宽和首行加粗
  175. * @param ws
  176. */
  177. private static void setColumnAutoSize(WritableSheet ws, int extraWith) {
  178. // 获取本列的最宽单元格的宽度
  179. for (int i = 0; i < ws.getColumns(); i++) {
  180. int colWith = 0;
  181. for (int j = 0; j < ws.getRows(); j++) {
  182. String content = ws.getCell(i, j).getContents().toString();
  183. int cellWith = content.length();
  184. if (colWith < cellWith) {
  185. colWith = cellWith;
  186. }
  187. }
  188. // 设置单元格的宽度为最宽宽度+额外宽度
  189. ws.setColumnView(i, colWith + extraWith);
  190. }
  191. }
  192. /**
  193. * @MethodName : getFieldValueByName
  194. * @Description : 根据字段名获取字段值
  195. * @param fieldName
  196. * 字段名
  197. * @param o
  198. * 对象
  199. * @return 字段值
  200. */
  201. private static Object getFieldValueByName(String fieldName, Object o) throws Exception {
  202. Object value = null;
  203. Field field = getFieldByName(fieldName, o.getClass());
  204. if (field != null) {
  205. field.setAccessible(true);
  206. value = field.get(o);
  207. } else {
  208. throw new ExcelException(o.getClass().getSimpleName() + "类不存在字段名 " + fieldName);
  209. }
  210. return value;
  211. }
  212. /**
  213. * @MethodName : getFieldByName
  214. * @Description : 根据字段名获取字段
  215. * @param fieldName
  216. * 字段名
  217. * @param clazz
  218. * 包含该字段的类
  219. * @return 字段
  220. */
  221. private static Field getFieldByName(String fieldName, Class<?> clazz) {
  222. // 拿到本类的所有字段
  223. Field[] selfFields = clazz.getDeclaredFields();
  224. // 如果本类中存在该字段,则返回
  225. for (Field field : selfFields) {
  226. if (field.getName().equals(fieldName)) {
  227. return field;
  228. }
  229. }
  230. // 否则,查看父类中是否存在此字段,如果有则返回
  231. Class<?> superClazz = clazz.getSuperclass();
  232. if (superClazz != null && superClazz != Object.class) {
  233. return getFieldByName(fieldName, superClazz);
  234. }
  235. // 如果本类和父类都没有,则返回空
  236. return null;
  237. }
复制代码


回复

使用道具 举报