struts + poi
一、poi知识讲解
可以下载 孔浩老师 的poi视频,其中封装的四个工具类,很好用,能方便应用到项目中。
二、poi实例
1.引入jar包
2. 引入四个工具类
1 package com.pl.util; 2 3 import java.lang.annotation.Retention; 4 import java.lang.annotation.RetentionPolicy; 5 6 @Retention(RetentionPolicy.RUNTIME) 7 public @interface ExcelResources { 8 9 String title(); 10 11 int order() default 9999; 12 } 13 14 /------------------------*******----------------------/ 15 package com.pl.util; 16 17 /** 18 * 用来存储Excel标题的对象,通过该对象可以获取标题和方法的对应关系 19 * @author Administrator 20 * 21 */ 22 public class ExcelHeader implements Comparable<ExcelHeader>{ 23 /** 24 * excel的标题名称 25 */ 26 private String title; 27 /** 28 * 每一个标题的顺序 29 */ 30 private int order; 31 /** 32 * 说对应方法名称 33 */ 34 private String methodName; 35 36 37 public String getTitle() { 38 return title; 39 } 40 public void setTitle(String title) { 41 this.title = title; 42 } 43 public int getOrder() { 44 return order; 45 } 46 public void setOrder(int order) { 47 this.order = order; 48 } 49 public String getMethodName() { 50 return methodName; 51 } 52 public void setMethodName(String methodName) { 53 this.methodName = methodName; 54 } 55 56 public int compareTo(ExcelHeader o) { 57 return order>o.order?1:(order<o.order?-1:0); 58 } 59 public ExcelHeader(String title, int order, String methodName) { 60 super(); 61 this.title = title; 62 this.order = order; 63 this.methodName = methodName; 64 } 65 @Override 66 public String toString() { 67 return "ExcelHeader [title=" + title + ", order=" + order 68 + ", methodName=" + methodName + "]"; 69 } 70 71 72 } 73 74 /--------------------*************-----------------/ 75 package com.pl.util; 76 77 import java.io.File; 78 import java.io.FileNotFoundException; 79 import java.io.FileOutputStream; 80 import java.io.IOException; 81 import java.io.OutputStream; 82 import java.lang.reflect.InvocationTargetException; 83 import java.lang.reflect.Method; 84 import java.util.ArrayList; 85 import java.util.Collections; 86 import java.util.HashMap; 87 import java.util.List; 88 import java.util.Map; 89 import java.util.Properties; 90 91 import org.apache.commons.beanutils.BeanUtils; 92 import org.apache.poi.hssf.usermodel.HSSFWorkbook; 93 import org.apache.poi.openxml4j.exceptions.InvalidFormatException; 94 import org.apache.poi.ss.usermodel.Cell; 95 import org.apache.poi.ss.usermodel.Row; 96 import org.apache.poi.ss.usermodel.Sheet; 97 import org.apache.poi.ss.usermodel.Workbook; 98 import org.apache.poi.ss.usermodel.WorkbookFactory; 99 import org.apache.poi.xssf.usermodel.XSSFWorkbook; 100 101 /** 102 * 该类实现了将一组对象转换为Excel表格,并且可以从Excel表格中读取到一组List对象中 103 * 该类利用了BeanUtils框架中的反射完成 104 * 使用该类的前提,在相应的实体对象上通过ExcelReources来完成相应的注解 105 * @author Administrator 106 * 107 */ 108 @SuppressWarnings({"rawtypes"}) 109 public class ExcelUtil { 110 private static ExcelUtil eu = new ExcelUtil(); 111 private ExcelUtil(){} 112 113 public static ExcelUtil getInstance() { 114 return eu; 115 } 116 /** 117 * 处理对象转换为Excel 118 * @param datas 119 * @param template 120 * @param objs 121 * @param clz 122 * @param isClasspath 123 * @return 124 */ 125 public ExcelTemplate handlerObj2Excel (String template,List objs,Class clz,boolean isClasspath) { 126 ExcelTemplate et = ExcelTemplate.getInstance(); 127 try { 128 if(isClasspath) { 129 et.readTemplateByClasspath(template); 130 } else { 131 et.readTemplateByPath(template); 132 } 133 List<ExcelHeader> headers = getHeaderList(clz); 134 Collections.sort(headers); 135 //输出标题 136 et.createNewRow(); 137 for(ExcelHeader eh:headers) { 138 et.createCell(eh.getTitle()); 139 } 140 //输出值 141 for(Object obj:objs) { 142 et.createNewRow(); 143 for(ExcelHeader eh:headers) { 144 // Method m = clz.getDeclaredMethod(mn); 145 // Object rel = m.invoke(obj); 146 et.createCell(BeanUtils.getProperty(obj,getMethodName(eh) )); 147 } 148 } 149 } catch (IllegalAccessException e) { 150 e.printStackTrace(); 151 } catch (InvocationTargetException e) { 152 e.printStackTrace(); 153 } catch (NoSuchMethodException e) { 154 e.printStackTrace(); 155 } 156 return et; 157 } 158 /** 159 * 根据标题获取相应的方法名称 160 * @param eh 161 * @return 162 */ 163 public String getMethodName(ExcelHeader eh) { 164 String mn = eh.getMethodName().substring(3); 165 mn = mn.substring(0,1).toLowerCase()+mn.substring(1); 166 return mn; 167 } 168 /** 169 * 将对象转换为Excel并且导出,该方法是基于模板的导出,导出到流 170 * @param datas 模板中的替换的常量数据 171 * @param template 模板路径 172 * @param os 输出流 173 * @param objs 对象列表 174 * @param clz 对象的类型 175 * @param isClasspath 模板是否在classPath路径下 176 */ 177 public void exportObj2ExcelByTemplate(Map<String,String> datas,String template,OutputStream os,List objs,Class clz,boolean isClasspath) { 178 ExcelTemplate et = handlerObj2Excel(template, objs, clz, isClasspath); 179 et.replaceFinalData(datas); 180 et.wirteToStream(os); 181 } 182 /** 183 * 将对象转换为Excel并且导出,该方法是基于模板的导出,导出到一个具体的路径中 184 * @param datas 模板中的替换的常量数据 185 * @param template 模板路径 186 * @param os 输出路径 187 * @param objs 对象列表 188 * @param clz 对象的类型 189 * @param isClasspath 模板是否在classPath路径下 190 */ 191 public void exportObj2ExcelByTemplate(Map<String,String> datas,String template,String outPath,List objs,Class clz,boolean isClasspath) { 192 ExcelTemplate et = handlerObj2Excel(template, objs, clz, isClasspath); 193 et.replaceFinalData(datas); 194 et.writeToFile(outPath); 195 } 196 197 /** 198 * 将对象转换为Excel并且导出,该方法是基于模板的导出,导出到流,基于Properties作为常量数据 199 * @param prop 基于Properties的常量数据模型 200 * @param template 模板路径 201 * @param os 输出流 202 * @param objs 对象列表 203 * @param clz 对象的类型 204 * @param isClasspath 模板是否在classPath路径下 205 */ 206 public void exportObj2ExcelByTemplate(Properties prop,String template,OutputStream os,List objs,Class clz,boolean isClasspath) { 207 ExcelTemplate et = handlerObj2Excel(template, objs, clz, isClasspath); 208 et.replaceFinalData(prop); 209 et.wirteToStream(os); 210 } 211 /** 212 * 将对象转换为Excel并且导出,该方法是基于模板的导出,导出到一个具体的路径中,基于Properties作为常量数据 213 * @param prop 基于Properties的常量数据模型 214 * @param template 模板路径 215 * @param os 输出路径 216 * @param objs 对象列表 217 * @param clz 对象的类型 218 * @param isClasspath 模板是否在classPath路径下 219 */ 220 public void exportObj2ExcelByTemplate(Properties prop,String template,String outPath,List objs,Class clz,boolean isClasspath) { 221 ExcelTemplate et = handlerObj2Excel(template, objs, clz, isClasspath); 222 et.replaceFinalData(prop); 223 et.writeToFile(outPath); 224 } 225 226 private Workbook handleObj2Excel(List objs,Class clz,boolean isXssf) { 227 Workbook wb = null; 228 try { 229 if(isXssf) { 230 wb = new XSSFWorkbook(); 231 } else { 232 wb = new HSSFWorkbook(); 233 } 234 Sheet sheet = wb.createSheet(); 235 Row r = sheet.createRow(0); 236 List<ExcelHeader> headers = getHeaderList(clz); 237 Collections.sort(headers); 238 //写标题 239 for(int i=0;i<headers.size();i++) { 240 r.createCell(i).setCellValue(headers.get(i).getTitle()); 241 } 242 //写数据 243 Object obj = null; 244 for(int i=0;i<objs.size();i++) { 245 r = sheet.createRow(i+1); 246 obj = objs.get(i); 247 for(int j=0;j<headers.size();j++) { 248 r.createCell(j).setCellValue(BeanUtils.getProperty(obj, getMethodName(headers.get(j)))); 249 } 250 } 251 } catch (IllegalAccessException e) { 252 e.printStackTrace(); 253 } catch (InvocationTargetException e) { 254 e.printStackTrace(); 255 } catch (NoSuchMethodException e) { 256 e.printStackTrace(); 257 } 258 return wb; 259 } 260 /** 261 * 导出对象到Excel,不是基于模板的,直接新建一个Excel完成导出,基于路径的导出 262 * @param outPath 导出路径 263 * @param objs 对象列表 264 * @param clz 对象类型 265 * @param isXssf 是否是2007版本 266 */ 267 public void exportObj2Excel(String outPath,List objs,Class clz,boolean isXssf) { 268 Workbook wb = handleObj2Excel(objs, clz, isXssf); 269 FileOutputStream fos = null; 270 try { 271 fos = new FileOutputStream(outPath); 272 wb.write(fos); 273 } catch (FileNotFoundException e) { 274 e.printStackTrace(); 275 } catch (IOException e) { 276 e.printStackTrace(); 277 } finally { 278 try { 279 if(fos!=null) fos.close(); 280 } catch (IOException e) { 281 e.printStackTrace(); 282 } 283 } 284 } 285 /** 286 * 导出对象到Excel,不是基于模板的,直接新建一个Excel完成导出,基于流 287 * @param os 输出流 288 * @param objs 对象列表 289 * @param clz 对象类型 290 * @param isXssf 是否是2007版本 291 */ 292 public void exportObj2Excel(OutputStream os,List objs,Class clz,boolean isXssf) { 293 try { 294 Workbook wb = handleObj2Excel(objs, clz, isXssf); 295 wb.write(os); 296 } catch (IOException e) { 297 e.printStackTrace(); 298 } 299 } 300 /** 301 * 从类路径读取相应的Excel文件到对象列表 302 * @param path 类路径下的path 303 * @param clz 对象类型 304 * @param readLine 开始行,注意是标题所在行 305 * @param tailLine 底部有多少行,在读入对象时,会减去这些行 306 * @return 307 */ 308 public List<Object> readExcel2ObjsByClasspath(String path,Class clz,int readLine,int tailLine) { 309 Workbook wb = null; 310 try { 311 wb = WorkbookFactory.create(ExcelUtil.class.getResourceAsStream(path)); 312 return handlerExcel2Objs(wb, clz, readLine,tailLine); 313 } catch (InvalidFormatException e) { 314 e.printStackTrace(); 315 } catch (IOException e) { 316 e.printStackTrace(); 317 } 318 return null; 319 } 320 /** 321 * 从文件路径读取相应的Excel文件到对象列表 322 * @param path 文件路径下的path 323 * @param clz 对象类型 324 * @param readLine 开始行,注意是标题所在行 325 * @param tailLine 底部有多少行,在读入对象时,会减去这些行 326 * @return 327 */ 328 public List<Object> readExcel2ObjsByPath(String path,Class clz,int readLine,int tailLine) { 329 Workbook wb = null; 330 try { 331 wb = WorkbookFactory.create(new File(path)); 332 return handlerExcel2Objs(wb, clz, readLine,tailLine); 333 } catch (InvalidFormatException e) { 334 e.printStackTrace(); 335 } catch (IOException e) { 336 e.printStackTrace(); 337 } 338 return null; 339 } 340 /** 341 * 从类路径读取相应的Excel文件到对象列表,标题行为0,没有尾行 342 * @param path 路径 343 * @param clz 类型 344 * @return 对象列表 345 */ 346 public List<Object> readExcel2ObjsByClasspath(String path,Class clz) { 347 return this.readExcel2ObjsByClasspath(path, clz, 0,0); 348 } 349 /** 350 * 从文件路径读取相应的Excel文件到对象列表,标题行为0,没有尾行 351 * @param path 路径 352 * @param clz 类型 353 * @return 对象列表 354 */ 355 public List<Object> readExcel2ObjsByPath(String path,Class clz) { 356 return this.readExcel2ObjsByPath(path, clz,0,0); 357 } 358 359 private String getCellValue(Cell c) { 360 String o = null; 361 switch (c.getCellType()) { 362 case Cell.CELL_TYPE_BLANK: 363 o = ""; break; 364 case Cell.CELL_TYPE_BOOLEAN: 365 o = String.valueOf(c.getBooleanCellValue()); break; 366 case Cell.CELL_TYPE_FORMULA: 367 o = String.valueOf(c.getCellFormula()); break; 368 case Cell.CELL_TYPE_NUMERIC: 369 double doubleVal = c.getNumericCellValue(); 370 long longVal = Math.round(c.getNumericCellValue()); 371 if(Double.parseDouble(longVal+".0")==doubleVal){ 372 o = String.valueOf(longVal); break; 373 }else{ 374 o = String.valueOf(doubleVal); break; 375 } 376 case Cell.CELL_TYPE_STRING: 377 o = c.getStringCellValue(); break; 378 default: 379 o = null; 380 break; 381 } 382 return o; 383 } 384 385 public List<Object> handlerExcel2Objs(Workbook wb,Class clz,int readLine,int tailLine) { 386 Sheet sheet = wb.getSheetAt(0); 387 List<Object> objs = null; 388 try { 389 Row row = sheet.getRow(readLine); 390 objs = new ArrayList<Object>(); 391 Map<Integer,String> maps = getHeaderMap(row, clz); 392 if(maps==null||maps.size()<=0) throw new RuntimeException("要读取的Excel的格式不正确,检查是否设定了合适的行"); 393 for(int i=readLine+1;i<=sheet.getLastRowNum()-tailLine;i++) { 394 row = sheet.getRow(i); 395 Object obj = clz.newInstance(); 396 for(Cell c:row) { 397 int ci = c.getColumnIndex(); 398 String mn = maps.get(ci).substring(3); 399 mn = mn.substring(0,1).toLowerCase()+mn.substring(1); 400 BeanUtils.copyProperty(obj,mn, this.getCellValue(c)); 401 // System.out.println("------------"+this.getCellValue(c)); 402 } 403 objs.add(obj); 404 } 405 } catch (InstantiationException e) { 406 e.printStackTrace(); 407 } catch (IllegalAccessException e) { 408 e.printStackTrace(); 409 } catch (InvocationTargetException e) { 410 e.printStackTrace(); 411 } 412 return objs; 413 } 414 415 public List<ExcelHeader> getHeaderList(Class clz) { 416 List<ExcelHeader> headers = new ArrayList<ExcelHeader>(); 417 Method[] ms = clz.getDeclaredMethods(); 418 for(Method m:ms) { 419 String mn = m.getName(); 420 if(mn.startsWith("get")) { 421 if(m.isAnnotationPresent(ExcelResources.class)) { 422 ExcelResources er = m.getAnnotation(ExcelResources.class); 423 headers.add(new ExcelHeader(er.title(),er.order(),mn)); 424 } 425 } 426 } 427 return headers; 428 } 429 430 public Map<Integer,String> getHeaderMap(Row titleRow,Class clz) { 431 List<ExcelHeader> headers = getHeaderList(clz); 432 Map<Integer,String> maps = new HashMap<Integer, String>(); 433 for(Cell c:titleRow) { 434 String title = c.getStringCellValue(); 435 for(ExcelHeader eh:headers) { 436 if(eh.getTitle().equals(title.trim())) { 437 maps.put(c.getColumnIndex(), eh.getMethodName().replace("get","set")); 438 break; 439 } 440 } 441 } 442 return maps; 443 } 444 } 445 446 /----------------**********----------------/ 447 package com.pl.util; 448 449 import java.io.File; 450 import java.io.FileNotFoundException; 451 import java.io.FileOutputStream; 452 import java.io.IOException; 453 import java.io.OutputStream; 454 import java.util.Calendar; 455 import java.util.Date; 456 import java.util.HashMap; 457 import java.util.Map; 458 import java.util.Properties; 459 460 import org.apache.poi.openxml4j.exceptions.InvalidFormatException; 461 import org.apache.poi.ss.usermodel.Cell; 462 import org.apache.poi.ss.usermodel.CellStyle; 463 import org.apache.poi.ss.usermodel.Row; 464 import org.apache.poi.ss.usermodel.Sheet; 465 import org.apache.poi.ss.usermodel.Workbook; 466 import org.apache.poi.ss.usermodel.WorkbookFactory; 467 468 /** 469 * 该类实现了基于模板的导出 470 * 如果要导出序号,需要在excel中定义一个标识为sernums 471 * 如果要替换信息,需要传入一个Map,这个map中存储着要替换信息的值,在excel中通过#来开头 472 * 要从哪一行那一列开始替换需要定义一个标识为datas 473 * 如果要设定相应的样式,可以在该行使用styles完成设定,此时所有此行都使用该样式 474 * 如果使用defaultStyls作为表示,表示默认样式,如果没有defaultStyles使用datas行作为默认样式 475 * @author KongHao 476 * 477 */ 478 public class ExcelTemplate { 479 /** 480 * 数据行标识 481 */ 482 public final static String DATA_LINE = "datas"; 483 /** 484 * 默认样式标识 485 */ 486 public final static String DEFAULT_STYLE = "defaultStyles"; 487 /** 488 * 行样式标识 489 */ 490 public final static String STYLE = "styles"; 491 /** 492 * 插入序号样式标识 493 */ 494 public final static String SER_NUM = "sernums"; 495 private static ExcelTemplate et = new ExcelTemplate(); 496 public Workbook wb; 497 private Sheet sheet; 498 /** 499 * 数据的初始化列数 500 */ 501 private int initColIndex; 502 /** 503 * 数据的初始化行数 504 */ 505 private int initRowIndex; 506 /** 507 * 当前列数 508 */ 509 private int curColIndex; 510 /** 511 * 当前行数 512 */ 513 private int curRowIndex; 514 /** 515 * 当前行对象 516 */ 517 private Row curRow; 518 /** 519 * 最后一行的数据 520 */ 521 private int lastRowIndex; 522 /** 523 * 默认样式 524 */ 525 private CellStyle defaultStyle; 526 /** 527 * 默认行高 528 */ 529 private float rowHeight; 530 /** 531 * 存储某一方所对于的样式 532 */ 533 private Map<Integer,CellStyle> styles; 534 /** 535 * 序号的列 536 */ 537 private int serColIndex; 538 private ExcelTemplate(){ 539 540 } 541 public static ExcelTemplate getInstance() { 542 return et; 543 } 544 //1、读取相应的模板文档 545 /** 546 * 从classpath路径下读取相应的模板文件 547 * @param path 548 * @return 549 */ 550 public ExcelTemplate readTemplateByClasspath(String path) { 551 try { 552 wb = WorkbookFactory.create(ExcelTemplate.class.getResourceAsStream(path)); 553 initTemplate(); 554 } catch (InvalidFormatException e) { 555 e.printStackTrace(); 556 throw new RuntimeException("读取模板格式有错,!请检查"); 557 } catch (IOException e) { 558 e.printStackTrace(); 559 throw new RuntimeException("读取模板不存在!请检查"); 560 } 561 return this; 562 } 563 /** 564 * 将文件写到相应的路径下 565 * @param filepath 566 */ 567 public void writeToFile(String filepath) { 568 FileOutputStream fos = null; 569 try { 570 fos = new FileOutputStream(filepath); 571 wb.write(fos); 572 } catch (FileNotFoundException e) { 573 e.printStackTrace(); 574 throw new RuntimeException("写入的文件不存在"); 575 } catch (IOException e) { 576 e.printStackTrace(); 577 throw new RuntimeException("写入数据失败:"+e.getMessage()); 578 } finally { 579 try { 580 if(fos!=null) fos.close(); 581 } catch (IOException e) { 582 e.printStackTrace(); 583 } 584 } 585 } 586 /** 587 * 将文件写到某个输出流中 588 * @param os 589 */ 590 public void wirteToStream(OutputStream os) { 591 try { 592 wb.write(os); 593 } catch (IOException e) { 594 e.printStackTrace(); 595 throw new RuntimeException("写入流失败:"+e.getMessage()); 596 } 597 } 598 /** 599 * 从某个路径来读取模板 600 * @param path 601 * @return 602 */ 603 public ExcelTemplate readTemplateByPath(String path) { 604 try { 605 wb = WorkbookFactory.create(new File(path)); 606 initTemplate(); 607 } catch (InvalidFormatException e) { 608 e.printStackTrace(); 609 throw new RuntimeException("读取模板格式有错,!请检查"); 610 } catch (IOException e) { 611 e.printStackTrace(); 612 throw new RuntimeException("读取模板不存在!请检查"); 613 } 614 return this; 615 } 616 617 /** 618 * 创建相应的元素,基于String类型 619 * @param value 620 */ 621 public void createCell(String value) { 622 Cell c = curRow.createCell(curColIndex); 623 setCellStyle(c); 624 c.setCellValue(value); 625 curColIndex++; 626 } 627 public void createCell(int value) { 628 Cell c = curRow.createCell(curColIndex); 629 setCellStyle(c); 630 c.setCellValue((int)value); 631 curColIndex++; 632 } 633 public void createCell(Date value) { 634 Cell c = curRow.createCell(curColIndex); 635 setCellStyle(c); 636 c.setCellValue(value); 637 curColIndex++; 638 } 639 public void createCell(double value) { 640 Cell c = curRow.createCell(curColIndex); 641 setCellStyle(c); 642 c.setCellValue(value); 643 curColIndex++; 644 } 645 public void createCell(boolean value) { 646 Cell c = curRow.createCell(curColIndex); 647 setCellStyle(c); 648 c.setCellValue(value); 649 curColIndex++; 650 } 651 652 public void createCell(Calendar value) { 653 Cell c = curRow.createCell(curColIndex); 654 setCellStyle(c); 655 c.setCellValue(value); 656 curColIndex++; 657 } 658 /** 659 * 设置某个元素的样式 660 * @param c 661 */ 662 private void setCellStyle(Cell c) { 663 if(styles.containsKey(curColIndex)) { 664 c.setCellStyle(styles.get(curColIndex)); 665 } else { 666 c.setCellStyle(defaultStyle); 667 } 668 } 669 /** 670 * 创建新行,在使用时只要添加完一行,需要调用该方法创建 671 */ 672 public void createNewRow() { 673 if(lastRowIndex>curRowIndex&&curRowIndex!=initRowIndex) { 674 sheet.shiftRows(curRowIndex, lastRowIndex, 1,true,true); 675 lastRowIndex++; 676 } 677 curRow = sheet.createRow(curRowIndex); 678 curRow.setHeightInPoints(rowHeight); 679 curRowIndex++; 680 curColIndex = initColIndex; 681 } 682 683 /** 684 * 插入序号,会自动找相应的序号标示的位置完成插入 685 */ 686 public void insertSer() { 687 int index = 1; 688 Row row = null; 689 Cell c = null; 690 for(int i=initRowIndex;i<curRowIndex;i++) { 691 row = sheet.getRow(i); 692 c = row.createCell(serColIndex); 693 setCellStyle(c); 694 c.setCellValue(index++); 695 } 696 } 697 /** 698 * 根据map替换相应的常量,通过Map中的值来替换#开头的值 699 * @param datas 700 */ 701 public void replaceFinalData(Map<String,String> datas) { 702 if(datas==null) return; 703 for(Row row:sheet) { 704 for(Cell c:row) { 705 if(c.getCellType()!=Cell.CELL_TYPE_STRING) continue; 706 String str = c.getStringCellValue().trim(); 707 if(str.startsWith("#")) { 708 if(datas.containsKey(str.substring(1))) { 709 c.setCellValue(datas.get(str.substring(1))); 710 } 711 } 712 } 713 } 714 } 715 /** 716 * 基于Properties的替换,依然也是替换#开始的 717 * @param prop 718 */ 719 public void replaceFinalData(Properties prop) { 720 if(prop==null) return; 721 for(Row row:sheet) { 722 for(Cell c:row) { 723 if(c.getCellType()!=Cell.CELL_TYPE_STRING) continue; 724 String str = c.getStringCellValue().trim(); 725 if(str.startsWith("#")) { 726 if(prop.containsKey(str.substring(1))) { 727 c.setCellValue(prop.getProperty(str.substring(1))); 728 } 729 } 730 } 731 } 732 } 733 734 private void initTemplate() { 735 sheet = wb.getSheetAt(0); 736 initConfigData(); 737 lastRowIndex = sheet.getLastRowNum(); 738 curRow = sheet.createRow(curRowIndex); 739 } 740 /** 741 * 初始化数据信息 742 */ 743 private void initConfigData() { 744 boolean findData = false; 745 boolean findSer = false; 746 for(Row row:sheet) { 747 if(findData) break; 748 for(Cell c:row) { 749 if(c.getCellType()!=Cell.CELL_TYPE_STRING) continue; 750 String str = c.getStringCellValue().trim(); 751 if(str.equals(SER_NUM)) { 752 serColIndex = c.getColumnIndex(); 753 findSer = true; 754 } 755 if(str.equals(DATA_LINE)) { 756 initColIndex = c.getColumnIndex(); 757 initRowIndex = row.getRowNum(); 758 curColIndex = initColIndex; 759 curRowIndex = initRowIndex; 760 findData = true; 761 defaultStyle = c.getCellStyle(); 762 rowHeight = row.getHeightInPoints(); 763 initStyles(); 764 break; 765 } 766 } 767 } 768 if(!findSer) { 769 initSer(); 770 } 771 System.out.println(curColIndex+","+curRowIndex); 772 } 773 /** 774 * 初始化序号位置 775 */ 776 private void initSer() { 777 for(Row row:sheet) { 778 for(Cell c:row) { 779 if(c.getCellType()!=Cell.CELL_TYPE_STRING) continue; 780 String str = c.getStringCellValue().trim(); 781 if(str.equals(SER_NUM)) { 782 serColIndex = c.getColumnIndex(); 783 } 784 } 785 } 786 } 787 /** 788 * 初始化样式信息 789 */ 790 private void initStyles() { 791 styles = new HashMap<Integer, CellStyle>(); 792 for(Row row:sheet) { 793 for(Cell c:row) { 794 if(c.getCellType()!=Cell.CELL_TYPE_STRING) continue; 795 String str = c.getStringCellValue().trim(); 796 if(str.equals(DEFAULT_STYLE)) { 797 defaultStyle = c.getCellStyle(); 798 } 799 if(str.equals(STYLE)) { 800 styles.put(c.getColumnIndex(), c.getCellStyle()); 801 } 802 } 803 } 804 } 805 }
3. 引入相应xls模版到src目录下
4. 配置struts.xml
<action name="viewSelfExcel" class="com.pl.action.ViewExcelAction" method="viewSelfExcel"> <result type="stream"> <param name="contentType">application/vnd.ms-excel</param> <param name="contentDisposition">attachment;filename="${downloadFileName}"</param> <param name="bufferSize">1024</param> <param name="inputName">excelFile</param> </result> </action>
5. ViewExcelAction
package com.pl.action; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.text.DecimalFormat; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.servlet.http.HttpSession; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.struts2.ServletActionContext; import com.pl.pojo.Department; import com.pl.pojo.Teacher; import com.pl.pojo.TempWorkloadAccount; import com.pl.service.ComputeService; import com.pl.util.ExcelTemplate; import com.pl.util.ExcelUtil; public class ViewExcelAction { ......... //替换模版的对应变量 private Map<String,String> map; //获取输入流,要和配置中的名字对应 private InputStream excelFile; //设置下载文件名 private String downloadFileName; public InputStream getExcelFile() { return excelFile; } public void setExcelFile(InputStream excelFile) { this.excelFile = excelFile; } public String getDownloadFileName() { SimpleDateFormat sf = new SimpleDateFormat("MMddhhmmss"); String downFileName = (sf.format(new Date())).toString()+"工作量.xls"; try { downFileName = new String(downFileName.getBytes(),"ISO8859-1"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } downloadFileName = downFileName; return downloadFileName; } public void setDownloadFileName(String downloadFileName) { this.downloadFileName = downloadFileName; } public String viewSelfExcel(){ try { ...... map = new HashMap<String, String>(); map.put("title1","计算机学院教师工作量表"); map.put("title2","系 名"); map.put("title3","教 师"); map.put("teacherName",teacher.getTeacherName()); map.put("title4","教学总工作量"); map.put("title5","教日"); map.put("title6","指导研究生总工作量"); map.put("dept", department.getDepartmentName()); map.put("sum1", Double.toString(workloadSum)); map.put("sum2", Double.toString(workloadGraduated)); //关键步骤,获取工具类实例,套用模版方法,只需要传入相应的数据集合,如tempWorkloadAccountArray ExcelUtil eu = ExcelUtil.getInstance(); ExcelTemplate et = eu.handlerObj2Excel("/querySelf.xls", tempWorkloadAccountArray, TempWorkloadAccount.class, true); //使用模版中替换数据的方法 et.replaceFinalData(map); //获取相应workbook HSSFWorkbook workbook = (HSSFWorkbook) et.wb; //得到字节流输出 ByteArrayOutputStream output = new ByteArrayOutputStream(); workbook.write(output); byte[] ba = output.toByteArray(); excelFile = new ByteArrayInputStream(ba); output.flush(); output.close(); return "success"; } catch (NumberFormatException e) { e.printStackTrace(); return "fail"; } catch (IOException e) { e.printStackTrace(); return "fail"; } } }
时间: 2024-10-11 06:12:06