java中excel导入导出工具类
Posted newandhui
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 }
以上是关于java中excel导入导出工具类的主要内容,如果未能解决你的问题,请参考以下文章