PageRenderTime 89ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/src/main/java/com/dylan/lang/ExcelUtil.java

https://github.com/dylanvivi/util
Java | 418 lines | 319 code | 28 blank | 71 comment | 50 complexity | a75d39e57f9db6720178088f2a109b58 MD5 | raw file
  1. package com.dylan.lang;
  2. import java.io.FileNotFoundException;
  3. import java.io.FileOutputStream;
  4. import java.io.IOException;
  5. import java.io.OutputStream;
  6. import java.lang.reflect.Field;
  7. import java.lang.reflect.InvocationTargetException;
  8. import java.lang.reflect.Method;
  9. import java.text.SimpleDateFormat;
  10. import java.util.Collection;
  11. import java.util.Date;
  12. import java.util.Iterator;
  13. import java.util.Map;
  14. import java.util.regex.Matcher;
  15. import java.util.regex.Pattern;
  16. import org.apache.poi.hssf.usermodel.HSSFCell;
  17. import org.apache.poi.hssf.usermodel.HSSFCellStyle;
  18. import org.apache.poi.hssf.usermodel.HSSFClientAnchor;
  19. import org.apache.poi.hssf.usermodel.HSSFComment;
  20. import org.apache.poi.hssf.usermodel.HSSFDataFormat;
  21. import org.apache.poi.hssf.usermodel.HSSFFont;
  22. import org.apache.poi.hssf.usermodel.HSSFPatriarch;
  23. import org.apache.poi.hssf.usermodel.HSSFRichTextString;
  24. import org.apache.poi.hssf.usermodel.HSSFRow;
  25. import org.apache.poi.hssf.usermodel.HSSFSheet;
  26. import org.apache.poi.hssf.usermodel.HSSFWorkbook;
  27. import org.apache.poi.hssf.util.HSSFColor;
  28. import org.slf4j.Logger;
  29. import org.slf4j.LoggerFactory;
  30. /**
  31. * @author lucas ^_^
  32. * @date 2012-12-11
  33. * @Description
  34. */
  35. public class ExcelUtil {
  36. private static Logger log = LoggerFactory.getLogger(ExcelUtil.class);
  37. /**
  38. * 功能:生成Excel文件
  39. * @param wb HSSFWorkbook
  40. * @param fileName 写入文件的相对路径 (包含文件名)
  41. */
  42. public static void writeWorkbook(HSSFWorkbook wb, String fileName) {
  43. FileOutputStream fos = null;
  44. try {
  45. fos = new FileOutputStream(fileName);
  46. wb.write(fos);
  47. } catch (FileNotFoundException e) {
  48. log.error(e.getMessage());
  49. } catch (IOException e) {
  50. log.error(e.getMessage());
  51. } finally {
  52. try {
  53. if (fos != null) {
  54. fos.close();
  55. }
  56. } catch (IOException e) {
  57. log.error(e.getMessage());
  58. }
  59. }
  60. }
  61. public static <T> void exportExcel(String title, String[] headers, String[] cols, Collection<T> dataset,
  62. OutputStream out, String pattern, String[] sumcols) {
  63. // 声明一个工作薄
  64. HSSFWorkbook workbook = new HSSFWorkbook();
  65. // 生成一个表格
  66. HSSFSheet sheet = workbook.createSheet(title);
  67. // 设置表格默认列宽度为15个字节
  68. sheet.setDefaultColumnWidth(15);
  69. // 生成一个样式
  70. HSSFCellStyle style = createStyle(workbook, HSSFColor.LIME.index, HSSFCellStyle.SOLID_FOREGROUND,
  71. HSSFCellStyle.BORDER_THIN, HSSFCellStyle.BORDER_THIN, HSSFCellStyle.BORDER_THIN,
  72. HSSFCellStyle.BORDER_THIN, HSSFCellStyle.ALIGN_CENTER);
  73. //生成一个字体
  74. HSSFFont font = createFont(workbook, HSSFColor.BLACK.index, HSSFFont.BOLDWEIGHT_BOLD);
  75. font.setFontHeightInPoints((short) 12);
  76. font.setFontName("微软雅黑");
  77. //字体设置给样式
  78. style.setFont(font);
  79. // 生成并设置另一个样式
  80. HSSFCellStyle style2 = createStyle(workbook, HSSFColor.WHITE.index, HSSFCellStyle.SOLID_FOREGROUND,
  81. HSSFCellStyle.BORDER_THIN, HSSFCellStyle.BORDER_THIN, HSSFCellStyle.BORDER_THIN,
  82. HSSFCellStyle.BORDER_THIN, HSSFCellStyle.ALIGN_CENTER);
  83. style2.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
  84. // 生成另一个字体
  85. HSSFFont font2 = workbook.createFont();
  86. font2.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL);
  87. // 把字体应用到当前的样式
  88. style2.setFont(font2);
  89. //生成数字类型样式(三位小数)
  90. HSSFCellStyle style3 = createStyle(workbook, HSSFColor.WHITE.index, HSSFCellStyle.SOLID_FOREGROUND,
  91. HSSFCellStyle.BORDER_THIN, HSSFCellStyle.BORDER_THIN, HSSFCellStyle.BORDER_THIN,
  92. HSSFCellStyle.BORDER_THIN, HSSFCellStyle.ALIGN_CENTER);
  93. style3.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
  94. HSSFDataFormat format = workbook.createDataFormat();
  95. style3.setDataFormat(format.getFormat("0.000"));
  96. //生成数字类型样式(整数)
  97. HSSFCellStyle style4 = createStyle(workbook, HSSFColor.WHITE.index, HSSFCellStyle.SOLID_FOREGROUND,
  98. HSSFCellStyle.BORDER_THIN, HSSFCellStyle.BORDER_THIN, HSSFCellStyle.BORDER_THIN,
  99. HSSFCellStyle.BORDER_THIN, HSSFCellStyle.ALIGN_CENTER);
  100. style4.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
  101. style4.setDataFormat(HSSFDataFormat.getBuiltinFormat("0"));
  102. // 声明一个画图的顶级管理器
  103. HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
  104. // 定义注释的大小和位置,详见文档
  105. HSSFComment comment = patriarch.createComment(new HSSFClientAnchor(0, 0, 0, 0, (short) 4, 2, (short) 6, 5));
  106. // 设置注释内容
  107. comment.setString(new HSSFRichTextString("happy life"));
  108. // 设置注释作者,当鼠标移动到单元格上是可以在状态栏中看到该内容.
  109. comment.setAuthor("dylan");
  110. // 产生表格标题行
  111. int index = 0;
  112. HSSFRow row = sheet.createRow(0);
  113. for (int i = 0; i < headers.length; i++) {
  114. HSSFCell cell = row.createCell(i);
  115. cell.setCellStyle(style);
  116. HSSFRichTextString text = new HSSFRichTextString(headers[i]);
  117. cell.setCellValue(text);
  118. }
  119. index++;
  120. // 遍历集合数据,产生数据行
  121. Iterator<T> it = dataset.iterator();
  122. while (it.hasNext()) {
  123. row = sheet.createRow(index);
  124. index++;
  125. T t = (T) it.next();
  126. // 利用反射,根据javabean属性的先后顺序,动态调用getXxx()方法得到属性值
  127. Field[] fields = t.getClass().getDeclaredFields();
  128. for (int i = 0; i < fields.length; i++) {
  129. Field field = fields[i];
  130. String fieldName = field.getName();
  131. for (int j = 0; j < cols.length; j++) {
  132. boolean hasField = false;
  133. if (cols[j].equalsIgnoreCase(fieldName)) {
  134. hasField = true;
  135. }
  136. if (!hasField) {
  137. continue;
  138. }
  139. HSSFCell cell = row.createCell(j);
  140. cell.setCellStyle(style2);
  141. String getMethodName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
  142. try {
  143. Class tCls = t.getClass();
  144. Method getMethod = tCls.getMethod(getMethodName, new Class[] {});
  145. Object value = getMethod.invoke(t, new Object[] {});
  146. // 判断值的类型后进行强制类型转换
  147. String textValue = null;
  148. if (value instanceof Double || value instanceof Float) {
  149. textValue = value.toString();
  150. } else if (value instanceof Date) {
  151. Date date = (Date) value;
  152. SimpleDateFormat sdf = new SimpleDateFormat(pattern);
  153. textValue = sdf.format(date);
  154. } else {
  155. // 其它数据类型都当作字符串简单处理
  156. if (value == null) {
  157. textValue = null;
  158. } else {
  159. textValue = value.toString();
  160. }
  161. }
  162. // 如果不是图片数据,就利用正则表达式判断textValue是否全部由数字组成
  163. if (textValue != null) {
  164. Pattern p = Pattern.compile("^//d+(//.//d+)?$");
  165. Matcher matcher = p.matcher(textValue);
  166. if (matcher.matches()) {
  167. // 是数字当作double处理
  168. cell.setCellValue(Double.parseDouble(textValue));
  169. } else {
  170. cell.setCellValue(textValue);
  171. }
  172. }
  173. } catch (SecurityException e) {
  174. e.printStackTrace();
  175. } catch (NoSuchMethodException e) {
  176. e.printStackTrace();
  177. } catch (IllegalArgumentException e) {
  178. e.printStackTrace();
  179. } catch (IllegalAccessException e) {
  180. e.printStackTrace();
  181. } catch (InvocationTargetException e) {
  182. e.printStackTrace();
  183. } finally {
  184. // 清理资源
  185. }
  186. }
  187. }
  188. }
  189. try {
  190. workbook.write(out);
  191. } catch (IOException e) {
  192. e.printStackTrace();
  193. }
  194. }
  195. /**
  196. * 根据map输出excel结果集
  197. * @param title - sheet的名称
  198. * @param headers - 列名
  199. * @param cols - 要输出的列名(无视大小写)
  200. * @param dataset - 输出对象Map
  201. * @param out - 输出流
  202. * @param pattern - 日期格式
  203. * @param sumcols - 合计行, 没有则传null
  204. */
  205. public static void export(String title, String[] headers, String[] cols, Collection<Map<String, Object>> dataset,
  206. OutputStream out, String pattern, String[] sumcols) {
  207. // 声明一个工作薄
  208. HSSFWorkbook workbook = new HSSFWorkbook();
  209. // 生成一个表格
  210. HSSFSheet sheet = workbook.createSheet(title);
  211. // 设置表格默认列宽度为15个字节
  212. sheet.setDefaultColumnWidth(15);
  213. // 生成一个样式
  214. HSSFCellStyle style = createStyle(workbook, HSSFColor.LIME.index, HSSFCellStyle.SOLID_FOREGROUND,
  215. HSSFCellStyle.BORDER_THIN, HSSFCellStyle.BORDER_THIN, HSSFCellStyle.BORDER_THIN,
  216. HSSFCellStyle.BORDER_THIN, HSSFCellStyle.ALIGN_CENTER);
  217. //生成一个字体
  218. HSSFFont font = createFont(workbook, HSSFColor.BLACK.index, HSSFFont.BOLDWEIGHT_BOLD);
  219. font.setFontHeightInPoints((short) 12);
  220. font.setFontName("微软雅黑");
  221. //字体设置给样式
  222. style.setFont(font);
  223. // 生成并设置另一个样式
  224. HSSFCellStyle style2 = createStyle(workbook, HSSFColor.WHITE.index, HSSFCellStyle.SOLID_FOREGROUND,
  225. HSSFCellStyle.BORDER_THIN, HSSFCellStyle.BORDER_THIN, HSSFCellStyle.BORDER_THIN,
  226. HSSFCellStyle.BORDER_THIN, HSSFCellStyle.ALIGN_CENTER);
  227. style2.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
  228. // 生成另一个字体
  229. HSSFFont font2 = workbook.createFont();
  230. font2.setBoldweight(HSSFFont.BOLDWEIGHT_NORMAL);
  231. // 把字体应用到当前的样式
  232. style2.setFont(font2);
  233. //生成数字类型样式(三位小数)
  234. HSSFCellStyle style3 = createStyle(workbook, HSSFColor.WHITE.index, HSSFCellStyle.SOLID_FOREGROUND,
  235. HSSFCellStyle.BORDER_THIN, HSSFCellStyle.BORDER_THIN, HSSFCellStyle.BORDER_THIN,
  236. HSSFCellStyle.BORDER_THIN, HSSFCellStyle.ALIGN_CENTER);
  237. style3.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
  238. HSSFDataFormat format = workbook.createDataFormat();
  239. style3.setDataFormat(format.getFormat("0.000"));
  240. //生成数字类型样式(整数)
  241. HSSFCellStyle style4 = createStyle(workbook, HSSFColor.WHITE.index, HSSFCellStyle.SOLID_FOREGROUND,
  242. HSSFCellStyle.BORDER_THIN, HSSFCellStyle.BORDER_THIN, HSSFCellStyle.BORDER_THIN,
  243. HSSFCellStyle.BORDER_THIN, HSSFCellStyle.ALIGN_CENTER);
  244. style4.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
  245. style4.setDataFormat(HSSFDataFormat.getBuiltinFormat("0"));
  246. // 声明一个画图的顶级管理器
  247. HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
  248. // 定义注释的大小和位置,详见文档
  249. HSSFComment comment = patriarch.createComment(new HSSFClientAnchor(0, 0, 0, 0, (short) 4, 2, (short) 6, 5));
  250. // 设置注释内容
  251. comment.setString(new HSSFRichTextString("happy life"));
  252. // 设置注释作者,当鼠标移动到单元格上是可以在状态栏中看到该内容.
  253. comment.setAuthor("dylan");
  254. // 产生表格标题行
  255. HSSFRow row = sheet.createRow(0);
  256. for (int i = 0; i < headers.length; i++) {
  257. HSSFCell cell = row.createCell(i);
  258. cell.setCellStyle(style);
  259. HSSFRichTextString text = new HSSFRichTextString(headers[i]);
  260. cell.setCellValue(text);
  261. }
  262. // 遍历集合数据,产生数据行
  263. Iterator<Map<String, Object>> it = dataset.iterator();
  264. int index = 0;
  265. while (it.hasNext()) {
  266. index++;
  267. row = sheet.createRow(index);
  268. Map<String, Object> t = (Map<String, Object>) it.next();
  269. Object[] keys = t.keySet().toArray();
  270. for (int i = 0; i < cols.length; i++) {
  271. String fieldName = "";
  272. String col = cols[i];
  273. boolean hasCol = false;
  274. for (Object fieldNameStr : keys) {
  275. if (col.equalsIgnoreCase(fieldNameStr.toString())) {
  276. hasCol = true;
  277. fieldName = fieldNameStr.toString();
  278. break;
  279. }
  280. }
  281. if (!hasCol) {
  282. continue;
  283. }
  284. HSSFCell cell = row.createCell(i);
  285. cell.setCellStyle(style2);
  286. try {
  287. Object value = t.get(fieldName);
  288. // 判断值的类型后进行强制类型转换
  289. String textValue = null;
  290. if (value instanceof Double || value instanceof Float) {
  291. String fvalue = value.toString();
  292. textValue = StringUtils.trimFloat(fvalue, 2);
  293. } else if (value instanceof Date) {
  294. Date date = (Date) value;
  295. SimpleDateFormat sdf = new SimpleDateFormat(pattern);
  296. textValue = sdf.format(date);
  297. } else if (value instanceof byte[]) {
  298. // 有图片时,设置行高为60px;
  299. row.setHeightInPoints(60);
  300. // 设置图片所在列宽度为80px,注意这里单位的一个换算
  301. sheet.setColumnWidth(i, (short) (35.7 * 80));
  302. // sheet.autoSizeColumn(i);
  303. byte[] bsValue = (byte[]) value;
  304. HSSFClientAnchor anchor = new HSSFClientAnchor(0, 0, 1023, 255, (short) 6, index, (short) 6,
  305. index);
  306. anchor.setAnchorType(2);
  307. patriarch.createPicture(anchor, workbook.addPicture(bsValue, HSSFWorkbook.PICTURE_TYPE_JPEG));
  308. } else {
  309. // 其它数据类型都当作字符串简单处理
  310. if (value == null) {
  311. textValue = null;
  312. } else {
  313. textValue = value.toString();
  314. }
  315. }
  316. // 如果不是图片数据,就利用正则表达式判断textValue是否全部由数字组成
  317. if (textValue != null) {
  318. Pattern p = Pattern.compile("^\\d+\\.\\d+?$");
  319. Matcher matcher = p.matcher(textValue);
  320. Pattern pn = Pattern.compile("^\\d+$");
  321. Matcher matcherPN = pn.matcher(textValue);
  322. if (matcher.matches()) {
  323. // 是数字当作double处理
  324. cell.setCellStyle(style3);
  325. cell.setCellValue(Double.parseDouble(textValue));
  326. } else if (matcherPN.matches()) {
  327. cell.setCellStyle(style4);
  328. cell.setCellValue(Double.parseDouble(textValue));
  329. } else {
  330. cell.setCellValue(textValue);
  331. }
  332. }
  333. } catch (Exception e) {
  334. e.printStackTrace();
  335. } finally {
  336. // 清理资源
  337. }
  338. }
  339. }
  340. //增加合计行
  341. if (sumcols != null) {
  342. row = sheet.createRow(index + 1);
  343. for (int i = 0; i < sumcols.length; i++) {
  344. HSSFCell cell = row.createCell(i);
  345. cell.setCellStyle(style2);
  346. HSSFFont font4 = workbook.createFont();
  347. font4.setColor(HSSFColor.BLACK.index);
  348. font4.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
  349. style2.setFont(font4);
  350. String formula = null;
  351. if (i == 0) {
  352. HSSFRichTextString richString = new HSSFRichTextString("合计");
  353. richString.applyFont(font4);
  354. cell.setCellValue(richString);
  355. } else if ("0".equals(sumcols[i])) { //不计算
  356. cell.setCellValue(new HSSFRichTextString(""));
  357. } else {
  358. formula = "SUM(" + sumcols[i] + "2:" + sumcols[i] + (index + 1) + ")";
  359. cell.setCellFormula(formula);
  360. }
  361. }
  362. }
  363. try {
  364. workbook.write(out);
  365. } catch (IOException e) {
  366. e.printStackTrace();
  367. }
  368. }
  369. private static HSSFCellStyle createStyle(HSSFWorkbook workbook, short fillForegroundColor, short fillPattern,
  370. short borderBottom, short borderleft, short borderright, short bordertop, short alignment) {
  371. HSSFCellStyle style = workbook.createCellStyle();
  372. // 设置这些样式
  373. style.setFillForegroundColor(fillForegroundColor);
  374. style.setFillPattern(fillPattern);
  375. style.setBorderBottom(borderBottom);
  376. style.setBorderLeft(borderleft);
  377. style.setBorderRight(borderright);
  378. style.setBorderTop(bordertop);
  379. style.setAlignment(alignment);
  380. return style;
  381. }
  382. private static HSSFFont createFont(HSSFWorkbook workbook, short color, short bold) {
  383. // 生成一个字体
  384. HSSFFont font = workbook.createFont();
  385. font.setColor(color);
  386. font.setFontHeightInPoints((short) 12);
  387. font.setBoldweight(bold);
  388. return font;
  389. }
  390. }