Cannot get a NUMERIC value from a STRING cell? 已解决
最近在写项目中用到了excel的导入,遇到了Cannot get a NUMERIC value from a STRING cell的报错。原因是无法从纯数字的单元格用获取String的方式获取。跟了一下蛋码,但是我明明做了处理了啊,看这里
真是奇了个怪。。。。
网上百度了一堆,基本都指出了这个错误的原因,但。。。可能是我这个新手看不懂别人的蛋码吧,其实我觉得他们的蛋码没有抽出来真的难看。
好了,看看我之前的代码:
再看看我修改之后的代码:
总结起来就是,我已经把读取到的单元格内容的类型(NUMERIC)改为了STRING了,但我不知道为什么switch还是走了NUMERIC(可能是我没有转换格式成功),然后我又用NUMERIC的取值方式 getNumericCellValue(),所以就报错咯。
这是全部代码
Controller
/**
* 兑换码导入
*
* @return
* @throws ParseException
* @author lmh
*/
@PostMapping(value = "/readExcel")
// @ApiOperation(value = "兑换码导入")
@Transactional
// @RequiresPermissions("/lotteryPrize/readExcel")
// @ApiImplicitParams({
// @ApiImplicitParam(name = "prizeId", value = "奖品id", required = true, dataType = "String"),
// @ApiImplicitParam(name = "prizeUrl", value = "兑换URI", required = true, dataType = "String")})
public ResponseEntity<Map<String, Object>> readExcel(/*String prizeId, String prizeUrl,*/
@RequestParam(value = "excelFile") MultipartFile excelFile) throws ParseException {
Map<String, Object> resultMap = new HashMap<>();
try {
// 修改奖品表
// LotteryPrize prize = new LotteryPrize();
// prize.setId(prizeId);
// prize.setPrizeUrl(prizeUrl);
// prize.setUpdateTime(new Date(System.currentTimeMillis()));
// boolean ret = this.prizeService.updateById(prize);
// 导入兑换码
List<LotteryRedeemCode> redeemCodes = new ArrayList<LotteryRedeemCode>();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
List<String[]> codeList = ReadExcelUtil.readExcel(excelFile);
Map<String, Integer> titleMap = new HashMap<String, Integer>();
for (int i = 0; i < codeList.size(); i++) {
String[] code = codeList.get(i);
if (i == 0) {
for (int j = 0; j < code.length; j++) {
titleMap.put(code[j], j);
}
continue;
}
LotteryRedeemCode redeemCode = new LotteryRedeemCode();
redeemCode.setCreateTime(new Date(System.currentTimeMillis()));
redeemCode.setRedeemCode(code[titleMap.get("兑换码")]);
// redeemCode.setPrizeId(prizeId);
redeemCodes.add(redeemCode);
}
if (redeemCodes.size() > 0) {
// 批量新增(这里是Mybatis-Plus框架),你们可以用for进行新增操作
this.redeemCodeService.insertBatch(redeemCodes);
}
if (!ret) {
// 删除失败, 500
resultMap.put("status", 500);
resultMap.put("message", "上传失败!");
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(resultMap);
}
resultMap.put("status", 201);
resultMap.put("message", "上传成功!");
return ResponseEntity.status(HttpStatus.CREATED).body(resultMap);
} catch (IOException e) {
logger.info("读取excel文件失败", e);
}
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);
}
package 这里自己写; import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List; import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile; /**
* 导入excel工具类
*
* @author lmh
*/
public class ReadExcelUtil { private static Logger logger = LoggerFactory.getLogger(ReadExcelUtil.class);
private final static String xls = "xls";
private final static String xlsx = "xlsx"; /**
* 读入excel文件,解析后返回
*
* @param file
* @throws IOException
*/
public static List<String[]> readExcel(MultipartFile file) throws IOException {
// 检查文件
checkFile(file);
// 获得Workbook工作薄对象
Workbook workbook = getWorkBook(file);
// 创建返回对象,把每行中的值作为一个数组,所有行作为一个集合返回
List<String[]> list = new ArrayList<String[]>();
if (workbook != null) {
for (int sheetNum = 0; sheetNum < workbook.getNumberOfSheets(); sheetNum++) {
// 获得当前sheet工作表
Sheet sheet = workbook.getSheetAt(sheetNum);
if (sheet == null) {
continue;
}
// 获得当前sheet的开始行
int firstRowNum = sheet.getFirstRowNum();
// 获得当前sheet的结束行
int lastRowNum = sheet.getLastRowNum(); if (firstRowNum <= 0 && lastRowNum < 1) {
break;
}
// 获取头部的长度
Row tiRow = sheet.getRow(firstRowNum);
int totalClumNum = tiRow.getPhysicalNumberOfCells(); // 循环所有行
for (int rowNum = firstRowNum; rowNum <= lastRowNum; rowNum++) {
// 获得当前行
Row row = sheet.getRow(rowNum);
if (row == null) {
continue;
}
int lastCellNum = row.getPhysicalNumberOfCells();
if (lastCellNum <= 0) {
continue;
}
// 获得当前行的开始列
// int firstCellNum = row.getFirstCellNum(); 区第一个有值的列
// //获得当前行的列数
// int lastCellNum = row.getPhysicalNumberOfCells();
String[] cells = new String[totalClumNum];
// 循环当前行
for (int cellNum = 0; cellNum < totalClumNum; cellNum++) {
Cell cell = row.getCell(cellNum);
cells[cellNum] = getCellValue(cell);
}
list.add(cells);
}
}
workbook.close();
}
return list;
} public static void checkFile(MultipartFile file) throws IOException {
// 判断文件是否存在
if (null == file) {
logger.error("文件不存在!");
throw new FileNotFoundException("文件不存在!");
}
// 获得文件名
String fileName = file.getOriginalFilename();
// 判断文件是否是excel文件
if (!fileName.endsWith(xls) && !fileName.endsWith(xlsx)) {
logger.error(fileName + "不是excel文件");
throw new IOException(fileName + "不是excel文件");
}
} public static Workbook getWorkBook(MultipartFile file) {
// 获得文件名
String fileName = file.getOriginalFilename();
// 创建Workbook工作薄对象,表示整个excel
Workbook workbook = null;
try {
// 获取excel文件的io流
InputStream is = file.getInputStream();
// 根据文件后缀名不同(xls和xlsx)获得不同的Workbook实现类对象
if (fileName.endsWith(xls)) {
// 2003
workbook = new HSSFWorkbook(is);
} else if (fileName.endsWith(xlsx)) {
// 2007
workbook = new XSSFWorkbook(is);
}
} catch (IOException e) {
logger.info(e.getMessage());
}
return workbook;
} public static String getCellValue(Cell cell) {
SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd");
String cellValue = "";
if (cell == null) {
return cellValue;
} CellType cellType = cell.getCellTypeEnum();
// 把数字当成String来读,避免出现1读成1.0的情况
if (cellType == CellType.NUMERIC) {
cell.setCellType(CellType.STRING);
} // 判断数据的类型
switch (cellType) {
case NUMERIC: // 数字、日期
if (DateUtil.isCellDateFormatted(cell)) {
cellValue = fmt.format(cell.getDateCellValue()); // 日期型
} else {
cellValue = String.valueOf(cell.getStringCellValue());
// cellValue = String.valueOf(cell.getNumericCellValue()); // 数字
if (cellValue.contains("E")) {
cellValue = String.valueOf(new Double(cell.getNumericCellValue()).longValue()); // 数字
}
}
break;
case STRING: // 字符串
cellValue = String.valueOf(cell.getStringCellValue());
break;
case BOOLEAN: // Boolean
cellValue = String.valueOf(cell.getBooleanCellValue());
break;
case FORMULA: // 公式
cellValue = String.valueOf(cell.getCellFormula());
break;
case BLANK: // 空值
cellValue = cell.getStringCellValue();
break;
case ERROR: // 故障
cellValue = "非法字符";
break;
default:
cellValue = "未知类型";
break;
}
return cellValue;
} }
上面是工具类,下面是实体类:
@TableName("lottery_redeem_code")
public class LotteryRedeemCode extends Model<LotteryRedeemCode> { private static final long serialVersionUID = 1L; @TableId(value = "id", type = IdType.UUID)
private String id;
/**
* 奖品ID
*/
@ApiModelProperty(value = "奖品ID")
@TableField("prize_id")
private String prizeId;
/**
* 兑换码
*/
@ApiModelProperty(value = "兑换码")
@TableField("redeem_code")
private String redeemCode;
/**
* 0-已抽中 1-未抽中
*/
@ApiModelProperty(value = "0-已抽中 1-未抽中")
private Integer status;
/**
* 创建时间
*/
@ApiModelProperty(value = "创建时间")
@TableField("create_time")
private Date createTime;
/**
* 修改时间
*/
@ApiModelProperty(value = "修改时间", hidden = true)
@TableField("update_time")
private Date updateTime; public String getId() {
return id;
} public void setId(String id) {
this.id = id;
} public String getPrizeId() {
return prizeId;
} public void setPrizeId(String prizeId) {
this.prizeId = prizeId;
} public String getRedeemCode() {
return redeemCode;
} public void setRedeemCode(String redeemCode) {
this.redeemCode = redeemCode;
} public Integer getStatus() {
return status;
} public void setStatus(Integer status) {
this.status = status;
} public Date getCreateTime() {
return createTime;
} public void setCreateTime(Date createTime) {
this.createTime = createTime;
} public Date getUpdateTime() {
return updateTime;
} public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
} @Override
protected Serializable pkVal() {
return this.id;
} @Override
public String toString() {
return "LotteryRedeemCode{" +
", id=" + id +
", prizeId=" + prizeId +
", redeemCode=" + redeemCode +
", status=" + status +
", createTime=" + createTime +
", updateTime=" + updateTime +
"}";
}
}
MySQL:
CREATE TABLE `lottery_redeem_code` (
`id` CHAR(32) NOT NULL,
`redeem_code` VARCHAR(100) NOT NULL COMMENT '兑换码',
`status` TINYINT(4) NOT NULL DEFAULT '1' COMMENT '0-已抽中 1-未抽中',
`create_time` DATETIME NOT NULL COMMENT '创建时间',
`update_time` DATETIME NULL DEFAULT NULL COMMENT '修改时间',
PRIMARY KEY (`id`)
)
COMMENT='奖品兑换码表'
COLLATE='utf8_general_ci'
ENGINE=InnoDB
;
这是excel表的格式,格式要求不高,只要有一列的表头是“兑换码”就行了,可以随意更改,只要和Controller中的
redeemCode.setRedeemCode(code[titleMap.get("兑换码")]);对应起来就行了,假如我把”兑换码“换成”牛逼“,excel的表头也要换成”牛逼“。多个表头的操作也一样。
Cannot get a NUMERIC value from a STRING cell? 已解决的更多相关文章
- c#npoi 报错Cannot get a numeric value from a text cell 的解决
一般是因为cell里边的值为数字导致,有时变成文本格式还是解决不了这个问题. 下边的代码是c# 改变设置cell类型的方法 是用这个参数 CellType.String Row.GetCell((in ...
- string.erase()--已解决
在代码中需要实现这样一个功能,需要将[00000001]这个存储在string中的字符串的中括号去掉,首先想到的就是string.erase()这个函数.结果... 代码: #include < ...
- SyntaxError: EOL while scanning string literal的解决
2281 python中字符串的最后一个字符是斜杠会导致出错:SyntaxError: EOL while scanning string literal [背景] Python 2.7.2 中想要通 ...
- SpringBoot整合Swagger2案例,以及报错:java.lang.NumberFormatException: For input string: ""原因和解决办法
原文链接:https://blog.csdn.net/weixin_43724369/article/details/89341949 SpringBoot整合Swagger2案例 先说SpringB ...
- ASP.NET - Web API,从简单类型到复杂类型的参数传递用例,以及传递简单string类型的解决办法
一,简单类型的传值 比如 public Users Get(int id) ,它可以使用两种方式获取: api/default/ $.get("/api/default",{id: ...
- Incorrect string value异常解决
mysql数据库的一个问题 1366-Incorrect string value:'\xE5\x8D\xA1\xE5......' for column 'filename' at row 1 问题 ...
- Spring @ResponseBody只能返回String类型数据解决办法
今天自己搭Spring MVC框架玩,使用AJAX调用Spring controller 并返回map对象,突然发现,哎,怎么@Response中只能返回String, 我用的Spring 3的版本也 ...
- spring mvc绑定对象String转Date解决入参不能是Date的问题
使用spring的mvc,直接将页面参数绑定到对象中,对象中有属性为Date时会报错,此时需要处理下. 同样的,其他的需要处理的类型也可以用这种方法. 在controller中加入代码 @InitBi ...
- mybatis invalid comparison: java.sql.Timestamp and java.lang.String报错解决方法
这个错的意思是:java.sql.Timestamp和java.lang.String无效的比较 错误的原因是:拿传入的时间类型参数与空字符串进行比较就会报这个异常 解决方法:只保留非null判断就可 ...
随机推荐
- AngularJs-变量
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...
- Pycharm2019最新激活码
激活pycharm的方法有很多,一种是使用最新的激活码,另一种是使用破解补丁的方式(可以长期使用) pycharm2019最新激活码: 812LFWMRSH-eyJsaWNlbnNlSWQiOiI4M ...
- 通过远程 HTTP GET 请求载入信息
jQuery.get(url, [data], [callback], [type]) 概述 通过远程 HTTP GET 请求载入信息. 这是一个简单的 GET 请求功能以取代复杂 $.ajax .请 ...
- jquery unload方法 语法
jquery unload方法 语法 作用:当用户离开页面时,会发生 unload 事件.具体来说,当发生以下情况时,会发出 unload 事件:点击某个离开页面的链接在地址栏中键入了新的 URL使用 ...
- VLC播放器:快捷键
造冰箱的大熊猫@cnblogs 2019/2/27 VLC播放器(VLC Media Player)快捷键汇总(在Ubuntu 16.04环境下测试) - 音量大/小:CTRL+上/下 - 静音开/ ...
- NOI2013 二叉查找树
题目链接:戳我 对于一个排序二叉树来讲,它的中序遍历对应的序列是可以确定的. 我们知道如果求一个访问频率最低的(也就是没有修改),直接就区间DP即可.\(dp[i][j]=min(dp[i][j],d ...
- 使用matplotlib绘制常用图表(1)
#导入相关包from matplotlib import pyplot as plt import matplotlib from matplotlib import font_manager #初始 ...
- BZOJ1718分离的路径
边双题. 求的就是最少加几条边可以使一个图变成边双联通图. 首先tarjan求一下边双,缩完点变成一颗树,统计度数为1的点(无根树的叶子),把这个数算出来,设为x,则ans=(x+1)/2. 这个可以 ...
- 初识 Premiere
本记录基于Premiere Pro CC 2015.3,编号不连贯,以视频编号为准,对应视频没有有用信息的没有记录. 1.3 基本工作界面和预设工作区 将面板独立出来:按住Ctrl拖动窗口 将关闭的面 ...
- 通过ID获取元素
网页由标签将信息组织起来,而标签的id属性值是唯一的,就像是每人有一个身份证号一样,只要通过身份证号就可以找到相对应的人.那么在网页中,我们通过id先找到标签,然后进行操作. 语法: document ...