通用的POI导入Excel解决方案
引言:在项目中,经常免不了要导入、导出Excel,导出Excel稍微简单点,制作一张模板,然后将查询之后的数据写入到模板中即可,导出程序可以做到一次写好,基本上就可以通用。
但导入Excel相对麻烦点,一般情况下,导入的程序无法通用的主要原因是:对于不同的导入模板,字段field与单元格cellRef的映射关系是不相同的,这就导致对每一个导入模板都要去写一套相似的代码;我们应该想办法解决这个问题,减少每次导入Excel时都去拷贝粘贴相同的代码。
问题的关键是解决:字段field与单元格cellRef的映射关系;
如何解决呢?将这个映射关系从程序中抽取出来。
如何抽取呢?曾经跟一些同事、朋友聊天时谈到这个话题,
有的建议将这个映射关系写在Excel单元格里面,并且设置将单元格隐藏;
有的建议用2个相似的excel模板文件,将映射关系放在A模板文件中,B模板文件提供给用户导入数据;
有的建议将映射关系单独写在xml文件中;。。。。
经过再三权衡,最终我选择使用方法3,即将映射关系写在XML配置文件中。
通常情况下,我们的导入模板是大致为这样的:
(1) 有颜色的单元格是需要被导入到后台的有用信息,且单元格中的单词即为field信息
(2) 橙色单元格为只填写/读取一次的数据。
(3) 蓝色单元格为循环填写/读取的数据,A10单元格中,End表示读取到这里时,循环结束。
所以我们字段field与单元格cellRef映射信息可以是这样子的:
<?xml version="1.0" encoding="UTF-8"?>
<excelImport>
<onceImport>
<![CDATA[
C3 = ORDER_NBR, H3 = CUST_NAME,
N3 = CUST_LINK_INFO, C4 = CUST_ID,
H4 = CUST_ADDR, N4 = ONCE_TYPE,
C5 = CONTACT_ID, H5 = CUST_FILE,
N5 = LOOP_TYPE, C6 = PRO_NAME,
H6 = OPPO_ORDER_NBR, N6 = COOPERATE_MODE,
C11 = AUD_MANGER, N11 = BM,
C12 = ORDER_COMMENT
]]>
</onceImport>
<repeatImport>
<![CDATA[
A9 = STRNUM, B9 = FRI_AREA,
C9 = OPP_A, D9 = SEC_AREA,
E9 = OPP_B, F9 = NUM,
G9 = SERV_NBR, H9 = SPEED,
I9 = FRI_ADDR, J9 = PORT_TYPE_A,
K9 = FRI_LINK_A, L9 = SEC_ADDR,
M9 = PORT_TYPE_B, N9 = FRI_LINK_B,
O9 = APPLY_INFO, P9 = ORDER_DATE,
Q9 = HIRE_TIME, R9 = DISCOUNT_MID,
S9 = BILL_DATE, T9 = OLD_BILL_DATE,
U9 = LINE_COMMENT
]]>
<endCode>End</endCode>
</repeatImport>
</excelImport>
(1) <onceImport/> 表示只需要一次导入的数据,字段field与单元格cellRef的映射关系写在CDATA区中。
(2) <repeatImport/>表示需要循环导入的数据,字段field与单元格cellRef的映射关系写在CDATA区中。<endCode/>表示循环终止的字符。
下面说一下,根据这个XML描述文件,我们需要从Excel中解析出什么样的数据格式来:
/**
* 读取导入的Excel的内容
* 模板要求:
* (1)开始重复行与End行 有且只能有 一空行
*/
public class ExcelImportUtil
{
/**
* 读取导入的Excel的文件内容
* @param xmlFile 描述被导入的Excel的格式的XML文件
* @param importExcelStream 被导入的XML文件
* @return Excel中需要导入的数据
*/
public static ExcelData readExcel(String xmlFile, InputStream importExcelStream) throws ExcelImportException
{}
}
/**
* Excel导入的信息
*/
import java.util.List;
import java.util.Map;
public class ExcelData
{
// 一次导入的数据,key就是field,一个ImportCellDesc描述了一个单元格(field,value,单元格名称)
private Map<String, ImportCellDesc> onceData;
// 重复导入的数据
private List<Map<String, ImportCellDesc>> repeatData;
// setter/getter
}
/**
* 单元格的描述信息
* (1)数据格式校验时,可以精确定位到某个单元格。
*/
public class ImportCellDesc
{
/**
* 引用的单元格;如:A3
*/
private String cellRef;
/**
* 单元格的对应数据库的字段名称;
* 如:fieldName = "username"
*/
private String fieldName;
/**
* 字段值,如:张三
*/
private String fieldValue;
// setter/getter
}
调用代码:
ExcelData excelData = ExcelImportUtil.readExcel(xmlFile, importExcelStream);
然后在这个基础上,我们可以对数据进行一些操作,如:数据校验,插入数据。。。
其中数据校验时,如果数据不合法,给用户的提示信息可以精确指定某个单元格的数据不合法。(如:提示信息为:A3单元格数据不合法!)
注:使用了如下第三方JAR包:
Jdom :解析XML描述文件
POI3.0 : 读取Excel文件
Xml描述文件,必须放在cn.zhaoql.excelimport.xml这个包里面。
分享到:
相关推荐
兼容excel各种版本,灵活控制导入列,导入行,多sheet导入。。。
Java中excel导入导出的通用方法。
支持通用Excel/WPS的版本快速导入,Office支持Excel97,Excel2003,Excel2010等多个版本,WPS的版本支持不限制,能自动识别导入excel的页签,根据所选页签导入后自动返回当前表格包含的列标题信息和含数据信息,这些...
Excel导入工具,根据自己设定的数据字段名称对应关系,根据提供的路径进行通用导入!但是一次只能导入一张表!
通用Excel数据导入模块
。net通用导入导出 excel 类,返回datatable
这是一个利用poi封装的excel导入导出通用组件,详细用法请访问:http://fuyangrong.top/2018/01/29/excel导入导出通用组件/
java注解实现通用Excel中文表格转实体对象列表,支持中文表头,在Excel数据导入使用的通用工具类,代码简洁优雅 。基于注解实现的支持中文表头的读取Excel数据并转换为实体对象列表的工具类,使用该工具类可将Excel...
能实现一对多关联的通用EXCEL导入功能 具体访问我的BLOG http://blog.csdn.net/dreamdiary
通用的Excel导入到数据库程序,通过配置xml文件就可以进行导入。
ZCL_EXCEL 操作EXCEL通用类
asp通用的excel 导入Access数据库程序 含源文件下载 源文件,测试ok 分享
闲下来的时候心血来潮,花了1个小时的时间写出来的excel通用导入模板示例,写法比较简陋,但是excelUtil这个类却是写的比较全,下载后可以根据自己的不同需求进行修改,做过测试修改了日期和数值的bug,如果在使用中...
一个通用从数据库导出excel、excel导入数据库组件的Java项目程序所用到的jar包。
我朋友写出来的excel通用导入模板示例,写法比较简洁,excelUtil这个类却是写的比较全,下载后可以根据自己的不同需求进行修改,做过测试修改了日期和数值的bug,比较有用,希望对大家有用。有什么好的建议或者看法...
考虑到Excel导入在项目中应用较多,随后其他项目中都会用到,为了减少重复工作,不必因为excel的样式、数据等变化而重新编码,重复劳动,因此必须抽取通用的东西出来,封装共同点,暴露个性点,使用时只需要关注相关...
导入Excel到MySQL通用工具(Java)源码,可将任意符合数据库格式的Excel文件导入MySQL数据库,只支持xls格式.
简单通用的Excel导入导出,导入生成对应的DataTable,导出给出路径,直接生成文件。
你还在为手工录入凭证烦恼吗,通用excel凭证导入工具(T3).zip能够实现快速导入凭证,接触手工录入凭证的烦恼,降低手工录入过程中出现的差错,提供会计工作的准确性和效率。