ExportExcel.java 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468
  1. package cn.com.lzt.common.util;
  2. import cn.com.lzt.common.excel.ExportExcelBean;
  3. import cn.com.lzt.common.excel.ZipCompressorByAnt;
  4. import org.apache.commons.lang.StringUtils;
  5. import org.apache.log4j.Logger;
  6. import org.apache.poi.hssf.usermodel.*;
  7. import org.apache.poi.ss.usermodel.*;
  8. import org.apache.poi.ss.util.CellRangeAddress;
  9. import javax.servlet.http.HttpServletRequest;
  10. import javax.servlet.http.HttpServletResponse;
  11. import java.io.*;
  12. import java.lang.reflect.Field;
  13. import java.lang.reflect.Method;
  14. import java.net.URLEncoder;
  15. import java.util.ArrayList;
  16. import java.util.List;
  17. import java.util.Map;
  18. /**
  19. * 导出Excel公共方法
  20. *
  21. */
  22. @SuppressWarnings("deprecation")
  23. public class ExportExcel {
  24. private static final Logger log = Logger.getLogger(ExportExcel.class);
  25. // 显示的导出表的标题
  26. private String title;
  27. // 导出表的列名
  28. private Object[] rowName;
  29. // 导出的实体类对应的属性名称
  30. private Object[] attributeName;
  31. // 导出数据
  32. private List<Object> dataList = new ArrayList<Object>();
  33. // 导出excel表明
  34. private String excelName;
  35. // 构造方法,传入要导出的数据
  36. public ExportExcel(String title, Object[] rowName, String excelName,List<Object> dataList,Object[] attributeName) {
  37. this.dataList = dataList;
  38. this.rowName = rowName;
  39. this.excelName = excelName;
  40. this.title = title;
  41. this.attributeName = attributeName;
  42. }
  43. public ExportExcel(){
  44. }
  45. /*
  46. * 导出数据
  47. */
  48. public void export(HttpServletResponse response) throws Exception {
  49. try {
  50. HSSFWorkbook workbook = new HSSFWorkbook(); // 创建工作簿对象
  51. HSSFSheet sheet = workbook.createSheet(title); // 创建工作表
  52. // 产生表格标题行
  53. HSSFRow rowm = sheet.createRow(0);
  54. HSSFCell cellTiltle = rowm.createCell(0);
  55. // sheet样式定义【getColumnTopStyle()/getStyle()均为自定义方法 - 在下面 - 可扩展】
  56. HSSFCellStyle columnTopStyle = this.getColumnTopStyle(workbook);// 获取列头样式对象
  57. HSSFCellStyle style = this.getStyle(workbook); // 单元格样式对象
  58. sheet.addMergedRegion(new CellRangeAddress(0, 1, 0,
  59. (rowName.length - 1)));
  60. cellTiltle.setCellStyle(columnTopStyle);
  61. cellTiltle.setCellValue(title);
  62. // 定义所需列数
  63. int columnNum = rowName.length;
  64. HSSFRow rowRowName = sheet.createRow(2); // 在索引2的位置创建行(最顶端的行开始的第二行)
  65. // 将列头设置到sheet的单元格中
  66. for (int n = 0; n < columnNum; n++) {
  67. HSSFCell cellRowName = rowRowName.createCell(n); // 创建列头对应个数的单元格
  68. cellRowName.setCellType(CellType.STRING); // 设置列头单元格的数据类型
  69. HSSFRichTextString text = new HSSFRichTextString(rowName[n]!=null?rowName[n].toString():"");
  70. cellRowName.setCellValue(text); // 设置列头单元格的值
  71. cellRowName.setCellStyle(columnTopStyle); // 设置列头单元格样式
  72. }
  73. // 将查询出的数据设置到sheet对应的单元格中
  74. if (dataList !=null && dataList.size() > 0){
  75. for (int i = 0; i < dataList.size(); i++) {
  76. Object object = dataList.get(i);// 遍历每个对象
  77. HSSFRow row = sheet.createRow(i + 3);// 创建所需的行数
  78. Class<?> cla = object.getClass();
  79. if (cla.isAssignableFrom(java.util.HashMap.class)){
  80. /*if (rowName !=null && rowName.length > 0) {
  81. for (int n = 0; n < columnNum; n++) {
  82. HSSFCell cellRowName = rowRowName.createCell(n); // 创建列头对应个数的单元格
  83. cellRowName.setCellType(CellType.STRING); // 设置列头单元格的数据类型
  84. HSSFRichTextString text = new HSSFRichTextString(rowName[n]!=null?rowName[n].toString():"");
  85. cellRowName.setCellValue(text); // 设置列头单元格的值
  86. cellRowName.setCellStyle(columnTopStyle); // 设置列头单元格样式
  87. }
  88. }*/
  89. @SuppressWarnings("unchecked")
  90. Map<String,Object> map = (Map<String,Object>)object;
  91. Object[] keys = map.keySet().toArray();
  92. if(attributeName != null){
  93. keys = attributeName;
  94. }
  95. //Object[] keys = attributeName;
  96. //log.info("........"+JSON.toJSON(keys));
  97. for (int j = 0; j < keys.length; j++) {
  98. HSSFCell cell = null; // 设置单元格的数据类型
  99. cell = row.createCell(j, CellType.STRING);
  100. if (map.get(keys[j]) !=null){
  101. cell.setCellValue(map.get(keys[j]).toString()); // 设置单元格的值
  102. }else{
  103. cell.setCellValue("");
  104. }
  105. cell.setCellStyle(style); // 设置单元格样式
  106. }
  107. }else if (cla.isAssignableFrom(java.lang.Object[].class)){
  108. Object[] obj = (Object[])object;
  109. for (int j = 0; j < obj.length; j++) {
  110. HSSFCell cell = null; // 设置单元格的数据类型
  111. cell = row.createCell(j, CellType.STRING);
  112. if (obj[j] != null) {
  113. cell.setCellValue(obj[j].toString()); // 设置单元格的值
  114. }else{
  115. cell.setCellValue("");
  116. }
  117. cell.setCellStyle(style); // 设置单元格样式
  118. }
  119. }else{
  120. if (attributeName !=null && attributeName.length > 0){
  121. for (int j = 0; j < attributeName.length; j++) {
  122. String fdname = attributeName[j].toString();
  123. StringBuffer sb = new StringBuffer(fdname);
  124. if (!Character.isUpperCase(sb.charAt(1)))
  125. sb.setCharAt(0, Character.toUpperCase(sb.charAt(0)));
  126. Method metd = cla.getMethod("get"+sb.toString(), null);
  127. Object value = metd.invoke(object, null);
  128. HSSFCell cell = null; // 设置单元格的数据类型
  129. cell = row.createCell(j, CellType.STRING);
  130. if (value !=null) {
  131. cell.setCellValue(value.toString()); // 设置单元格的值
  132. }else{
  133. cell.setCellValue("");
  134. }
  135. cell.setCellStyle(style); // 设置单元格样式
  136. }
  137. }else{
  138. Field[] fds = cla.getDeclaredFields();
  139. for (int j = 0; j < fds.length; j++) {
  140. Field field = fds[j];
  141. String fdname = field.getName();
  142. StringBuffer sb = new StringBuffer(fdname);
  143. if (!Character.isUpperCase(sb.charAt(1)))
  144. sb.setCharAt(0, Character.toUpperCase(sb.charAt(0)));
  145. Method metd = cla.getMethod("get"+sb.toString(), null);
  146. Object value = metd.invoke(object, null);
  147. HSSFCell cell = null; // 设置单元格的数据类型
  148. cell = row.createCell(j, CellType.STRING);
  149. if (value !=null) {
  150. cell.setCellValue(value.toString()); // 设置单元格的值
  151. }else{
  152. cell.setCellValue("");
  153. }
  154. cell.setCellStyle(style); // 设置单元格样式
  155. }
  156. }
  157. }
  158. }
  159. }
  160. // 让列宽随着导出的列长自动适应
  161. for (int colNum = 0; colNum < columnNum; colNum++) {
  162. int columnWidth = sheet.getColumnWidth(colNum) / 256;
  163. for (int rowNum = 0; rowNum < sheet.getLastRowNum(); rowNum++) {
  164. HSSFRow currentRow;
  165. // 当前行未被使用过
  166. if (sheet.getRow(rowNum) == null) {
  167. currentRow = sheet.createRow(rowNum);
  168. } else {
  169. currentRow = sheet.getRow(rowNum);
  170. }
  171. if (currentRow.getCell(colNum) != null) {
  172. try {
  173. HSSFCell currentCell = currentRow.getCell(colNum);
  174. if (currentCell.getCellType() == CellType.STRING) {
  175. int length = 0;
  176. if (StringUtils.isNotEmpty(currentCell.getStringCellValue())){
  177. length = currentCell.getStringCellValue().getBytes().length;
  178. }
  179. if (columnWidth < length) {
  180. columnWidth = length;
  181. }
  182. }
  183. } catch (Exception e) {
  184. //undo
  185. }
  186. }
  187. }
  188. if (colNum == 0) {
  189. sheet.setColumnWidth(colNum, (columnWidth - 2) * 256);
  190. } else {
  191. sheet.setColumnWidth(colNum, (columnWidth + 4) * 256);
  192. }
  193. }
  194. if (workbook != null) {
  195. OutputStream out = response.getOutputStream();
  196. try {
  197. // String fileName = "Excel-"
  198. // + String.valueOf(System.currentTimeMillis())
  199. // .substring(4, 13) + ".xls";
  200. String fileName = URLEncoder.encode(excelName + ".xls","utf-8");
  201. String headStr = "attachment; filename=\"" + fileName
  202. + "\"";
  203. response.setContentType("application/vnd.ms-excel");
  204. response.setHeader("Content-Disposition", headStr);
  205. workbook.write(out);
  206. } catch (IOException e) {
  207. e.printStackTrace();
  208. }finally{
  209. if (out !=null){
  210. out.close();
  211. response.flushBuffer();
  212. }
  213. }
  214. }
  215. } catch (Exception e) {
  216. e.printStackTrace();
  217. }
  218. }
  219. public void toExcel(List<ExportExcelBean> eList,HttpServletRequest request,OutputStream out) throws IOException{
  220. // List<String> fileNames = new ArrayList<String>();// 用于存放生成的文件名称s
  221. // File zip = new File(request.getRealPath("/files") + "/" + "fff" + ".zip");// 压缩文件
  222. String dir = "excels";
  223. String basePath = request.getSession().getServletContext().getRealPath("");
  224. String excelsPath = basePath.substring(0,basePath.lastIndexOf(File.separator))+File.separator+dir;
  225. //log.info("获取的路径>>>>>"+excelsPath);
  226. File rDir = new File(excelsPath);
  227. if (!rDir.exists()){
  228. rDir.mkdirs();
  229. }
  230. for (int i = 0; i < eList.size(); i++) {
  231. HSSFWorkbook workbook = new HSSFWorkbook(); // 创建工作簿对象
  232. String title2 = eList.get(i).getTableName()+"查询";
  233. HSSFSheet sheet = workbook.createSheet(title2); // 创建工作表
  234. String file = excelsPath+ "/"
  235. +eList.get(i).getCombName()+"-"
  236. +eList.get(i).getTableName()+"-"
  237. +eList.get(i).getExportTime()
  238. + ".xls";
  239. // fileNames.add(file);
  240. FileOutputStream o = new FileOutputStream(file);
  241. // 产生表格标题行
  242. HSSFRow rowm = sheet.createRow(0);
  243. HSSFCell cellTiltle = rowm.createCell(0);
  244. // sheet样式定义【getColumnTopStyle()/getStyle()均为自定义方法 - 在下面 - 可扩展】
  245. HSSFCellStyle columnTopStyle = this.getColumnTopStyle(workbook);// 获取列头样式对象
  246. HSSFCellStyle style = this.getStyle(workbook); // 单元格样式对象
  247. int rowLeng = eList.get(i).getRows().length;
  248. sheet.addMergedRegion(new CellRangeAddress(0, 1, 0,(rowLeng - 1)));
  249. cellTiltle.setCellStyle(columnTopStyle);
  250. cellTiltle.setCellValue(title2);
  251. // 定义所需列数
  252. int columnNum = rowLeng;
  253. // int columnNum = rowName.length;
  254. HSSFRow rowRowName = sheet.createRow(2); // 在索引2的位置创建行(最顶端的行开始的第二行)
  255. // 将列头设置到sheet的单元格中
  256. for (int n = 0; n < columnNum; n++) {
  257. HSSFCell cellRowName = rowRowName.createCell(n); // 创建列头对应个数的单元格
  258. cellRowName.setCellType(CellType.STRING); // 设置列头单元格的数据类型
  259. HSSFRichTextString text = new HSSFRichTextString(eList.get(i).getRows()[n]!=null?eList.get(i).getRows()[n].toString():"");
  260. cellRowName.setCellValue(text); // 设置列头单元格的值
  261. cellRowName.setCellStyle(columnTopStyle); // 设置列头单元格样式
  262. }
  263. List<Object> dataList2 = eList.get(i).getObjList();
  264. if (dataList2!=null&&dataList2.size()>0) {
  265. for (int j = 0; j < dataList2.size(); j++) {
  266. Object object = dataList2.get(j);// 遍历每个对象
  267. HSSFRow row = sheet.createRow(j + 3);// 创建所需的行数
  268. Class<?> cla = object.getClass();
  269. if (cla.isAssignableFrom(java.util.HashMap.class)){
  270. @SuppressWarnings("unchecked")
  271. Map<String,Object> map = (Map<String,Object>)object;
  272. Object[] keys = eList.get(i).getAttrs();
  273. for (int k = 0; k < keys.length; k++) {
  274. HSSFCell cell = null; // 设置单元格的数据类型
  275. cell = row.createCell(k, CellType.STRING);
  276. if (map.get(keys[k]) !=null){
  277. cell.setCellValue(map.get(keys[k]).toString()); // 设置单元格的值
  278. }else{
  279. cell.setCellValue("");
  280. }
  281. cell.setCellStyle(style); // 设置单元格样式
  282. }
  283. }
  284. }
  285. }
  286. // 让列宽随着导出的列长自动适应
  287. for (int colNum = 0; colNum < columnNum; colNum++) {
  288. int columnWidth = sheet.getColumnWidth(colNum) / 128;
  289. for (int rowNum = 0; rowNum < sheet.getLastRowNum(); rowNum++) {
  290. HSSFRow currentRow;
  291. // 当前行未被使用过
  292. if (sheet.getRow(rowNum) == null) {
  293. currentRow = sheet.createRow(rowNum);
  294. } else {
  295. currentRow = sheet.getRow(rowNum);
  296. }
  297. if (currentRow.getCell(colNum) != null) {
  298. try {
  299. HSSFCell currentCell = currentRow.getCell(colNum);
  300. if (currentCell.getCellType() == CellType.STRING) {
  301. int length = 0;
  302. if (StringUtils.isNotEmpty(currentCell.getStringCellValue())){
  303. length = currentCell.getStringCellValue().getBytes().length;
  304. }
  305. if (columnWidth < length) {
  306. columnWidth = length;
  307. }
  308. }
  309. } catch (Exception e) {
  310. //undo
  311. }
  312. }
  313. }
  314. if (colNum == 0) {
  315. sheet.setColumnWidth(colNum, (columnWidth - 2) * 256);
  316. } else {
  317. sheet.setColumnWidth(colNum, (columnWidth + 4) * 256);
  318. }
  319. }
  320. if (workbook!=null) {
  321. workbook.write(o);
  322. o.close();
  323. }
  324. }
  325. ZipCompressorByAnt zca = new ZipCompressorByAnt(rDir.getAbsolutePath()+".zip");
  326. int isZip = zca.compress(rDir.getAbsolutePath());
  327. if (isZip==0) {
  328. File file = new File(rDir.getAbsolutePath()+".zip");
  329. FileInputStream inStream = new FileInputStream(file);
  330. byte[] buf = new byte[4096];
  331. int readLength;
  332. while (((readLength = inStream.read(buf)) != -1)) {
  333. out.write(buf, 0, readLength);
  334. }
  335. inStream.close();
  336. out.close();
  337. }
  338. deleteDir(rDir);
  339. File file = new File(rDir.getAbsolutePath()+".zip");
  340. file.delete();
  341. }
  342. private static boolean deleteDir(File dir) {
  343. if (dir.isDirectory()) {
  344. String[] children = dir.list();
  345. //递归删除目录中的子目录下
  346. for (int i=0; i<children.length; i++) {
  347. boolean success = deleteDir(new File(dir, children[i]));
  348. if (!success) {
  349. return false;
  350. }
  351. }
  352. }
  353. // 目录此时为空,可以删除
  354. return dir.delete();
  355. }
  356. /*
  357. * 列头单元格样式
  358. */
  359. public HSSFCellStyle getColumnTopStyle(HSSFWorkbook workbook) {
  360. // 设置字体
  361. HSSFFont font = workbook.createFont();
  362. // 设置字体大小
  363. font.setFontHeightInPoints((short) 11);
  364. // 字体加粗
  365. font.setBold(true);
  366. // 设置字体名字
  367. font.setFontName("Courier New");
  368. // 设置样式;
  369. HSSFCellStyle style = workbook.createCellStyle();
  370. // 设置底边框;
  371. style.setBorderBottom(BorderStyle.THIN);
  372. // 设置底边框颜色;
  373. style.setBottomBorderColor(IndexedColors.BLACK.index);
  374. // 设置左边框;
  375. style.setBorderLeft(BorderStyle.THIN);
  376. // 设置左边框颜色;
  377. style.setLeftBorderColor(IndexedColors.BLACK.index);
  378. // 设置右边框;
  379. style.setBorderRight(BorderStyle.THIN);
  380. // 设置右边框颜色;
  381. style.setRightBorderColor(IndexedColors.BLACK.index);
  382. // 设置顶边框;
  383. style.setBorderTop(BorderStyle.THIN);
  384. // 设置顶边框颜色;
  385. style.setTopBorderColor(IndexedColors.BLACK.index);
  386. // 在样式用应用设置的字体;
  387. style.setFont(font);
  388. // 设置自动换行;
  389. style.setWrapText(false);
  390. // 设置水平对齐的样式为居中对齐;
  391. // style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
  392. style.setAlignment(HorizontalAlignment.CENTER);
  393. // 设置垂直对齐的样式为居中对齐;
  394. style.setVerticalAlignment(VerticalAlignment.CENTER);
  395. return style;
  396. }
  397. /*
  398. * 列数据信息单元格样式
  399. */
  400. public HSSFCellStyle getStyle(HSSFWorkbook workbook) {
  401. // 设置字体
  402. HSSFFont font = workbook.createFont();
  403. // 设置字体大小
  404. // font.setFontHeightInPoints((short)10);
  405. // 字体加粗
  406. // font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
  407. // 设置字体名字
  408. font.setFontName("Courier New");
  409. // 设置样式;
  410. HSSFCellStyle style = workbook.createCellStyle();
  411. // 设置底边框;
  412. style.setBorderBottom(BorderStyle.THIN);
  413. // 设置底边框颜色;
  414. style.setBottomBorderColor(IndexedColors.BLACK.index);
  415. // 设置左边框;
  416. style.setBorderLeft(BorderStyle.THIN);
  417. // 设置左边框颜色;
  418. style.setLeftBorderColor(IndexedColors.BLACK.index);
  419. // 设置右边框;
  420. style.setBorderRight(BorderStyle.THIN);
  421. // 设置右边框颜色;
  422. style.setRightBorderColor(IndexedColors.BLACK.index);
  423. // 设置顶边框;
  424. style.setBorderTop(BorderStyle.THIN);
  425. // 设置顶边框颜色;
  426. style.setTopBorderColor(IndexedColors.BLACK.index);
  427. // 在样式用应用设置的字体;
  428. style.setFont(font);
  429. // 设置自动换行;
  430. style.setWrapText(false);
  431. // 设置水平对齐的样式为居中对齐;
  432. style.setAlignment(HorizontalAlignment.CENTER);
  433. // 设置垂直对齐的样式为居中对齐;
  434. style.setVerticalAlignment(VerticalAlignment.CENTER);
  435. return style;
  436. }
  437. }