https://github.com/deadzq/cp-utils-excelreader  <(感谢知名网友的帮助)

https://sargeraswang.com/blog/2018/11/27/excelutil-1-dot-2-1-doc/

https://github.com/SargerasWang/ExcelUtil

轮子好,但是永远比不上自己写,但是项目节奏紧张,只能先用别人写好的轮子.

这个问题主要发生在后台easyui界面的导入导出excel数据.

导出我没有使用大多数博客推荐的poi,而是使用了两个js插件,感觉这样还是比较方便的.(分页上的也同时能导出) ? <还得测试下

导入必须走数据库,也就是说需要将excel中的数据转为List<数据对象bean> 再传入insertObjList(Obj objList) <service层,再去调用dao层的单个insert数据里

首先创建了ExcelController用于接收路径请求;

package com.tansuo365.test1.controller;

import com.alibaba.fastjson.JSONObject;
import com.sargeraswang.util.ExcelUtil.ExcelLogs;
import com.sargeraswang.util.ExcelUtil.ExcelUtil;
import com.tansuo365.test1.bean.PetroleumCoke;
import com.tansuo365.test1.service.PetroleumCokeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile; import java.io.IOException;
import java.io.InputStream;
import java.util.Collection;
import java.util.List; @RestController
@RequestMapping("/excel")
public class ExcelController { @Autowired
private PetroleumCokeService petroleumCokeService; @RequestMapping("/importExcel")
public Integer importExcel(@RequestParam(value = "uploadFile") MultipartFile uploadFile,
Model model){
JSONObject jsonObject = new JSONObject();
InputStream in = null;
System.err.println("in Excel Controller importExcel method;");
System.out.println("excel:"+uploadFile);
//获取前台excel输入流
try {
in = uploadFile.getInputStream();
System.err.println(in);
} catch (IOException e) {
e.printStackTrace();
}
//excel的表头与文字对应,获取excel表头.
if (uploadFile.getOriginalFilename().isEmpty() || uploadFile.getSize() == 0) {
String message="上传失败";
model.addAttribute("m",message);
}
ExcelLogs log = new ExcelLogs();
Collection<PetroleumCoke> petroleumCokes = ExcelUtil.importExcel(PetroleumCoke.class, in, "yyyy/MM/dd HH:mm:ss", log, 0);
List list = (List) petroleumCokes;
Integer message = petroleumCokeService.insertBatchList(list); return message;
}
}

在进行转换时因为前端页面使用了转化(将字段转为了对应的中文)

coke.html  line 474 :

 sheetsData.forEach(function (item, index) {
content[item.position] = {v: item.value};
if (item.value == 'id') {
content[item.position] = {v: '序列号'};
} else if (item.value == 'grade') {
content[item.position] = {v: '品级'};
} else if (item.value == 'province') {
content[item.position] = {v: '省份'};
} else if (item.value == 'company') {
content[item.position] = {v: '企业'};
} else if (item.value == 's_company') {
content[item.position] = {v: '简称'};
} else if (item.value == 'sulfur') {
content[item.position] = {v: '硫含量%'};
} else if (item.value == 'ash') {
content[item.position] = {v: '灰分%'};
} else if (item.value == 'volatile_matter') {
content[item.position] = {v: '挥发分%'};
} else if (item.value == 'wdr') {
content[item.position] = {v: '扣水率%'};
} else if (item.value == 'vanadium') {
content[item.position] = {v: '钒含量ppm'};
} else if (item.value == 'density') {
content[item.position] = {v: '真密度g/cm³'};
} else if (item.value == 'coke_content') {
content[item.position] = {v: '粉焦量'};
} else if (item.value == 'coke_type') {
content[item.position] = {v: '类型'};
} else if (item.value == 'today_price') {
content[item.position] = {v: '今日报价(元)'};
} else if (item.value == 'remarks') {
content[item.position] = {v: '备注'};
} else if (item.value == 'create_time') {
content[item.position] = {v: '创建时间'};
} else if (item.value == 'update_time') {
content[item.position] = {v: '更新时间'};
}
});

excel:

所以在录入的时候其没法根据字段去录入所以报错:

