java中excel导入\导出工具类

1.导入工具

  1 package com.linrain.jcs.test;
  2
  3
  4 import jxl.Cell;
  5 import jxl.Sheet;
  6 import jxl.Workbook;
  7 import jxl.write.Label;
  8 import jxl.write.WritableSheet;
  9
 10 import java.io.InputStream;
 11 import java.lang.reflect.Field;
 12 import java.text.SimpleDateFormat;
 13 import java.util.*;
 14
 15
 16 /**
 17  * @Description: 导入excel工具类
 18  * @CreateDate: 2019/1/24/0024$ 19:39$
 19  * @Version: 1.0
 20  */
 21 public class ImportExcelUtil {
 22
 23
 24     /**
 25      * @param in           :承载着Excel的输入流
 26      * @param :要导入的工作表序号
 27      * @param entityClass  :List中对象的类型(Excel中的每一行都要转化为该类型的对象)
 28      * @param fieldMap     :Excel中的中文列头和类的英文属性的对应关系Map
 29      * @param uniqueFields :指定业务主键组合(即复合主键),这些列的组合不能重复
 30      * @return :List
 31      * @throws ExcelException
 32      * @MethodName : excelToList
 33      * @Description : 将Excel转化为List
 34      */
 35     public static <T> List<T> excelToList(InputStream in, String sheetName, Class<T> entityClass,
 36                                           LinkedHashMap<String, String> fieldMap, String[] uniqueFields) throws ExcelException {
 37
 38         //定义要返回的list
 39         List<T> resultList = new ArrayList<T>();
 40
 41         try {
 42
 43             //根据Excel数据源创建WorkBook
 44             Workbook wb = Workbook.getWorkbook(in);
 45             //获取工作表
 46             Sheet sheet = wb.getSheet(sheetName);
 47
 48             //获取工作表的有效行数
 49             int realRows = 0;
 50             for (int i = 0; i < sheet.getRows(); i++) {
 51
 52                 int nullCols = 0;
 53                 for (int j = 0; j < sheet.getColumns(); j++) {
 54                     Cell currentCell = sheet.getCell(j, i);
 55                     if (currentCell == null || "".equals(currentCell.getContents().toString())) {
 56                         nullCols++;
 57                     }
 58                 }
 59
 60                 if (nullCols == sheet.getColumns()) {
 61                     break;
 62                 } else {
 63                     realRows++;
 64                 }
 65             }
 66
 67
 68             //如果Excel中没有数据则提示错误
 69             if (realRows <= 1) {
 70                 throw new ExcelException("Excel文件中没有任何数据");
 71             }
 72
 73
 74             Cell[] firstRow = sheet.getRow(0);
 75
 76             String[] excelFieldNames = new String[firstRow.length];
 77
 78             //获取Excel中的列名
 79             for (int i = 0; i < firstRow.length; i++) {
 80                 excelFieldNames[i] = firstRow[i].getContents().toString().trim();
 81             }
 82
 83             //判断需要的字段在Excel中是否都存在
 84             boolean isExist = true;
 85             List<String> excelFieldList = Arrays.asList(excelFieldNames);
 86             for (String cnName : fieldMap.keySet()) {
 87                 if (!excelFieldList.contains(cnName)) {
 88                     isExist = false;
 89                     break;
 90                 }
 91             }
 92
 93             //如果有列名不存在,则抛出异常,提示错误
 94             if (!isExist) {
 95                 throw new ExcelException("Excel中缺少必要的字段,或字段名称有误");
 96             }
 97
 98
 99             //将列名和列号放入Map中,这样通过列名就可以拿到列号
100             LinkedHashMap<String, Integer> colMap = new LinkedHashMap<String, Integer>();
101             for (int i = 0; i < excelFieldNames.length; i++) {
102                 colMap.put(excelFieldNames[i], firstRow[i].getColumn());
103             }
104
105
106             //判断是否有重复行
107             //1.获取uniqueFields指定的列
108             Cell[][] uniqueCells = new Cell[uniqueFields.length][];
109             for (int i = 0; i < uniqueFields.length; i++) {
110                 int col = colMap.get(uniqueFields[i]);
111                 uniqueCells[i] = sheet.getColumn(col);
112             }
113
114             //2.从指定列中寻找重复行
115             for (int i = 1; i < realRows; i++) {
116                 int nullCols = 0;
117                 for (int j = 0; j < uniqueFields.length; j++) {
118                     String currentContent = uniqueCells[j][i].getContents();
119                     Cell sameCell = sheet.findCell(currentContent,
120                             uniqueCells[j][i].getColumn(),
121                             uniqueCells[j][i].getRow() + 1,
122                             uniqueCells[j][i].getColumn(),
123                             uniqueCells[j][realRows - 1].getRow(),
124                             true);
125                     if (sameCell != null) {
126                         nullCols++;
127                     }
128                 }
129
130                 if (nullCols == uniqueFields.length) {
131                     throw new ExcelException("Excel中有重复行,请检查");
132                 }
133             }
134
135             //将sheet转换为list
136             for (int i = 1; i < realRows; i++) {
137                 //新建要转换的对象
138                 T entity = entityClass.newInstance();
139
140                 //给对象中的字段赋值
141                 for (Map.Entry<String, String> entry : fieldMap.entrySet()) {
142                     //获取中文字段名
143                     String cnNormalName = entry.getKey();
144                     //获取英文字段名
145                     String enNormalName = entry.getValue();
146                     //根据中文字段名获取列号
147                     int col = colMap.get(cnNormalName);
148
149                     //获取当前单元格中的内容
150                     String content = sheet.getCell(col, i).getContents().toString().trim();
151
152                     //给对象赋值
153                     setFieldValueByName(enNormalName, content, entity);
154                 }
155
156                 resultList.add(entity);
157             }
158         } catch (Exception e) {
159             e.printStackTrace();
160             //如果是ExcelException,则直接抛出
161             if (e instanceof ExcelException) {
162                 throw (ExcelException) e;
163
164                 //否则将其它异常包装成ExcelException再抛出
165             } else {
166                 e.printStackTrace();
167                 throw new ExcelException("导入Excel失败");
168             }
169         }
170         return resultList;
171     }
172
173     /**
174      * 根据字段名给对象的字段赋值
175      *
176      * @param fieldName  字段名
177      * @param fieldValue 字段值
178      * @param o          对象
179      * @throws Exception 异常
180      */
181     public static void setFieldValueByName(String fieldName, Object fieldValue, Object o) throws Exception {
182
183         Field field = getFieldByName(fieldName, o.getClass());
184         if (field != null) {
185             field.setAccessible(true);
186             // 获取字段类型
187             Class<?> fieldType = field.getType();
188
189             // 根据字段类型给字段赋值
190             if (String.class == fieldType) {
191                 field.set(o, String.valueOf(fieldValue));
192             } else if ((Integer.TYPE == fieldType) || (Integer.class == fieldType)) {
193                 field.set(o, Integer.parseInt(fieldValue.toString()));
194             } else if ((Long.TYPE == fieldType) || (Long.class == fieldType)) {
195                 field.set(o, Long.valueOf(fieldValue.toString()));
196             } else if ((Float.TYPE == fieldType) || (Float.class == fieldType)) {
197                 field.set(o, Float.valueOf(fieldValue.toString()));
198             } else if ((Short.TYPE == fieldType) || (Short.class == fieldType)) {
199                 field.set(o, Short.valueOf(fieldValue.toString()));
200             } else if ((Double.TYPE == fieldType) || (Double.class == fieldType)) {
201                 field.set(o, Double.valueOf(fieldValue.toString()));
202             } else if (Character.TYPE == fieldType) {
203                 if ((fieldValue != null) && (fieldValue.toString().length() > 0)) {
204                     field.set(o, Character.valueOf(fieldValue.toString().charAt(0)));
205                 }
206             } else if (Date.class == fieldType) {
207                 if (!fieldValue.toString().isEmpty()) {
208                     if (fieldValue.toString().length() > 10) {
209
210                         field.set(o, new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(fieldValue.toString()));
211                     } else {
212                         field.set(o, new SimpleDateFormat("yyyy-MM-dd").parse(fieldValue.toString()));
213                     }
214                 }
215             } else {
216                 field.set(o, fieldValue);
217             }
218         } else {
219             throw new ExcelException(o.getClass().getSimpleName() + "类不存在字段名 " + fieldName);
220         }
221     }
222
223     /**
224      * @param sourceSheet
225      * @param eSheet      错误列表
226      * @param errorMap    错误原因
227      * @throws Exception
228      * @MethodName : addErrorRow
229      * @Description : 添加一行错误列表
230      */
231     private void addErrorRow(Sheet sourceSheet, WritableSheet eSheet, LinkedHashMap<Integer, String> errorMap) throws Exception {
232
233         // 复制错误的数据到错误列表
234         for (Map.Entry<Integer, String> entry : errorMap.entrySet()) {
235             int errorNo = entry.getKey();
236             String reason = entry.getValue();
237             int rows = eSheet.getRows();
238             for (int i = 0; i < sourceSheet.getColumns(); i++) {
239                 System.out.println("错误列表当前列号" + i);
240                 eSheet.addCell(new Label(i, rows, sourceSheet.getCell(i, errorNo).getContents()));
241             }
242
243             // 添加错误原因和所在行号
244             eSheet.addCell(new Label(sourceSheet.getColumns(), rows, reason));
245             eSheet.addCell(new Label(sourceSheet.getColumns() + 1, rows, String.valueOf(errorNo + 1)));
246
247         }
248
249     }
250
251     /**
252      * 设置工作表自动列宽和首行加粗
253      *
254      * @param ws        要设置格式的工作表
255      * @param extraWith 额外的宽度
256      */
257     public static void setColumnAutoSize(WritableSheet ws, int extraWith) {
258         // 获取本列的最宽单元格的宽度
259         for (int i = 0; i < ws.getColumns(); i++) {
260             int colWith = 0;
261             for (int j = 0; j < ws.getRows(); j++) {
262                 String content = ws.getCell(i, j).getContents().toString();
263                 int cellWith = content.length();
264                 if (colWith < cellWith) {
265                     colWith = cellWith;
266                 }
267             }
268             // 设置单元格的宽度为最宽宽度+额外宽度
269             ws.setColumnView(i, colWith + extraWith);
270         }
271
272     }
273
274     /**
275      * 根据字段名获取字段
276      *
277      * @param fieldName 字段名
278      * @param clazz     包含该字段的类
279      * @return 字段
280      */
281     public static Field getFieldByName(String fieldName, Class<?> clazz) {
282         // 拿到本类的所有字段
283         Field[] selfFields = clazz.getDeclaredFields();
284
285         // 如果本类中存在该字段,则返回
286         for (Field field : selfFields) {
287             if (field.getName().equals(fieldName)) {
288                 return field;
289             }
290         }
291
292         // 否则,查看父类中是否存在此字段,如果有则返回
293         Class<?> superClazz = clazz.getSuperclass();
294         if (superClazz != null && superClazz != Object.class) {
295             return getFieldByName(fieldName, superClazz);
296         }
297
298         // 如果本类和父类都没有,则返回空
299         return null;
300     }
301
302     /**
303      * 根据实体拿到该实体的所有属性
304      *
305      * @param clazz 实体
306      * @return 返回属性的list集合
307      */
308     public static List<String> getSuperClassFieldByClass(Class<?> clazz) {
309
310         List<String> list = new ArrayList<String>();
311
312         // 否则,查看父类中是否存在此字段,如果有则返回
313         Class<?> superClazz = clazz.getSuperclass();
314
315         Field[] superFields = superClazz.getDeclaredFields();
316         for (Field field : superFields) {
317             list.add(field.getName());
318         }
319
320         // 如果父类没有,则返回空
321         return list;
322     }
323
324
325     /**
326      * @param clazz       :对象对应的类
327      * @param equalFields :复合业务主键对应的map
328      * @return 查询到的对象
329      * @MethodName : getObjByFields
330      * @Description :根据复合业务主键查询对象
331      */
332     private <T> T getObjByFields(Class<T> clazz, LinkedHashMap<Object, Object> equalFields) {
333
334         List<T> list = null;
335         if (equalFields.size() != 0) {
336             // list=commonBean.findResultListByEqual(clazz, equalFields);
337         }
338
339         return list == null || list.size() == 0 ? null : list.get(0);
340     }
341
342     /**
343      * @param normalFieldMap 普通字段Map
344      * @param referFieldMap  引用字段Map
345      * @return 组合后的Map
346      * @MethodName : combineFields
347      * @Description : 组合普通和引用中英文字段Map
348      */
349     private LinkedHashMap<String, String> combineFields(LinkedHashMap<String, String> normalFieldMap, LinkedHashMap<LinkedHashMap<String, Class<?>>, LinkedHashMap<String, String>> referFieldMap) {
350
351         LinkedHashMap<String, String> combineMap = new LinkedHashMap<String, String>();
352
353         // 如果存在普通字段,则添加之
354         if (normalFieldMap != null && normalFieldMap.size() != 0) {
355             combineMap.putAll(normalFieldMap);
356         }
357
358         // 如果存在引用字段,则添加之
359         if (referFieldMap != null && referFieldMap.size() != 0) {
360
361             // 组建引用中英文字段Map
362             LinkedHashMap<String, String> simpleReferFieldMap = new LinkedHashMap<String, String>();
363             for (Map.Entry<LinkedHashMap<String, Class<?>>, LinkedHashMap<String, String>> entry : referFieldMap.entrySet()) {
364                 LinkedHashMap<String, Class<?>> keyMap = entry.getKey();
365                 LinkedHashMap<String, String> valueMap = entry.getValue();
366
367                 // 获取引用中文字段名
368                 String referField = "";
369                 for (Map.Entry<String, Class<?>> keyEntry : keyMap.entrySet()) {
370                     referField = keyEntry.getKey();
371                     break;
372                 }
373
374                 for (Map.Entry<String, String> valueEntry : valueMap.entrySet()) {
375                     String enField = valueEntry.getValue();
376                     String cnField = valueEntry.getKey();
377                     // 拼接英文引用字段
378                     String fullEnField = referField + "." + enField;
379
380                     // 放入simpleReferFieldMap
381                     simpleReferFieldMap.put(cnField, fullEnField);
382                 }
383
384             }
385
386             // 放入combineMap
387             combineMap.putAll(simpleReferFieldMap);
388         }
389
390         return combineMap;
391
392     }
393
394
395 }

