JAVA报表

  1. package com.app.common.excel;
  2.  
  3. import java.io.File;
  4.  
  5. import java.io.FileInputStream;
  6.  
  7. import java.lang.reflect.Field;
  8.  
  9. import java.lang.reflect.Method;
  10.  
  11. import java.lang.reflect.Type;
  12.  
  13. import java.text.DecimalFormat;
  14.  
  15. import java.text.SimpleDateFormat;
  16.  
  17. import java.util.ArrayList;
  18.  
  19. import java.util.Collection;
  20.  
  21. import java.util.Date;
  22.  
  23. import java.util.HashMap;
  24.  
  25. import java.util.Iterator;
  26.  
  27. import java.util.Map;
  28.  
  29. import org.apache.poi.hssf.usermodel.HSSFCell;
  30.  
  31. import org.apache.poi.hssf.usermodel.HSSFDateUtil;
  32.  
  33. import org.apache.poi.hssf.usermodel.HSSFRow;
  34.  
  35. import org.apache.poi.hssf.usermodel.HSSFSheet;
  36.  
  37. import org.apache.poi.hssf.usermodel.HSSFWorkbook;
  38.  
  39. import com.app.common.excel.annotation.ExcelAnnotation;
  40.  
  41. import com.app.common.utils.StringUtils;
  42.  
  43. /**
  44.  
  45. * EXCEL通用导入(根据annotation判断导入字段)
  46.  
  47. *
  48.  
  49. * @author ZhouBo
  50.  
  51. *
  52.  
  53. * @param <T>,Model对象
  54.  
  55. * @since 2011-07-12
  56.  
  57. */
  58.  
  59. public class ExcelImport<T> {
  60.  
  61. Class<T> clazz;
  62.  
  63. public ExcelImport(Class<T> clazz) {
  64.  
  65. this.clazz = clazz;
  66.  
  67. }
  68.  
  69. @SuppressWarnings("unchecked")
  70.  
  71. public Collection<T> importExcel(File file, String... pattern) {
  72.  
  73. Collection<T> dist = new ArrayList();
  74.  
  75. try {
  76.  
  77. /**
  78.  
  79. * 类反射得到调用方法
  80.  
  81. */
  82.  
  83. // 得到目标目标类的所有的字段列表
  84.  
  85. Field filed[] = clazz.getDeclaredFields();
  86.  
  87. // 将所有标有Annotation的字段,也就是允许导入数据的字段,放入到一个map中
  88.  
  89. Map fieldmap = new HashMap();
  90.  
  91. // 循环读取所有字段
  92.  
  93. for (int i = 0; i < filed.length; i++) {
  94.  
  95. Field f = filed[i];
  96.  
  97. // 得到单个字段上的Annotation
  98.  
  99. ExcelAnnotation exa = f.getAnnotation(ExcelAnnotation.class);
  100.  
  101. // 如果标识了Annotationd的话
  102.  
  103. if (exa != null) {
  104.  
  105. // 构造设置了Annotation的字段的Setter方法
  106.  
  107. String fieldname = f.getName();
  108.  
  109. String setMethodName = "set"
  110.  
  111. + fieldname.substring(0, 1).toUpperCase()
  112.  
  113. + fieldname.substring(1);
  114.  
  115. // 构造调用的method,
  116.  
  117. Method setMethod = clazz.getMethod(setMethodName,
  118.  
  119. new Class[] { f.getType() });
  120.  
  121. // 将这个method以Annotaion的名字为key来存入。
  122.  
  123. fieldmap.put(exa.exportName(), setMethod);
  124.  
  125. }
  126.  
  127. }
  128.  
  129. /**
  130.  
  131. * excel的解析开始
  132.  
  133. */
  134.  
  135. // 将传入的File构造为FileInputStream;
  136.  
  137. FileInputStream in = new FileInputStream(file);
  138.  
  139. // // 得到工作表
  140.  
  141. HSSFWorkbook book = new HSSFWorkbook(in);
  142.  
  143. // // 得到第一页
  144.  
  145. HSSFSheet sheet = book.getSheetAt(0);
  146.  
  147. // // 得到第一面的所有行
  148.  
  149. Iterator<HSSFRow> row = sheet.rowIterator();
  150.  
  151. /**
  152.  
  153. * 标题解析
  154.  
  155. */
  156.  
  157. // 得到第一行,也就是标题行
  158.  
  159. HSSFRow title = row.next();
  160.  
  161. // 得到第一行的所有列
  162.  
  163. Iterator<HSSFCell> cellTitle = title.cellIterator();
  164.  
  165. // 将标题的文字内容放入到一个map中。
  166.  
  167. Map titlemap = new HashMap();
  168.  
  169. // 从标题第一列开始
  170.  
  171. int i = 0;
  172.  
  173. // 循环标题所有的列
  174.  
  175. while (cellTitle.hasNext()) {
  176.  
  177. HSSFCell cell = cellTitle.next();
  178.  
  179. String value = cell.getStringCellValue();
  180.  
  181. titlemap.put(i, value);
  182.  
  183. i = i + 1;
  184.  
  185. }
  186.  
  187. /**
  188.  
  189. * 解析内容行
  190.  
  191. */
  192.  
  193. // 用来格式化日期的DateFormat
  194.  
  195. SimpleDateFormat sf;
  196.  
  197. if (pattern.length < 1) {
  198.  
  199. sf = new SimpleDateFormat("yyyy-MM-dd");
  200.  
  201. } else
  202.  
  203. sf = new SimpleDateFormat(pattern[0]);
  204.  
  205. int w = 0;
  206.  
  207. while (row.hasNext()) {
  208.  
  209. // 标题下的第一行
  210.  
  211. HSSFRow rown = row.next();
  212.  
  213. // 行的所有列
  214.  
  215. //Iterator<HSSFCell> cellbody = rown.cellIterator();
  216.  
  217. // 得到传入类的实例
  218.  
  219. T tObject = clazz.newInstance();
  220.  
  221. short k = 0;
  222.  
  223. // 遍历一行的列
  224.  
  225. w++;
  226.  
  227. //while (cellbody.hasNext()) {
  228.  
  229. for(k=0; k < title.getLastCellNum(); k++) {
  230.  
  231. //HSSFCell cell = cellbody.next();
  232.  
  233. HSSFCell cell = rown.getCell(k);
  234.  
  235. // 这里得到此列的对应的标题
  236.  
  237. String titleString = (String) titlemap.get((int)k);
  238.  
  239. // 如果这一列的标题和类中的某一列的Annotation相同,那么则调用此类的的set方法,进行设值
  240.  
  241. if (fieldmap.containsKey(titleString)) {
  242.  
  243. Method setMethod = (Method) fieldmap.get(titleString);
  244.  
  245. // 得到setter方法的参数
  246.  
  247. Type[] ts = setMethod.getGenericParameterTypes();
  248.  
  249. // 只要一个参数
  250.  
  251. String xclass = ts[0].toString();
  252.  
  253. String cons = null;
  254.  
  255. if (cell == null) {
  256.  
  257. cons = "";
  258.  
  259. continue;
  260.  
  261. }
  262.  
  263. else if (cell.getCellType() == HSSFCell.CELL_TYPE_STRING) {
  264.  
  265. cons = cell.getStringCellValue();
  266.  
  267. }
  268.  
  269. else if (cell.getCellType() == HSSFCell.CELL_TYPE_NUMERIC) {
  270.  
  271. if(HSSFDateUtil.isCellDateFormatted(cell)) {
  272.  
  273. Date date = cell.getDateCellValue();
  274.  
  275. cons = (date.getYear() + 1900) + "-" + (date.getMonth() + 1) + "-" + date.getDate();
  276.  
  277. } else {
  278.  
  279. // 是否为数值型
  280.  
  281. double d = cell.getNumericCellValue();
  282.  
  283. if (d - (int) d < Double.MIN_VALUE) {
  284.  
  285. // 是否为int型
  286.  
  287. cons = Integer.toString((int) d);
  288.  
  289. } else {
  290.  
  291. System.out.println("double.....");
  292.  
  293. // 是否为double型
  294.  
  295. DecimalFormat df = new DecimalFormat("#");
  296.  
  297. cons = df.format(cell.getNumericCellValue());
  298.  
  299. }
  300.  
  301. }
  302.  
  303. }
  304.  
  305. ///
  306.  
  307. /*
  308.  
  309. if (cell.getCellType() == HSSFCell.CELL_TYPE_NUMERIC) {
  310.  
  311. DateFormat format = new SimpleDateFormat(DateUtil.YYYY_MM_DD);
  312.  
  313. if(HSSFDateUtil.isCellDateFormatted(cell)) {
  314.  
  315. // 是否为日期型
  316.  
  317. str = format.format(cell.getDateCellValue());
  318.  
  319. } else {
  320.  
  321. // 是否为数值型
  322.  
  323. double d = cell.getNumericCellValue();
  324.  
  325. if (d - (int) d < Double.MIN_VALUE) {
  326.  
  327. // 是否为int型
  328.  
  329. str = Integer.toString((int) d);
  330.  
  331. } else {
  332.  
  333. System.out.println("double.....");
  334.  
  335. // 是否为double型
  336.  
  337. str = Double.toString(cell.getNumericCellValue());
  338.  
  339. }
  340.  
  341. }
  342.  
  343. System.out.println("type=="+cell.getCellType() );
  344.  
  345. System.out.println("cell=="+str);
  346.  
  347. }else if (cell.getCellType() == HSSFCell.CELL_TYPE_STRING) {
  348.  
  349. str = cell.getRichStringCellValue().getString();
  350.  
  351. }else if (cell.getCellType() == HSSFCell.CELL_TYPE_FORMULA) {
  352.  
  353. str = cell.getCellFormula();
  354.  
  355. }else if (cell.getCellType() == HSSFCell.CELL_TYPE_BLANK) {
  356.  
  357. str = " ";
  358.  
  359. }else if (cell.getCellType() == HSSFCell.CELL_TYPE_ERROR) {
  360.  
  361. str = " ";
  362.  
  363. }
  364.  
  365. */
  366.  
  367. ///
  368.  
  369. if (StringUtils.hasText(cons)
  370.  
  371. && cons.indexOf(".0") != -1) {
  372.  
  373. cons = cons.substring(0, cons.indexOf(".0"));
  374.  
  375. }
  376.  
  377. // 判断参数类型
  378.  
  379. if (xclass.equals("class java.lang.String")) {
  380.  
  381. setMethod.invoke(tObject, cons);
  382.  
  383. } else if (xclass.equals("class java.util.Date")) {
  384.  
  385. setMethod.invoke(tObject, sf.parse(cons));
  386.  
  387. } else if (xclass.equals("class java.lang.Boolean")) {
  388.  
  389. Boolean boolname = true;
  390.  
  391. if (cell.getStringCellValue().equals("否")) {
  392.  
  393. boolname = false;
  394.  
  395. }
  396.  
  397. setMethod.invoke(tObject, boolname);
  398.  
  399. } else if (xclass.equals("class java.lang.Integer")) {
  400.  
  401. // 截取小数点
  402.  
  403. if (StringUtils.hasText(cons)) {
  404.  
  405. if (cons.indexOf(".") >= 0)
  406.  
  407. cons = cons.substring(0, cons.indexOf("."));
  408.  
  409. setMethod.invoke(tObject, new Integer(cons));
  410.  
  411. }
  412.  
  413. } else if (xclass.equals("class java.lang.Long")) {
  414.  
  415. setMethod.invoke(tObject, new Long(cons));
  416.  
  417. }
  418.  
  419. }
  420.  
  421. // 下一列
  422.  
  423. //k = k + 1;
  424.  
  425. }
  426.  
  427. //}
  428.  
  429. dist.add(tObject);
  430.  
  431. }
  432.  
  433. } catch (Exception e) {
  434.  
  435. e.printStackTrace();
  436.  
  437. return null;
  438.  
  439. }
  440.  
  441. return dist;
  442.  
  443. }
  444.  
  445. }

