Java处理CSV文件的读取与写入
目的:重复性代码尽量少写或者不写,复制粘贴即可
CSV文件读取代码
/** * 读取csv文件数据到对象集合中 * @param inputStream 文件输入流 * @param charset 文件字符集 * @param fields 对象的字段 * @param startRow 从第几行开始读 * @param clazz 对象类 * @param <T> * @return */ public static <T> List<T> readCsv(InputStream inputStream, String charset, String[] fields, int startRow, Class<T> clazz){ List<T> list = new ArrayList<>(); InputStreamReader inputStreamReader = null; BufferedReader bufferedReader = null; try { if(StringUtils.isEmpty(charset)){ charset = SettingConstant.CHAR_SET_GBK; } inputStreamReader = new InputStreamReader(inputStream, charset); bufferedReader = new BufferedReader(inputStreamReader); String rowStr; int row = 0; while((rowStr=bufferedReader.readLine())!=null){ row++; if(row < startRow){ continue; } if (rowStr.contains(",")) { T obj = clazz.newInstance(); String[] datas = rowStr.split(","); Field rowNumField = clazz.getDeclaredField(ROW_NUM_FIELD); rowNumField.setAccessible(true); rowNumField.set(obj, row); // 循环次数:如果对象字段个数与csv的字段个数比较,取较小的数值 int cycleCount = fields.length > datas.length ? datas.length : fields.length; for (int i = 0; i < cycleCount; i++) { Field declaredField = clazz.getDeclaredField(fields[i]); declaredField.setAccessible(true); declaredField.set(obj, datas[i]); } list.add(obj); } else { log.error("第{}行的数据格式错误", row); } } } catch (IOException e) { log.error("文件读写异常!",e); throw new BusinessException("文件读写异常"); } catch (IllegalAccessException e) { log.error("对象属性访问异常!",e); throw new BusinessException("对象属性访问异常"); } catch (InstantiationException e) { log.error("对象实例化异常!",e); throw new BusinessException("对象实例化异常"); } catch (NoSuchFieldException e) { log.error("字段不存在!",e); throw new BusinessException("字段不存在"); } finally { try { if(inputStreamReader != null){ inputStreamReader.close(); } if(bufferedReader != null){ bufferedReader.close(); } } catch (IOException e) { log.error("文件流关闭异常!",e); throw new BusinessException("文件流关闭异常"); } } return list; }
CSV文件生成
/** * 根据传入的字段顺序生成csv文件 * @param fileName 文件名 * @param dataList 数据集合 * @param tableHeads csv表头 * @param fieldNames 指定的字段名集合 * @return csv文件 */ public static File exportCsv(String fileName, List<?> dataList, String[] tableHeads, String[] fieldNames) { if (CollectionUtils.isEmpty(dataList) && Objects.isNull(tableHeads)) { log.info("数据集和表头不能同时为空"); throw new RuntimeException("数据集和表头不能同时为空"); } File file = new File(fileName); try (OutputStreamWriter streamWriter = new OutputStreamWriter(new FileOutputStream(file),"GBK"); BufferedWriter bufferedWriter = new BufferedWriter(streamWriter)) { // CSV表头处理 if (tableHeads != null && tableHeads.length > 0) { StringBuffer headerBuffer = new StringBuffer(); for (int i = 0; i < tableHeads.length; i++) { // 拼接表头字段 headerBuffer.append(doCsvCell(tableHeads[i])); } // 截掉最后一个逗号,并写入文件流中 if (headerBuffer.length() > 1) { headerBuffer.substring(0, headerBuffer.length() - 1); } bufferedWriter.write(headerBuffer.toString()); bufferedWriter.newLine(); } // CSV数据处理 if (!CollectionUtils.isEmpty(dataList)) { for (int i = 0; i < dataList.size(); i++) { StringBuffer rowDataBuffer = new StringBuffer(); // 获取list中的数据对象,根据传如的字段顺序进行写入到CSV中 Object dataObj = dataList.get(i); for (int j = 0; j < fieldNames.length; j++) { // 获取对象对应的字段值 Field field = dataObj.getClass().getDeclaredField(fieldNames[j]); field.setAccessible(true); Object fieldValue = field.get(dataObj); rowDataBuffer.append(doCsvCell(fieldValue)); } // 截取掉最后一个逗号,并写入文件流中 if (rowDataBuffer.length() > 1) { rowDataBuffer.substring(0, rowDataBuffer.length() - 1); } bufferedWriter.write(rowDataBuffer.toString()); bufferedWriter.newLine(); } } bufferedWriter.flush(); } catch (IOException e) { log.error("文件操作异常",e); throw new RuntimeException("文件操作异常",e); } catch (IllegalAccessException e) { log.error("属性无法访问",e); throw new RuntimeException("属性无法访问",e); } catch (NoSuchFieldException e) { log.error("字段不存在",e); throw new RuntimeException("字段不存在",e); } return file; }
探索不以困难而止,学习不以艰苦而终