2.导出工具

 1 package com.linrain.jcs.test;
 2
 3 import org.apache.commons.lang.StringUtils;
 4 import org.apache.poi.hssf.usermodel.HSSFCell;
 5 import org.apache.poi.hssf.usermodel.HSSFRow;
 6 import org.apache.poi.hssf.usermodel.HSSFSheet;
 7 import org.apache.poi.hssf.usermodel.HSSFWorkbook;
 8
 9 import javax.servlet.http.HttpServletResponse;
10 import java.io.*;
11 import java.util.List;
12 import java.util.Map;
13
14 /**
15  * @Description: 导出excel工具类
16  * @CreateDate: 2019/1/24/ 17:18$
17  * @Version: 1.0
18  */
19 public class ExportExcelUtil {
20     /**
21      * 常用普通文件下载
22      * @param response
23      * @param fileName
24      * @param sheetName
25      * @param data
26      */
27     public static void down(HttpServletResponse response, String fileName, String sheetName, List<Map<String, Object>> data) {
28         // 生成提示信息,
29         response.setContentType("application/vnd.ms-excel");
30         if (StringUtils.isBlank(fileName)) {
31             fileName = Long.toString(System.currentTimeMillis());
32         }
33         OutputStream fOut = null;
34         try {
35             // 进行转码,使其支持中文文件名
36             fOut = response.getOutputStream();
37             String codedFileName = new String(fileName.getBytes("gbk"), "iso-8859-1");
38             response.setHeader("content-disposition", "attachment;filename=" + codedFileName + ".xls");
39             HSSFWorkbook workbook = new HSSFWorkbook();
40             // 产生工作表对象
41             HSSFSheet sheet = workbook.createSheet(sheetName);
42
43             for (int i = 0; i < data.size(); i++) {
44                 HSSFRow row = sheet.createRow((int) i);
45                 Map<String, Object> map = data.get(i);
46
47                 //遍历map中的值
48                 int j = 0;
49                 for (Object value : map.values()) {
50                     HSSFCell cell = row.createCell((int) j);
51                     cell.setCellType(HSSFCell.CELL_TYPE_STRING);
52                     if (value == null) {
53                         value = "";
54                     }
55                     cell.setCellValue(value.toString());
56                     j++;
57                 }
58             }
59             workbook.write(fOut);
60         } catch (Exception e) {
61             e.printStackTrace();
62         } finally {
63             try {
64                 fOut.flush();
65                 fOut.close();
66             } catch (IOException e) {
67             }
68         }
69     }
70 }