### SQL: insert into petroleum_coke_tbl (province, company, s_company,     sulfur, ash, volatile_matter,     wdr, vanadium, coke_type,     today_price, remarks, grade,     expand_2, expand_3, create_time,     update_time, density, coke_content     )     values              (?, ?, ?,       ?, ?, ?,       ?, ?, ?,       ?, ?, ?,       ?, ?, ?,       ?, ?, ?       )      ,        (?, ?, ?,       ?, ?, ?,       ?, ?, ?,       ?, ?, ?,       ?, ?, ?,       ?, ?, ?       )
### Cause: java.sql.SQLIntegrityConstraintViolationException: Column 'province' cannot be null

在将上面js注释了转换后导出测试excel数据,再次进行导入测试:

错误依旧.这就奇怪了

那么也就是说传入的list中的province和其它字段是空的.

in Excel Controller importExcel method;
java.io.FileInputStream@7ebe9a94
petroleumCokes.toString()>>[PetroleumCoke(id=null, grade=null, province=null, company=null, s_company=null, sulfur=null, ash=null, volatile_matter=null, wdr=null, vanadium=null, density=null, coke_content=null, coke_type=null, today_price=null, remarks=null, expand_2=null, expand_3=null, create_time=null, update_time=null), PetroleumCoke(id=null, grade=null, province=null, company=null, s_company=null, sulfur=null, ash=null, volatile_matter=null, wdr=null, vanadium=null, density=null, coke_content=null, coke_type=null, today_price=null, remarks=null, expand_2=null, expand_3=null, create_time=null, update_time=null)]
list.get(0)>>PetroleumCoke(id=null, grade=null, province=null, company=null, s_company=null, sulfur=null, ash=null, volatile_matter=null, wdr=null, vanadium=null, density=null, coke_content=null, coke_type=null, today_price=null, remarks=null, expand_2=null, expand_3=null, create_time=null, update_time=null)
list.get(1)>>PetroleumCoke(id=null, grade=null, province=null, company=null, s_company=null, sulfur=null, ash=null, volatile_matter=null, wdr=null, vanadium=null, density=null, coke_content=null, coke_type=null, today_price=null, remarks=null, expand_2=null, expand_3=null, create_time=null, update_time=null)

如我所判断,确实这样,那么是ExcelUtil工具类转换出错么? (这里测试时,将inputStream读取了两次,第二次时就报错了,因为输入流只能读取一次,非要读取两次就应该拷贝一个输入流)

在bean上加上注解后还是出错. 读取不到除了String类型的其它参数:

petroleumCokes.toString()>>[PetroleumCoke(id=null, grade=null, province=山东, company=1, s_company=1, sulfur=null, ash=null, volatile_matter=null, wdr=null, vanadium=null, density=null, coke_content=null, coke_type=null, today_price=null, remarks=1, expand_2=null, expand_3=null, create_time=null, update_time=null), PetroleumCoke(id=null, grade=null, province=山东, company=1, s_company=1, sulfur=null, ash=null, volatile_matter=null, wdr=null, vanadium=null, density=null, coke_content=null, coke_type=null, today_price=null, remarks=null, expand_2=null, expand_3=null, create_time=null, update_time=null)]
list.get(0)>>PetroleumCoke(id=null, grade=null, province=山东, company=1, s_company=1, sulfur=null, ash=null, volatile_matter=null, wdr=null, vanadium=null, density=null, coke_content=null, coke_type=null, today_price=null, remarks=1, expand_2=null, expand_3=null, create_time=null, update_time=null)
list.get(1)>>PetroleumCoke(id=null, grade=null, province=山东, company=1, s_company=1, sulfur=null, ash=null, volatile_matter=null, wdr=null, vanadium=null, density=null, coke_content=null, coke_type=null, today_price=null, remarks=null, expand_2=null, expand_3=null, create_time=null, update_time=null)