要导入的实体类

/** 贷款联系人 */

@ExcelAnnotation(exportName = "联系人", exportFieldWidth = 60, exportConvertSign = 0, importConvertSign = 0)

private String linkMan;

/** 贷款联系人电话 */

@ExcelAnnotation(exportName = "联系人电话", exportFieldWidth = 60, exportConvertSign = 0, importConvertSign = 0)

private String linkTel;

/** 联系人职务 */

@ExcelAnnotation(exportName = "联系人职务", exportFieldWidth = 60, exportConvertSign = 0, importConvertSign = 0)

private String linkJob;

/** 联系人邮箱 */

@ExcelAnnotation(exportName = "联系人邮箱", exportFieldWidth = 60, exportConvertSign = 0, importConvertSign = 0)

private String linkMail;

/** 添加人 */

@ExcelAnnotation(exportName = "跟踪人", exportFieldWidth = 60, exportConvertSign = 0, importConvertSign = 0)

需要导入的字段就加上@ExcelAnnotation
excel表头跟 exportName一致就可以自动识别导入

河南省豫资城乡投资发展有限公司

importExcel运用注解实现EXCEL导入poi类的更多相关文章

  1. Excel导入工具类

    项目需要从Excel导入数据,然后插入到数据库对应表中.设计了一个导入工具类,导入数据和导入结果如下图示: poi jar版本采用的3.15 导入工具类实现如下: package com.alphaj ...

  2. Excel导入工具类兼容xls和xlsx

    package com.bj58.finance.platform.operation.provider.util; import org.apache.log4j.Logger; import or ...

  3. 不依赖Excel是否安装的Excel导入导出类

    本文利用第三方开源库NPOI实现Excel97-2003,Excel2007+的数据导入导出操作. 不依赖Office是否安装.NPOI开源项目地址:http://npoi.codeplex.com/ ...

  4. .net core 基于NPOI 的excel导入导出类,支持自定义导出哪些字段,和判断导入是否有失败的记录

    #region 从Excel导入 //用法 //var cellHeader = new Dictionary<string, string>(); //cellHeader.Add(&q ...

  5. 一个基于POI的通用excel导入导出工具类的简单实现及使用方法

    前言: 最近PM来了一个需求,简单来说就是在录入数据时一条一条插入到系统显得非常麻烦,让我实现一个直接通过excel导入的方法一次性录入所有数据.网上关于excel导入导出的例子很多,但大多相互借鉴. ...

  6. 170313、poi:采用自定义注解的方式导入、导出excel(这种方式比较好扩展)

    步骤一.自定义注解 步骤二.写Excel泛型工具类 步骤三.在需要导出excel的类属相上加上自定义注解,并设置 步骤四.写service,controller 步骤一:自定义注解 import ja ...

  7. POI导入导出excel(附工具类)

    关于POI导出excel的功能我在前面的文章已经写过了,POI导出excel的三种方式 , 导出表格数据到excel并下载(HSSFWorkbook版) ,本篇文章主要是将导入导出功能进一步地封装,在 ...

  8. Java基于注解和反射导入导出Excel

    代码地址如下:http://www.demodashi.com/demo/11995.html 1. 构建项目 使用Spring Boot快速构建一个Web工程,并导入与操作Excel相关的POI包以 ...

  9. POI之Excel导入

    1,maven配置 <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-oox ...

