java多线程导入excel(poi)

Posted gang-bryant

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java多线程导入excel(poi)相关的知识,希望对你有一定的参考价值。

导入excel util

  1 /**
  2  * @Description: excel导入工具类
  3 
  4  * @Author: hg
  5 
  6  * @CreateDate: 2019/6/4 11:58
  7 
  8  */
  9 @SuppressWarnings("all")
 10 public class POIUtil<T> 
 11 
 12     private Logger logger = LoggerFactory.getLogger(this.getClass());
 13 
 14     private Workbook wb;
 15 
 16     private String[] property;
 17 
 18     private Class<T> c;
 19 
 20     private String filePath;
 21 
 22     private int startRow;
 23     
 24     private int startColumn;
 25 
 26     //是否需要hash
 27     private boolean isHash = false;
 28 
 29     //存放hash集合
 30     private HashSet<Integer> hashSet;
 31   
 32     private CopyOnWriteArrayList beanList;
 33 
 34     public CopyOnWriteArrayList getBeanList() 
 35         return beanList;
 36     
 37 
 38     public POIUtil(String[] property, Class<T> c, String filePath, int startRow, int startColumn) 
 39         this.property = property;
 40         this.c = c;
 41         this.filePath = filePath;
 42         this.wb = getWorkbook(filePath);
 43         this.startRow = startRow;
 44         this.startColumn = startColumn;
 45         this.beanList = new CopyOnWriteArrayList();
 46     
 47 
 48     /**
 49      * @Description:
 50      * @Param: [property 类的属性字符串数组, c class对下你给, filePath excel地址,
 51      * startRow 开始行, startColumn 开始列, hashSet 不需要必填,hash校验]
 52      * @return:
 53      * @Author: hg
 54      * @Date: 2019/6/4
 55      */
 56     public POIUtil(String[] property, Class<T> c, String filePath, int startRow, int startColumn, HashSet<Integer> hashSet) 
 57         this.property = property;
 58         this.c = c;
 59         this.filePath = filePath;
 60         this.wb = getWorkbook(filePath);
 61         this.startRow = startRow;
 62         this.startColumn = startColumn;
 63         this.hashSet = hashSet;
 64         this.isHash = true;
 65         this.beanList = new CopyOnWriteArrayList();
 66     
 67 
 68     /**
 69      * @Description:
 70      * @Param: [startSheet sheet开始, endSheet sheet结束]
 71      * @return: void
 72      * @Author: hg
 73      * @Date: 2019/6/4
 74      */
 75     public void getBeanList(int startSheet, int endSheet) throws IllegalAccessException, InstantiationException, InvocationTargetException 
 76         HashMap<String, String> valueMap = new HashMap<>();
 77         for (int sheetNum = startSheet; sheetNum < endSheet; sheetNum++) 
 78             Sheet sheet = wb.getSheetAt(sheetNum);
 79             for (int rowNum = startRow; rowNum < sheet.getPhysicalNumberOfRows(); rowNum++) 
 80                 Row row = sheet.getRow(rowNum);
 81                 for (int i = 0, columnNum = startColumn; i < property.length; i++, columnNum++) 
 82                     Cell cell = row.getCell(columnNum);
 83                     valueMap.put(property[i], getCellValue(cell, cell.getCellType()));
 84                 
 85                 //这里使用clone效率更高
 86                 T t = c.newInstance();
 87                 BeanUtils.populate(t, valueMap);
 88 
 89                 //校验非空值
 90                 try 
 91                     ValidatorUtils.validateEntity(t);
 92                  catch (WLHSEException e) 
 93                     continue;
 94                 
 95 
 96                 //hash校验
 97                 if (isHash) 
 98                     synchronized (hashSet) 
 99                         if (hashSet.contains(t.hashCode()))