原文地址:https://www.cnblogs.com/newAndHui/p/10319286.html

时间: 2024-10-26 14:26:04

java中excel导入\导出工具类的相关文章

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

前言: 最近PM来了一个需求,简单来说就是在录入数据时一条一条插入到系统显得非常麻烦,让我实现一个直接通过excel导入的方法一次性录入所有数据.网上关于excel导入导出的例子很多,但大多相互借鉴.经过思考,认为一百个客户在录入excel的时候,就会有一百个格式版本,所以在实现这个功能之前,所以要统一excel的格式.于是提供了一个通用excel模版的下载功能.当所有客户用模版录入好数据再上传到系统,后端对excel进行解析,然后再持久化到数据库. 概述: 此工具类的几大特点 1.基本导入导出

【原创】POI操作Excel导入导出工具类ExcelUtil

关于本类线程安全性的解释: 多数工具方法不涉及共享变量问题,至于添加合并单元格方法addMergeArea,使用ThreadLocal变量存储合并数据,ThreadLocal内部借用Thread.ThreadLocalMap以当前ThreadLocal为key进行存储,设置一次变量,则其他线程也会有上次数据的残留,因此在addMergeArea方法中进行清空的操作.为了保证原子性, 采用ReentrantLock确保一次只有一个线程可以进行添加合并数据的操作. 线程安全性从以上两个方面保证. 水