随机推荐

  1. BP神经网络基本原理

    2.1 BP神经网络基本原理 BP网络模型处理信息的基本原理是:输入信号Xi通过中间节点(隐层点)作用于输出节点,经过非线形变换,产生输出信号Yk,网络训练的每一个样本包含输入向量X和期望输出量t,网 ...

  2. 史上比较用心的纯代码实现 AutoLayout

    入职有两三个月了吧,都是使用 Objective-C 纯代码(虽然有时候偷偷参杂一些 Swift 开源库)来编写公司APP,写布局的时候几乎都是要么在初始化的时候用 initWithFrame,要么就 ...

  3. raft 分布式协议 -- mongodb

    http://www.mongoing.com/presentations/webinar-raft-consensus-in-mongodb#rd

  4. 编写跨平台代码之memory alignment

    编写网络包(存储在堆上)转换程序时,在hp-ux机器上运行时会遇到 si_code: 1 - BUS_ADRALN - Invalid address alignment. Please refer ...

  5. hdu2049.java

    hdu 2049 不容易系列之(4)——考新郎 (组合+错排) 国庆期间,省城HZ刚刚举行了一场盛大的集体婚礼,为了使婚礼进行的丰富一些,司仪临时想出了有一个有意思的节目,叫做"考新郎&qu ...

  6. ( 转 )Github配置

    以下转自 http://liuzhijun.iteye.com/blog/1457207 有问题请联系我删除. -----———————————————————————— 如果你的代码不知道放哪里好, ...

  7. SQL 中case when then else 用法

    SQL如下: SELECT DISTINCTsy_haken_type,sy_sagyo_type,sy_kokyaku_cdFROm tbl_syukeiWHERE (sy_sagyo_ymd be ...

  8. javascript类继承系列三(对象伪装)

    原理:在子类的构造器上调用超类构造器(父类构造器中的this指向子类实例),js提供了apply()和call()函数,可以实现这种调用 function baseClass() { this.col ...

  9. iOS开发进阶--1.多线程简介

    学习是由已知的知识模型推理未知的知识模型的的过程. 本文适合学习完objective-c基础,想进一步提高做iOS开发的同学阅读. 在说线程的时候,我们先看看进程. 1.进程 每一个运行在系统中的应用 ...

  10. Lucene5.x 中文 同义词

    查询好好多资料,英文同义词好好的,中文就不行,多谢网友支持,拼接了好多代码,然后修改了一些,不足之处,多谢指正. 直接上代码吧,在代码中了解怎么分词的最好 1,创建分词引擎 public interf ...