这里看一眼importExcel方法

 public static <T> Collection<T> importExcel(Class<T> clazz, InputStream inputStream, String pattern, ExcelLogs logs, Integer... arrayCount) {
Workbook workBook;
try {
workBook = WorkbookFactory.create(inputStream);
} catch (Exception var28) {
LG.error("load excel file error", var28);
return null;
} List<T> list = new ArrayList();
Sheet sheet = workBook.getSheetAt(0);
Iterator rowIterator = sheet.rowIterator(); try {
List<ExcelLog> logList = new ArrayList();
HashMap titleMap = new HashMap(); while(true) {
Row row;
label136:
do {
while(rowIterator.hasNext()) {
row = (Row)rowIterator.next();
if (row.getRowNum() == 0) {
continue label136;
} boolean allRowIsNull = true;
Iterator cellIterator = row.cellIterator(); while(cellIterator.hasNext()) {
Object cellValue = getCellValue((Cell)cellIterator.next());
if (cellValue != null) {
allRowIsNull = false;
break;
}
} if (allRowIsNull) {
LG.warn("Excel row " + row.getRowNum() + " all row value is null!");
} else {
StringBuilder log = new StringBuilder();
if (clazz == Map.class) {
Map<String, Object> map = new HashMap();
Iterator var36 = titleMap.keySet().iterator(); while(var36.hasNext()) {
String k = (String)var36.next();
Integer index = (Integer)titleMap.get(k);
Cell cell = row.getCell(index);
if (cell == null) {
map.put(k, (Object)null);
} else {
cell.setCellType(CellType.STRING);
String value = cell.getStringCellValue();
map.put(k, value);
}
} list.add(map);
} else {
T t = clazz.newInstance();
int arrayIndex = 0;
int cellIndex = 0;
List<FieldForSortting> fields = sortFieldByAnno(clazz);
Iterator var19 = fields.iterator(); while(true) {
while(var19.hasNext()) {
FieldForSortting ffs = (FieldForSortting)var19.next();
Field field = ffs.getField();
field.setAccessible(true);
if (field.getType().isArray()) {
Integer count = arrayCount[arrayIndex];
Object value;
if (field.getType().equals(String[].class)) {
value = new String[count];
} else {
value = new Double[count];
} for(int i = 0; i < count; ++i) {
Cell cell = row.getCell(cellIndex);
String errMsg = validateCell(cell, field, cellIndex);
if (StringUtils.isBlank(errMsg)) {
((Object[])value)[i] = getCellValue(cell);
} else {
log.append(errMsg);
log.append(";");
logs.setHasError(true);
} ++cellIndex;
} field.set(t, value);
++arrayIndex;
} else {
Cell cell = row.getCell(cellIndex);
String errMsg = validateCell(cell, field, cellIndex);
if (StringUtils.isBlank(errMsg)) {
Object value = null;
if (field.getType().equals(Date.class) && cell.getCellTypeEnum() == CellType.STRING) {
Object strDate = getCellValue(cell); try {
value = (new SimpleDateFormat(pattern)).parse(strDate.toString());
} catch (ParseException var27) {
errMsg = MessageFormat.format("the cell [{0}] can not be converted to a date ", CellReference.convertNumToColString(cell.getColumnIndex()));
}
} else {
value = getCellValue(cell);
ExcelCell annoCell = (ExcelCell)field.getAnnotation(ExcelCell.class);
if (value instanceof String && !field.getType().equals(String.class) && StringUtils.isNotBlank(annoCell.defaultValue())) {
value = annoCell.defaultValue();
}
} field.set(t, value);
} if (StringUtils.isNotBlank(errMsg)) {
log.append(errMsg);
log.append(";");
logs.setHasError(true);
} ++cellIndex;
}
} list.add(t);
logList.add(new ExcelLog(t, log.toString(), row.getRowNum() + 1));
break;
}
}
}
} logs.setLogList(logList);
return list;
} while(clazz != Map.class); Iterator<Cell> cellIterator = row.cellIterator(); for(Integer index = 0; cellIterator.hasNext(); index = index + 1) {
String value = ((Cell)cellIterator.next()).getStringCellValue();
titleMap.put(value, index);
}
}
} catch (InstantiationException var29) {
throw new RuntimeException(MessageFormat.format("can not instance class:{0}", clazz.getSimpleName()), var29);
} catch (IllegalAccessException var30) {
throw new RuntimeException(MessageFormat.format("can not instance class:{0}", clazz.getSimpleName()), var30);
}
}

sheet对应着excel表的那个sheel,表示一个工作簿

row表示每行

