- 浏览: 56928 次
- 性别:
- 来自: 上海
文章分类
最新评论
前言:
这里仅仅支持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 796一、JVM配置参数中文说明: 1、-Xmixed ... -
分布式服务框架之NIO(一)
2011-10-22 23:08 1301NIO在实现分布式服务框架中非阻塞高并发的服务器端功能 ... -
Spring声明线程池配置示例
2011-09-13 14:19 727<bean id="***Ta ... -
HTTPS下载的问题
2011-08-31 17:18 1726遇到一个很恶心的问题,开发以及测试环境是http协议,下 ... -
迷茫了
2011-08-08 23:09 735又迷茫了,感觉没事可做,什么都不想做 实际并不是没事可做,实 ... -
通用的excel报表生成工具类
2011-07-20 20:41 1108下面这个工具类是今天半天的劳动成果。 以后自己也可能用得到。 ... -
正则表达式元字符总结
2011-07-14 23:22 922正则表达式元字符总结如下: 点号(.):任何单字符的通 ... -
多并发情况下日志信息中如何区分不同线程(客户端)调用
2011-07-13 21:57 1365在企业开发中,常常会遇到这样的需求:通过一个唯一标 ... -
windows下perl开发环境搭建
2011-07-09 22:07 69001、下载并安装ActivePerl,貌似不需要额外的配置,一步 ... -
如何让右键菜单出现“命令行在这里”,即cmd here
2011-06-29 00:24 4707要在命令行下跳转到某个嵌套很深的目录下时,使用cd命令等比 ... -
使用JMock简介
2011-06-28 13:36 944一、常用关键字 one ... -
利用数据库锁实现简单的防并发编程
2011-06-22 23:27 1081大约有两类情况: 1、一个程序代码块同一时刻只允许一个 ... -
程序员如何减少BUG
2011-06-21 22:04 2510最近一个项目出了大量的BUG,很是惭愧,有没有可以尽量规避BU ... -
一些常用的正则表达式(项目中经常用到)
2011-06-15 17:11 8109最近做的一个内部系统项目,涉及大量的文本校验,里面用到了一些常 ... -
解析Excel文件转换科学计数法字符串为正常数字
2011-06-14 22:55 5647问题出现的情形是这样的: excel文件中某个字段,既 ... -
js正则表达式去除表单提交字符串前后的空格
2011-06-13 19:31 1440str为表单提交数据。 str=str.replace ... -
debug容器启动类报MMO异常解决办法
2011-06-10 19:58 708类似的,在eclipse的VM arguments中设置参数: ... -
理想的设计特征
2011-06-09 00:57 696其实下面这些是来自于代码大全,觉得讲得实在是精辟无比,想摘抄下 ... -
最近的几点关于编码的心得
2011-05-25 00:35 6521、编写一个类或者新建一个变量的时候,名字问题需要仔细的斟酌斟 ... -
JMS实现简单的聊天程序
2011-05-15 19:30 6017实现这个简单的聊天 ...
相关推荐
用于在C#.NET Core中对CSV文件执行完全外部联接的命令行工具: CsvJoin.exe Data sales.csv new_sales.csv > joined_sales.csv 特征: 针对CSV文件执行SQL 将结果保存到CSV 保存自动生成SQL 先决条件: ...
Milieu意见提取引擎 版权 特此免费授予获得此软件和相关文档文件(以下简称... 对于任何新客户,我们只需将其.csv文件插入Watson watson-parser可以提出任何问题(列)并检索关键字 将数据放回.csv文件 安装 $ mk
WtCtaOptimizer CTA优化器,主要是利用multiprocessing并行回测,并统计各项交易指标,最后将统计结果汇总输出到csv文件 WtHotPicker 国内期货换月规则辅助模块,支持从交易所网站页面爬取数据确定换月规则,也支持...
爬虫通常由搜索引擎、数据挖掘工具、监测系统等应用于网络数据抓取的场景。 爬虫的工作流程包括以下几个关键步骤: URL收集: 爬虫从一个或多个初始URL开始,递归或迭代地发现新的URL,构建一个URL队列。这些URL...
使用elasticsearch的csv-movie(每一行都是带有很多细节的电影)的简单python搜索引擎 数据下载: : 。 工具/软件包:Elasticsearch-ES,用于可视化的Kibana。 语言:python也使用:pandas,numpy等。 使用ES索引...
它利用模板提供程序、转换器、占位符集合和解析器/生成器引擎。要求仅支持 PHP 5.4 及以上版本。安装推荐的安装方法是通过 ,一个 PHP 的依赖管理库。作曲家如果您安装了和 ,那么获取 Composer 就像: curl -s ...
数据集生成为始终更新的JSON文件以及具有以下设置的CSV文件ID 提供者标题开始日期结束日期开学年年终类型标签asset_url thumbnail_url AAFC / ACI 加拿大农业和农业食品加拿大AAFC年度作物清单2009-01-01 2021-03-...
在Java中使用Camel框架交易引擎 (要查看源代码,请进入“交易引擎”或“消费者或生产者”,然后进入... 在这些渠道的每一个中,将解析csv文件内容的所有价格和金额,并将其存储在StockStatData中。 然后,它将使用Stat
Toxy解析器的抽取参数Toxy的解析器不仅提供基本的抽取功能,同时也支持对抽取内容进行选择,这是通过ParserContext的Properties实现的。下面举一个Excel的抽取参数的例子:12345678ParserContext context = new ...
通过运行 python 脚本 parse.py (TXT -> CSV) 将文本文件中的数字提取到 CSV 文件中 将 CSV 文件上传到 Google 电子表格并清理数据 通过 Google Spreadsheet JSON API 将数据导出为 JSON 将 JSON 数据导入弹性搜索...
支持csv存储,注释丰富。 爬虫(Web Crawler)是一种自动化程序,用于从互联网上收集信息。其主要功能是访问网页、提取数据并存储,以便后续分析或展示。爬虫通常由搜索引擎、数据挖掘工具、监测系统等应用于网络...
从CSV文件开始解析产品。 模块化结构,网站解析器( MyEcommerce延伸SiteParser )。 将每个URL绑定到解析器的实例。 (解析器可以处理多个URL)。 检查网址是否得到了解析器。安装$ npm install --save price-...
支持csv,MySQL, MongoDB,Excel, json存储,支持Python2和3,图表展示数据,注释丰富。 爬虫(Web Crawler)是一种自动化程序,用于从互联网上收集信息。其主要功能是访问网页、提取数据并存储,以便后续分析或展示。...
java实现源码转补码很棒的 LINQ 介绍 精选的精选 LINQ 库、工具等。 目标是建立一个由社区驱动的非常知名资源的分类集合。 灵感来自 GitHub 上的整个awesome-*趋势。 随时欢迎分享、建议和贡献! 请先看一看。 感谢...
该程序通过 Tesseract OCR 引擎处理所有图像文件,并在 NLTK DATA 文件夹中输出 TXT 文件 Nltktest2 正在开发中,可以生成硬编码 TXT 文件的基本统计信息。 它将被扩展以生成额外的统计数据并循环遍历包含 ...
> - WtHotPicker 国内期货换月规则辅助模块,支持从交易所网站页面爬取数据确定换月规则,也支持解析`datakit`每日收盘生成的snapshot.csv来确定换月规则 + wrapper子模块 > 该模块主要包含了所有和`C++`底层对接...
解析器(抓取器)的工作类似于搜索引擎的工作。 搜索引擎可应要求分析网站内容并在浏览器中显示结果。 使用刮板解析器,您可以在站点页面上选择必要的元素,然后借助xpath,扩展名将所需值的地址传递给服务器。 接...
指定映射关系(定义目标域和Paradox文件解析域之间的对应关系); 按照Paradox的结构在MS Jet/ADO数据源里创建一个新的平台; 下载数据到目标平台或可编辑查询请求; 把Paradox/dBase记录转换为CSV-file或SQL-...
47:PHP输出CSV和EXCEL两种简单的方法 48:Ajax+PHP快速上手及应用 49: Ajax+PHP打造等待进度条效果(二) 50: Ajax+PHP检查用户名或邮件(三) 51:PHP+MYSQL会员系统的开发(上) P100视频教程52:PHP+MYSQL会员...
Shlink进口商收集工具以从不同来源导入链接并将它们映射为兼容shlink的格式。安装可以使用composer安装此模块: composer require ...标准CSV 它使用Long URL和Short code列解析CSV文件。 它可以可选地包含Domain ,