- 浏览: 58049 次
- 性别:
- 来自: 上海
文章分类
最新评论
前言:
这里仅仅支持Excel文件导出的CSV文件,解析的核心是一个正则表达式,这个正则表达式取自<精通正则表达式>一书中,感谢作者。
1、解析引擎结构图
2、很懒很懒,直接上代码了
/** * CSV 文件解析 * * @param <T> * @param xmlInputStream * @param clazz * @param file * @return */ protected <T> List<T> parse(InputStream xmlInputStream, Class<T> clazz, InputStream file) { //xml解析 Map<String, String> metaDataMap = parseXmlConfig(xmlInputStream); //获取对象实例 T obj = getInstance(clazz); //校验Map中的metaData信息与clazz中的属性是否完全匹配 checkProperty(metaDataMap, obj); //读取csv文件,返回解析结果 List<T> datas = parseCsvFile(file, clazz, metaDataMap); return datas; } /** * 获取对象属性与csv头部文件的映射Map * key:csv文件头部中文 * value:映射类的属性 * * @param xmlPath * @return */ @SuppressWarnings("unchecked") protected Map<String, String> parseXmlConfig(InputStream in) { Map<String, String> metaDataMap = new HashMap<String, String>(); SAXReader saxReader = new SAXReader(); try { Document document = saxReader.read(in); Element root = document.getRootElement(); //循环模板(*-*!!) for (Iterator iter = root.elementIterator(); iter.hasNext();) { Element element = (Element) iter.next(); getPropertyValue(element, "name", metaDataMap); } } catch (Throwable e) { throw new RuntimeException(e); } return metaDataMap; } /** * 获取映射对象的运行实例 * * @param <T> * @param clazz * @return */ private <T> T getInstance(Class<T> clazz) { T obj = null; try { obj = clazz.newInstance(); } catch (Throwable e) { throw new RuntimeException(e); } return obj; } /** * 校验Map中的metaData信息与clazz中的属性是否完全匹配 * * @param <T> * @param metaDataMap key:中文描述 value:类属性 * @param obj */ private <T> void checkProperty(Map<String, String> metaDataMap, T obj) { List<String> fieldList = new ArrayList<String>(); //获取obj属性名称列表 Field[] fields = obj.getClass().getDeclaredFields(); for (Field f : fields) { f.setAccessible(true); String name = f.getName(); if (!StringUtil.equals(name, ConstantEnum.REFLECT_FIELD_GARGABE_ONE.getCode()) && !StringUtil.equals(name, ConstantEnum.REFLECT_FIELD_GARGABE_TWO.getCode())) { fieldList.add(f.getName()); } } for (String fieldName : fieldList) { if (!metaDataMap.containsValue(fieldName)) { throw new RevmngException(RevmngResultCode.HEAD_INFO_NOT_SAME_OBJ); } } if (metaDataMap.size() != fieldList.size()) { throw new RevmngException(RevmngResultCode.HEAD_INFO_NOT_SAME_OBJ); } } /** * 解析csv文件 * * @param <T> * @param file * @param obj * @param metaDataMap key:中文 value:字段属性 * * @return */ private <T> List<T> parseCsvFile(InputStream file, Class<T> clazz, Map<String, String> metaDataMap) { List<T> datas = new ArrayList<T>(); InputStreamReader fr = new InputStreamReader(file); BufferedReader br = new BufferedReader(fr); List<String> headInfo = new ArrayList<String>(); try { String line = ""; int lineSeq = 0; while ((line = br.readLine()) != null) { T tempObj = getInstance(clazz); int cellSeq = -1; Map<String, String> mapLine = new HashMap<String, String>(); lineSeq++; Matcher matcher = getMatcher(line); Matcher mQuote = Pattern.compile("\"\"").matcher(""); while (matcher.find()) { cellSeq++; String field = getField(matcher, mQuote); if (lineSeq == 1) { //头部信息 if (StringUtil.isNotBlank(field)) { headInfo.add(field); } continue; } //映射类的属性名称 if (cellSeq >= headInfo.size()) { continue; } String propertyName = metaDataMap.get(headInfo.get(cellSeq)); if (StringUtil.isBlank(propertyName)) { logger.warn("未取到导入文件头部的文字信息属性!"); throw new RevmngException(RevmngResultCode.CSV_HEAD_INFO_ERROR); } mapLine.put(propertyName, field); } //解决这个正则的一个缺陷,类似这样的csv格式解析有误",a,bab,a,c,c"(第一个单元格数据为空),现在会直接跳过 firstCellIsNotNull(cellSeq, line, headInfo); //填充映射对象的属性值 if (lineSeq > 1) { if (headInfo.size() != metaDataMap.size()) { logger.warn("上传文件的模板不正确,请下载正确的模板!"); throw new RevmngException(RevmngResultCode.CSV_TEMPLATE_FILE_ERROR); } setObjectValue(tempObj, mapLine); datas.add(tempObj); } } } catch (RevmngException re) { throw re; } catch (Throwable e) { throw new RuntimeException(e); } return datas; } /** * 解决这个正则的一个缺陷,类似这样的csv格式解析有误",a,bab,a,c,c"(第一个单元格数据为空),现在会直接跳过 * * @param cellSeq * @param line */ @SuppressWarnings("unchecked") private void firstCellIsNotNull(int cellSeq, String line, List<String> headInfo) { if (StringUtil.isBlank(line)) { return; } String[] contens = line.split("[,]"); List<String> lists = Arrays.asList(contens); StringBuffer lineBuffer = new StringBuffer(); for (int i = 0; i < headInfo.size(); i++) { lineBuffer.append(headInfo.get(i)).append(" : "); if (i < lists.size()) { lineBuffer.append(lists.get(i)); } } if (!CollectionUtils.isEmpty(lists) && cellSeq == 0) { logger.warn("存在第一个单元格数据为空的文本行!line:" + line); throw new RevmngException(RevmngResultCode.CSV_FIRST_CELL_NOT_NULL.getCode(), "数据行: " + lineBuffer.toString() + " 的 " + lists.get(0) + "不允许为空!"); } } /** * 获取Matcher * @param line * @return */ private Matcher getMatcher(String line) { Matcher matcher = Pattern.compile(RegularExpressionEnum.REGEX_CSV_FOMAT.getCode(), Pattern.COMMENTS).matcher(""); matcher.reset(line); return matcher; } /** * 获取解析的一个单元值 * @param matcher * @param mQuote * @return */ private String getField(Matcher matcher, Matcher mQuote) { String field = ""; if (matcher.start(2) >= 0) field = matcher.group(2); else field = mQuote.reset(matcher.group(1)).replaceAll("\""); return field; } /** * 设置一行映射对象的属性值 * * @param <T> * @param object * @param mapLine key :属性名称 value:属性值 * @throws IllegalAccessException * @throws IllegalArgumentException */ private <T> void setObjectValue(T object, Map<String, String> mapLine) throws IllegalArgumentException, IllegalAccessException { Field[] fields = object.getClass().getDeclaredFields(); for (Field f : fields) { f.setAccessible(true); String name = f.getName(); //去除垃圾属性的影响 if (StringUtil.equals(name, ConstantEnum.REFLECT_FIELD_GARGABE_ONE.getCode()) || StringUtil.equals(name, ConstantEnum.REFLECT_FIELD_GARGABE_TWO.getCode())) { continue; } if (mapLine.containsKey(f.getName())) { //去空格 String value = StringUtil.trim(mapLine.get(f.getName())); f.set(object, value); } } }
只是一些关键代码而已,别人不一定看得明白,自己mark一下。。哇哈哈哈。。。
发表评论
-
JVM参数以及调优
2011-10-24 23:39 837一、JVM配置参数中文说明: 1、-Xmixed ... -
分布式服务框架之NIO(一)
2011-10-22 23:08 1346NIO在实现分布式服务框架中非阻塞高并发的服务器端功能 ... -
Spring声明线程池配置示例
2011-09-13 14:19 770<bean id="***Ta ... -
HTTPS下载的问题
2011-08-31 17:18 1766遇到一个很恶心的问题,开发以及测试环境是http协议,下 ... -
迷茫了
2011-08-08 23:09 769又迷茫了,感觉没事可做,什么都不想做 实际并不是没事可做,实 ... -
通用的excel报表生成工具类
2011-07-20 20:41 1155下面这个工具类是今天半天的劳动成果。 以后自己也可能用得到。 ... -
正则表达式元字符总结
2011-07-14 23:22 955正则表达式元字符总结如下: 点号(.):任何单字符的通 ... -
多并发情况下日志信息中如何区分不同线程(客户端)调用
2011-07-13 21:57 1433在企业开发中,常常会遇到这样的需求:通过一个唯一标 ... -
windows下perl开发环境搭建
2011-07-09 22:07 69351、下载并安装ActivePerl,貌似不需要额外的配置,一步 ... -
如何让右键菜单出现“命令行在这里”,即cmd here
2011-06-29 00:24 4748要在命令行下跳转到某个嵌套很深的目录下时,使用cd命令等比 ... -
使用JMock简介
2011-06-28 13:36 986一、常用关键字 one ... -
利用数据库锁实现简单的防并发编程
2011-06-22 23:27 1131大约有两类情况: 1、一个程序代码块同一时刻只允许一个 ... -
程序员如何减少BUG
2011-06-21 22:04 2540最近一个项目出了大量的BUG,很是惭愧,有没有可以尽量规避BU ... -
一些常用的正则表达式(项目中经常用到)
2011-06-15 17:11 8148最近做的一个内部系统项目,涉及大量的文本校验,里面用到了一些常 ... -
解析Excel文件转换科学计数法字符串为正常数字
2011-06-14 22:55 5685问题出现的情形是这样的: excel文件中某个字段,既 ... -
js正则表达式去除表单提交字符串前后的空格
2011-06-13 19:31 1474str为表单提交数据。 str=str.replace ... -
debug容器启动类报MMO异常解决办法
2011-06-10 19:58 746类似的,在eclipse的VM arguments中设置参数: ... -
理想的设计特征
2011-06-09 00:57 736其实下面这些是来自于代码大全,觉得讲得实在是精辟无比,想摘抄下 ... -
最近的几点关于编码的心得
2011-05-25 00:35 6831、编写一个类或者新建一个变量的时候,名字问题需要仔细的斟酌斟 ... -
JMS实现简单的聊天程序
2011-05-15 19:30 6059实现这个简单的聊天 ...
相关推荐
本篇文章将详细介绍如何使用ADO(ActiveX Data Objects)技术来实现多个CSV文件的合并。 #### 二、ADO简介 ADO是一种用于访问数据的技术,它提供了简单且一致的方式与不同类型的数据库进行交互。ADO通过OLE DB提供...
`neat-csv` 的设计目标是提供高效且易于使用的 CSV 解析功能,它能够处理大量数据,并且支持通过回调接口进行异步操作,这对于处理大文件或者实时流数据非常有用。 以下是一些关于 `neat-csv` 的关键知识点: 1. *...
"libcsv-" 是一个C++编写的CSV(逗号分隔值)库,它提供了处理CSV文件的全面功能,包括解析、编辑和写入操作。这个库对于那些需要在C++项目中与CSV数据打交道的开发者来说非常有用。 **描述详解:** libcsv++是一...
在实际应用中,文本文件解析对象会涉及文件读取(如使用fopen、readline等函数)、字符串处理(如split、join、replace等操作)、数据格式转换(如CSV转JSON、XML等)以及可能的数据验证和清洗步骤。理解并有效地...
CSV文件是一种广泛使用的数据格式,它以纯文本形式存储表格数据,便于在不同程序之间交换数据。Tad提供了一个直观的用户界面,让用户能够高效地浏览、操作和理解这些数据。 描述中的信息进一步强调了Tad的核心功能...
1. CSV文件解析基础: CSV文件由行和列组成,每行数据之间用换行符分隔,列数据之间用逗号分隔。例如: ``` Name,Age,Job John,30,Engineer Jane,25,Doctor ``` 这种格式使得CSV文件易于阅读和处理,可以用...
标题 "csv2es:将 csv 文件流导入 ES" 指的是一个用于将逗号分隔值(CSV)文件的数据导入到 Elasticsearch (ES) 的工具或库。这个工具主要适用于那些需要快速、批量地将结构化数据从 CSV 文件导入到 ES 数据存储中的...
总结来说,Cocos2d-x项目中读取CSV文件的关键在于利用C++标准库的功能,通过`fstream`打开文件,然后使用`istringstream`和分隔符来解析每一行的内容。这个过程可以灵活地适应各种数据结构,使得CSV文件成为一个有效...
- 打开CSV文件:使用合适的文本编辑器或工具确认CSV文件为UTF-8编码,避免乱码问题。 - 导入数据: - 直接SQL命令:使用`LOAD DATA INFILE`语句,但SQLite原生不支持此命令,需要借助第三方工具或编程实现。 - ...
通过这个简单的修改,Pandas应该能够成功读取并解析含有中文标题的CSV文件。不过,这也提醒我们,对于特定的编程任务,性能和功能之间可能存在权衡。在追求效率的同时,我们也需要确保我们的代码能够处理各种边缘...
这就引出了转换为CSV格式的需求,因为CSV文件仅包含基本的表格数据,没有Excel的样式、公式或图表等复杂元素,这使得它们能被大多数编程语言和数据库管理系统轻松解析。 CSV文件的结构简单,由逗号分隔的数据项组成...
4. JavaScript:作为项目的主要编程语言,JavaScript负责读取CSV文件,调用Google Cloud Translation API,处理翻译结果,并将数据写回到新的CSV文件中。JavaScript的Node.js环境使得可以在服务器端执行这些任务。 ...
通过将CSV文件转换为C#类,开发者可以更方便地在Unity项目中读取和操作这些数据,而无需编写大量的解析代码。 Unity引擎广泛应用于游戏开发,它支持C#编程语言,因此将CSV数据转换为C#类有助于提高开发效率和代码可...
用于在C#.NET Core中对CSV文件执行完全外部联接的命令行工具: CsvJoin.exe Data sales.csv new_sales.csv > joined_sales.csv 特征: 针对CSV文件执行SQL 将结果保存到CSV 保存自动生成SQL 先决条件: ...
在C++中,没有内置的库直接支持Excel文件,但我们可以通过第三方库,如`libcsv`、`pugixml`或`Boost.IOStreams`等,实现读写CSV文件的功能。 1. **读取CSV文件** - 使用标准库:你可以使用`fstream`类读取文件,...
转换后的CSV文件可以直接在Unity中导入,然后通过C#脚本来读取和解析数据。 `xls2lua`工具则更进一步,它不仅转换数据格式,还可能包含了一些针对Lua的特定优化,比如生成可以直接在Lua环境中运行的代码结构。Lua...
要将VCF文件转换为CSV格式,我们需要一个能够解析VCF文件并将其内容写入CSV文件的工具。在这个场景中,"vcf-to-csv-converter.exe" 是一个专门为此目的设计的程序。然而,使用这个工具之前,需要确保您的计算机上...
它提供了一种快速、便捷的方法,将Excel文件转换成JSON、CSV、XML以及Lua这四种常见的数据格式,使得Unity项目能够轻松地加载和解析这些数据。 JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,...
2. **内容解析**:读取的TXT文件内容可能包含结构化的数据,如CSV格式(逗号分隔值)或其他自定义格式。解析过程通常涉及分割文本,识别字段,以及处理可能的嵌套结构。例如,CSV数据可以通过Python的`csv`库解析;...
CSV文件因其简单性而被广泛使用,是存储和交换数据的一个非常方便的格式。MySQL数据库管理系统提供了一种高效的导入CSV数据的方式,即通过MySQL的CSV存储引擎。 MySQL的CSV存储引擎允许用户直接将CSV格式的文件导入...