下面代码判断了是否每个工作簿不是空的,空的就allRowIsNull = true, 如果元素 cellIterator.next(),判断获取的cellValue不是空的话,就将allRowIsNull = false (即有数据了,不要给他true的flag了)

 while(true) {
Row row;
label136:
do {
while(rowIterator.hasNext()) {
row = (Row)rowIterator.next();
if (row.getRowNum() == 0) {
continue label136;
} boolean allRowIsNull = true;
Iterator cellIterator = row.cellIterator(); while(cellIterator.hasNext()) {
Object cellValue = getCellValue((Cell)cellIterator.next());
if (cellValue != null) {
allRowIsNull = false;
break;
}
} if (allRowIsNull) {
LG.warn("Excel row " + row.getRowNum() + " all row value is null!");
} else {
StringBuilder log = new StringBuilder();
if (clazz == Map.class) {
Map<String, Object> map = new HashMap();
Iterator var36 = titleMap.keySet().iterator(); while(var36.hasNext()) {
String k = (String)var36.next();
Integer index = (Integer)titleMap.get(k);
Cell cell = row.getCell(index);
if (cell == null) {
map.put(k, (Object)null);
} else {
cell.setCellType(CellType.STRING);
String value = cell.getStringCellValue();
map.put(k, value);
}
} list.add(map);
} else {
T t = clazz.newInstance();
int arrayIndex = 0;
int cellIndex = 0;
List<FieldForSortting> fields = sortFieldByAnno(clazz);
Iterator var19 = fields.iterator();

for(Integer index = 0; cellIterator.hasNext(); index = index + 1) {
String value = ((Cell)cellIterator.next()).getStringCellValue();
titleMap.put(value, index);
}

可以看到上面这些好像都必须cell为string类型.

第二个错误是转型异常

can't ...numberic from string value.原因是设置的时间格式.

Collection<PetroleumCoke> petroleumCokes = ExcelUtil.importExcel(PetroleumCoke.class, in, "yyyy-MM-dd HH:mm:ss", log, 0);

注意这里的yyyy-MM-dd HH:mm:ss

当设置不全时,比如省略了excel中的HH:mm:ss,就会以00:00:00填充到数据中(录入后),所以要把excel表中的时间格式与这里的yyyy-MM-dd...对应起来,后期可以设置为后台设定.

remarks=null, expand_2=null, expand_3=null, create_time=Sun Jan 20 00:00:00 CST 2019, update_time=null)

为了快速开发,暂时把bean中的float改为double, Integer Long 改为了String

PetroleumCoke(id=31, grade=null, province=山东, company=1, s_company=31简称, sulfur=1.2, ash=4.0, volatile_matter=1.2, wdr=1.2, vanadium=123.0, density=1.2, coke_content=12.0, coke_type=海绵焦, today_price=213.0, remarks=备注31, expand_2=null, expand_3=null, create_time=null, update_time=null)
PetroleumCoke(id=32, grade=null, province=山东, company=1, s_company=32简称, sulfur=2.2, ash=12.0, volatile_matter=2.3, wdr=1.2, vanadium=2.0, density=1.3, coke_content=12.0, coke_type=弹丸焦, today_price=3124.0, remarks=备注32, expand_2=null, expand_3=null, create_time=Sun Jan 20 00:00:00 CST 2019, update_time=null)
PetroleumCoke(id=33, grade=null, province=山东, company=的, s_company=的, sulfur=1.2, ash=1.5, volatile_matter=3.0, wdr=1.2, vanadium=1.0, density=1.4, coke_content=11.0, coke_type=海绵焦, today_price=142.0, remarks=备注33, expand_2=null, expand_3=null, create_time=Sun Jan 20 18:16:04 CST 2019, update_time=null)

导入导出ok,不足之处是导出的excel再导入的话会有错误-->非string字段需要双击改善下(即将靠左的numberic改为靠右才判定为numberic,否则string)

导出通过的是html的js,没有调用数据库,而导出的字段可以在js中进行调整: 在上面提到的coke.html  line474

[exceltolist] - 一个excel转list的工具的更多相关文章

  1. C#开发的高性能EXCEL导入、导出工具DataPie(支持MSSQL、ORACLE、ACCESS,附源码下载地址)[转]

    转自:http://www.cnblogs.com/yfl8910/archive/2012/05/19/2509194.html 作为财务数据核算人员,面对大量的业务与财务数据,借助于传统的EXCE ...

  2. JEasyPoi 2.1.4 (Jeecg订制) 版本发布,Excel 和 Word 简易工具类

    JEasyPoi 2.1.4 (jeecg订制)版本发布,EasyPoi Excel 和 Word 简易工具类 easypoi 功能如同名字easy,主打的功能就是容易,让一个没见接触过poi的人员 ...

  3. Excel和Word 简易工具类,JEasyPoi 2.1.5 版本发布

    Excel和Word 简易工具类,JEasyPoi 2.1.5 版本发布 摘要: jeasypoi 功能如同名字easy,主打的功能就是容易,让一个没见接触过poi的人员 就可以方便的写出Excel导 ...

  4. JXLS (Excel导入、导出工具使用)

    JXLS (Excel导入.导出工具使用) 1:简介: jxls是一个简单的.轻量级的excel导出库,使用特定的标记在excel模板文件中来定义输出格式和布局.java中成熟的excel导出工具有p ...

  5. 《数据分析实战:基于EXCEL和SPSS系列工具的实践》一1.4 数据分析的流程

    本节书摘来华章计算机<数据分析实战:基于EXCEL和SPSS系列工具的实践>一书中的第1章 ,第1.4节,纪贺元 著 更多章节内容可以访问云栖社区"华章计算机"公众号查 ...

  6. 读取EXCEL文档解析工具类

    package test;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException ...

  7. 多Excel文件内容查询工具。

    多Excel文件内容查询工具. 告别繁琐重复的体力劳动,一分钟干完一天的活. 码云 github 下载 当需要在多个Excel表格中查询需要的信息是,一个文件一个文件的去查询非常麻烦. 虽然有其他方法 ...

  8. ExcelPatternTool: Excel表格-数据库互导工具

    ExcelPatternTool Excel表格-数据库互导工具 介绍: 指定Pattern文件-一个规则描述的json文档,基于此规则实现Excel表格与数据库之间的导入导出,校验等功能. 特点: ...

  9. 用php生成一个excel文件(原理)

    1.我们用php来生成一个excel文档来讲述其原理: excel2007里面的文档目录组成部分为: 2.我们使用ZipArchive()方法来生成一个简易的excel文件. 使用方法: 3.代码如下 ...

随机推荐

  1. 【2017-03-13】Tsql 表连接

    笛卡尔积          穷举 在未建立连接的情况下,将car表的name列和brand表的brand_name列进行笛卡尔积查询后,实际是将两列相乘,进行穷举,列举出所有可能性 表连接:将多个表不 ...

  2. Qt信号之自定义数据类型

    [1]为什么需要自定义数据类型? 内置类型毕竟很有局限性,否则为什么还需要类呢.总之,有时候,我们多么希望信号能发送自定义数据类型. 幸哉~ Qt是支持自定义信号,且自定义信号可以发送自定义数据类型的 ...

  3. hive 实现一个字段多行转一行 和 一行转多行

    1.多行转一行 多行转一行可以通过concat_ws(',',collect_set(col_name)) as col_new的方式实现,可以参考:https://www.cnblogs.com/s ...

  4. ClassOne__HomeWork

    1,static类型 static类型定义有两类,一类是静态数据,另一类是静态函数. 静态数据跟成员变量不同,它可以通过类名直接访问,而不需要通过定义对象来访问.它的的生成也和成员变量不一样,它只生成 ...

  5. 安装PG3.0详细教程附图

    从公司要求开始着手调研PG到今天上午都还不知道如何安装PG.. 囧的离谱.. 看了半天的PG官网 就这个网页我瞅了半天..对你没看错 半天 少说有10分钟..原谅我的英文不是非常好..但是我知道什么意 ...

  6. Icarscan VCI is definitely the update variation of Start iDiag

    Start iCarScan is alternative of Super X431 iDiag, it’ll make your Android smartphone or tablet righ ...

  7. webpack 创建vue项目过程中遇到的问题和解决方法

    目录 1 webpack简介 2 webpack实现多个输入输出多个html 3  webpack 中的module下rules 下的use和loader选项 4 webpack 文件更新,如何使页面 ...

  8. CI(CodeIgniter)框架下使用非自带类库实现邮件发送

    在项目开发过程中,需要到了邮件提醒功能.首先想到的是CI自身带不带邮件发送类,查看帖子,发现CI本身自带,然后试着利用CI自身带的类库来实现,经过搜搜很多帖子,不少开发者反馈CI自身的Email类有问 ...

  9. direct加载之ora-39782一例

    近日,我们有个环境在数据加载到oracle的时候出现ora-39782异常,版本是11.2.经google,几乎没有什么先例,因为我们是使用oci直接写的,可见现在还使用oci接口并不多,也或者我们的 ...

  10. MacOS Docker 安装

    使用 Homebrew 安装 macOS 我们可以使用 Homebrew 来安装 Docker. Homebrew 的 Cask 已经支持 Docker for Mac,因此可以很方便的使用 Home ...