配置简单功能强大的excel工具类搞定excel导入导出工具类(一)

对于J2EE项目导入导出Excel是最普通和实用功能,本工具类使用步骤简单,功能强大,只需要对实体类进行简单的注解就能实现导入导出功能,导入导出操作的都是实体对象. 请看一下这个类都有哪些功能:????? 1.实体属性配置了注解就能导出到excel中,每个属性都对应一列.????? 2.列名称可以通过注解配置.????? 3.导出到哪一列可以通过注解配置.????? 4.鼠标移动到该列时提示信息可以通过注解配置.????? 5.用注解设置只能下拉选择不能随意填写功能.???? ? 6.用注解设置

java jxl excel 导入导出的 总结(建立超链接,以及目录sheet的索引)

最近项目要一个批量导出功能,而且要生成一个单独的sheet页,最后后面所有sheet的索引,并且可以点击进入连接.网上搜索了一下,找到一个方法,同时把相关的excel导入导出操作记录一下!以便以后使用! 简单先写一下目录的建立的主要代码,测试用的 List ls = new ArrayList();//报表名称列表  ls.add("BB_BB03");  ls.add("BB_BB05");  ls.add("BB_BB06"); try { 

Java中Excel导入功能实现、excel导入公共方法_POI -

这是一个思路希望能帮助到大家:如果大家有更好的解决方法希望分享出来 公司导入是这样做的 每个到导入的地方 @Override public List<DataImportMessage> materialDataImport2(byte[] fileBytes, String fileName) { //return DataImport(fileBytes, fileName, "inv_m"); File file = FileUtils.getFileFromByte

Excel导入导出帮助类

/// <summary>    /// Excel导入导出帮助类    /// 记得引入 NPOI    /// 下载地址   http://npoi.codeplex.com/releases/    /// </summary> public class ExcelHelper    {        #region 导出Excel /// <summary>        /// 导出Excel  注:model 字段必须加[DisplayName("

java中IO写文件工具类

下面是一些根据常用java类进行组装的对文件进行操作的类,平时,我更喜欢使用Jodd.io中提供的一些对文件的操作类,里面的方法写的简单易懂. 其中jodd中提供的JavaUtil类中提供的方法足够我们使用,里面的方法写的非常简练,例如append,read等方法,封装更好,更符合面向对象, 这里面我写的一些方法可多都是模仿jodd,从里面进行抽取出来的. /** * 获取路径文件夹下的所有文件 * @param path * @return */ public static File[] ge

java poi excel 导入导出数据

背景:1.pringmvc 框架下 的excel 导入导出   2.OI 操作office. 页面代码: <div class="modal fade bs-example-modal-lg" tabindex="-1" role="dialog" aria-labelledby="myLargeModalLabel" aria-hidden="true"> <div class=&quo

快捷方便的Excel导入导出工具 Easy-Xls 1.0 版本发布

EasyXls 使用EasyXls可以使你很方便的操作Excel.本项目目的是解决简单的(不带任何样式)xls文件的导入导出. 处理XML时由于使用了JAXB,所以需要使用jdk1.6u14以上版本.  JAXB处理中文xml时容易出现乱码,因此这里限制XML为GBK编码,在Windwos中的保存格式为ANSI即可. 项目地址:http://git.oschina.net/free/EasyXls EasyXls特点 支持xls转换为List<Pojo>对象 支持xls转换为List<M