100                             continue;
101                         hashSet.add(t.hashCode());
102                     
103                 
104                 beanList.add(t);
105             
106         
107     
108 
109     private Workbook getWorkbook(String filePath) 
110         Workbook wb = null;
111         try 
112             if (null != filePath) 
113                 FileInputStream fis = new FileInputStream(filePath);
114                 if (filePath.endsWith(".xls")) 
115                     wb = new HSSFWorkbook(fis);
116                  else if (filePath.endsWith(".xlsx")) 
117                     wb = new XSSFWorkbook(fis);
118                 
119                 return wb;
120             
121          catch (Exception e) 
122             logger.error(e.getMessage(), e);
123         
124         return null;
125     
126 
127     private String getCellValue(Cell rowCell, int rowCellType) 
128         String value = "";
129         switch (rowCellType) 
130             case Cell.CELL_TYPE_STRING:
131                 value = rowCell.getStringCellValue();
132                 break;
133             case Cell.CELL_TYPE_NUMERIC:
134                 String dataFormat = rowCell.getCellStyle().getDataFormatString();
135                 AtomicReference<Boolean> isDate = new AtomicReference<>(false);
136                 if (DateUtil.isCellDateFormatted(rowCell)) 
137                     value = new SimpleDateFormat("yyyy-MM-dd").format(DateUtil.getJavaDate(rowCell.getNumericCellValue()));
138                  else if (DateUtil.isCellInternalDateFormatted(rowCell)) 
139                     value = new SimpleDateFormat("yyyy-MM-dd").format(DateUtil.getJavaDate(rowCell.getNumericCellValue()));
140                  else if (isDate.get()) 
141                     value = new SimpleDateFormat("yyyy-MM-dd").format(rowCell.getDateCellValue());
142                  else if (dataFormat == null) 
143                     value = new SimpleDateFormat("yyyy-MM-dd").format(DateUtil.getJavaDate(rowCell.getNumericCellValue()));
144                  else 
145                     if (dataFormat != null) 
146                         value = String.valueOf(rowCell.getNumericCellValue());
147                      else 
148                         if (rowCell.getCellStyle().getDataFormatString().contains("$")) 
149                             value = "$" + rowCell.getNumericCellValue();
150                          else if (rowCell.getCellStyle().getDataFormatString().contains("¥")) 
151                             value = "¥" + rowCell.getNumericCellValue();
152                          else if (rowCell.getCellStyle().getDataFormatString().contains("¥")) 
153                             value = "¥" + rowCell.getNumericCellValue();
154                          else if (rowCell.getCellStyle().getDataFormatString().contains("€")) 
155                             value = "€" + String.valueOf(rowCell.getNumericCellValue());
156                          else 
157                             value = String.valueOf(rowCell.getNumericCellValue());
158                         
159                     
160                 
161                 break;
162             case Cell.CELL_TYPE_BOOLEAN:
163                 value = String.valueOf(rowCell.getBooleanCellValue());
164                 break;
165             case Cell.CELL_TYPE_ERROR:
166                 value = ErrorEval.getText(rowCell.getErrorCellValue());
167                 break;
168             case Cell.CELL_TYPE_FORMULA:
169                 value = rowCell.getCellFormula();
170                 break;
171         
172         return value;
173     
174 
175     public Workbook getWb() 
176         return wb;
177     
178 

导入excel线程

 1 public class POIThread implements Runnable 
 2     private int startSheet;
 3     private int endSheet;
 4     private POIUtil util;
 5     private CountDownLatch countDownLatch;
 6 
 7 
 8     POIThread(int startSheet, int endSheet, POIUtil util, CountDownLatch countDownLatch) 
 9         this.startSheet = startSheet;
10         this.endSheet = endSheet;
11         this.util = util;
12         this.countDownLatch = countDownLatch;
13     
14 
15     @Override
16     public void run() 
17         try 
18             util.getBeanList(startSheet, endSheet);
19          catch (IllegalAccessException | InstantiationException | InvocationTargetException e) 
20             e.printStackTrace();
21          finally 
22             countDownLatch.countDown();
23         
24     
25 

 

执行线程

 1 public class POIThreadHelper 
 2     public void work(POIUtil util) 
 3         //一个sheet分配一个线程
 4         int runSize = util.getWb().getNumberOfSheets();
 5 
 6         ExecutorService executor = Executors.newFixedThreadPool(runSize);
 7         CountDownLatch countDownLatch = new CountDownLatch(runSize);
 8 
 9         for (int i = 0; i < runSize; i++) 
10             executor.execute(new POIThread(i, i + 1, util,countDownLatch));
11         
12 
13         try 
14             countDownLatch.await();
15          catch (InterruptedException e) 
16             e.printStackTrace();
17         
18         executor.shutdown();
19     
20 

 

测试

 1 @Test
 2     public void test1() throws IllegalAccessException, InvocationTargetException, InstantiationException 
 3         String path = "C:\\\\logs\\\\test.xls";
 4         String[] test = "name", "sex";
 5         POIUtil<Student> poiUtil = new POIUtil<Student>(test, Student.class, path, 1, 0);
 6         POIThreadHelper helper = new POIThreadHelper();
 7         helper.work(poiUtil);
 8         for (Object o : poiUtil.getBeanList()) 
 9             System.out.println(o.toString());
10         
11     

 技术图片

技术图片

 

 

 

结果

技术图片

 

以上是关于java多线程导入excel(poi)的主要内容,如果未能解决你的问题,请参考以下文章

Java-poi-excel-对空值单元格的读取

java通过poi包导入Excel

Java使用POI导入Excel文件

Java使用POI导入Excel文件

Java poi导入excel(合并单元格的excel)(转)

java poi xwpf操作word生成一个表格怎么合并单元格,求大神指导!