Open syc824951 opened 2 months ago
same question link #3793 .
Please add config use1904windowing(true)
目前这个情况与上述问题不是一个问题,
现在是将上图数据 会识别为1970/01/01 这种情况。还有一种情况忘说了,在wps中点击该时间框会转变为数值类型,如图:
这种数据读取会丢失左上方公式框内的精度。
我也出现日期读取出现错误情况,在程序读取1999/10/10 12:00:00 时候,大部分情况都是正常将数值转成日期,会偶现出现读取出来是数值36443.5,不知道是不是DateUtils中的ThreadLocal变量引起,望解答!
请提供完整代码或仓库链接
我无法通过你的贴图复现你的问题,请提供可以复现的代码和excel
服务器为arm64架构 日期出问题文件为: 日期问题文件.xlsx 丢失精度问题文件为:这里数据是再wps中双击交易时间列,他会自动转为数值,读取时会丢失公式框内精度。 丢失精度数据问题.xlsx 金额读取乱码文件:其中标黄的1.66为容易出问题地方 金额读取乱码文件.xlsx 读取时日志截图如下:
你可以提供一份直接复现问题的代码或仓库链接吗? 你的问题已经描述清楚了,我需要一份能复现的代码而不是各种贴图
package com.chinatelecom.business.datahandle.listener;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelReader;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.read.metadata.ReadSheet;
import com.chinatelecom.business.datahandle.domain.dto.ExcelReadDto;
import lombok.Data;
import org.springframework.util.CollectionUtils;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Test {
public static void main(String[] args) {
List<ExcelReadDto> list = new ArrayList<>();
try (InputStream fis = new URL("file:///E:\\work\\测试500问题\\空文件.xlsx").openStream()){
ExcelReader excelReader = EasyExcel.read(fis).build();
List<ReadSheet> readSheets = excelReader.excelExecutor().sheetList();
for (int i = 0; i < readSheets.size(); i++) {
ReadSheet readSheet = readSheets.get(i);
ExcelReadDto excelReadDto = new ExcelReadDto();
excelReadDto.setSheetName(readSheet.getSheetName());
list.add(readLimitExcel(excelReadDto, "空文件", 30, 20, readSheets.size(), i, excelReader));
}
System.out.println(readSheets);
} catch (Exception e) {
e.printStackTrace();
}
}
public static ExcelReadDto readLimitExcel(ExcelReadDto excelReadDto, String fileName, Integer limitColSize, Integer limitRowSize, int sheetTotal, int sheetNum, ExcelReader excelReader) {
LimitExcelReadListener dataListener = null;
// 读取sheet页数目
//读取文件数据
try {
//声明读取所需FileInputStream
excelReadDto.setSheetTotal(sheetTotal);
excelReadDto.setSheetNum(sheetNum + 1);
excelReadDto.setFileName(fileName);
dataListener = new LimitExcelReadListener(limitColSize, limitRowSize);
//初始化一个监听器
ReadSheet readSheet = EasyExcel
.readSheet(sheetNum)
.registerReadListener(dataListener)
.build();
excelReader.read(readSheet);
excelReadDto.setDataList(dataListener.getDataList());
excelReader.finish();
} catch (Exception e) {
throw new RuntimeException();
}
return excelReadDto;
}
@Data
static class LimitExcelReadListener extends AnalysisEventListener<Map<Integer, String>> {
// 定义变量,分别表示限制列数和行数
private Integer limitColSize;
private Integer limitRowSize;
private int sheetCount = 0;
/**
* 行数
*/
private int num;
// 定义变量,存储表头信息和表数据
private List<Map<Integer, String>> headList = new ArrayList<>();
private List<Map<Integer, String>> dataList = new ArrayList<>();
// 构造函数
public LimitExcelReadListener() {
}
// 带参构造函数,直接赋值限制行列
public LimitExcelReadListener(Integer limitColSize, Integer limitRowSize) {
this.limitColSize = limitColSize;
this.limitRowSize = limitRowSize;
}
/**
* 工具方法,根据传入的列限制来保留数据,也就是只取前几个Key,如果有需求,可以自己添加KeySet排序之后再取,我这里没这个需求
*
* @param oldMap 未限制列前的Map
* @return 限制列后的Map
*/
private Map<Integer, String> getLimitColMap(Map<Integer, String> oldMap) {
Integer size = oldMap.keySet().size();
Map<Integer, String> newMap = new HashMap<>();
for (int i = 0; i < (size >= this.limitColSize ? this.limitColSize : size); i++) {
//TODO 在这里获取时 就能看到乱码情况
newMap.put(i, oldMap.get(i));
}
return newMap;
}
@Override
public void invoke(Map<Integer, String> integerStringMap, AnalysisContext analysisContext) {
// 判断行数已达到限制行数,抛出ExcelAnalysisException
if (dataList.size() < this.limitRowSize) {
Map<Integer, String> newMap = this.getLimitColMap(integerStringMap);
dataList.add(newMap);
if (dataList.size()>2){
if (!CollectionUtils.isEmpty(dataList)){
if (dataList.size() == 3){
System.out.println(dataList.get(0));
System.out.println(dataList.get(1));
System.out.println(dataList.get(2));
}
}
}
// throw new ExcelAnalysisException(this.limitRowSize + "行" + this.limitColSize + "列读取完成");
}
}
@Override
public void invokeHeadMap(Map<Integer, String> headMap, AnalysisContext context) {
// 获取限制列之后的表头Map,并存入headList
Map<Integer, String> newMap = this.getLimitColMap(headMap);
dataList.add(newMap);
sheetCount++;
}
/**
* 所有数据解析完成了 都会来调用
*
* @param context EasyExcel上下文
*/
@Override
public void doAfterAllAnalysed(AnalysisContext context) {
}
}
}
以上 是目前我整理出来的代码。
更新一下 这部分代码实在异步中进行的。 示例:ExecutorService executorService = Executors.newFixedThreadPool(10); executorService.submit(()->{ List<ExcelReadDto> list = new ArrayList<>(); try (InputStream fis = new URL("file:///E:\\work\\测试500问题\\空文件.xlsx").openStream()){ ExcelReader excelReader = EasyExcel.read(fis).build(); List<ReadSheet> readSheets = excelReader.excelExecutor().sheetList(); for (int i = 0; i < readSheets.size(); i++) { ReadSheet readSheet = readSheets.get(i); ExcelReadDto excelReadDto = new ExcelReadDto(); excelReadDto.setSheetName(readSheet.getSheetName()); list.add(readLimitExcel(excelReadDto, "空文件", 30, 20, readSheets.size(), i, excelReader)); } System.out.println(readSheets); } catch (Exception e) { e.printStackTrace(); } });
Hi, after reviewing the comments on this issue, I believe it would be most helpful to provide a runnable, minimal reproducible demo. If possible, making it a Maven project would enable others to get involved more easily.
Hi,我观察了这个issue的评论。我觉得最好提供一个可运行的、最小可复现demo。如果可以的话,最好是一个maven项目。这样能够让其他人更好的参与进来。
建议先去看文档
快速开始 、常见问题
触发场景描述
上传文件。并读取时,在读到日期类型时 比如 创建时间 实际数据为:1999-01-01 11:22:33 但是在程序读出来时会变成1970-01-01 00:00:00 还有在读取数值类型时,原数据为:119944, 在读取后数据为 示例:0(0xwhwh),实际类似。
触发Bug的代码
提示的异常或者没有达到的效果
大家尽量把问题一次性描述清楚,然后贴上全部异常,这样方便把问题一次性解决掉。 至少大家要符合一个原则就是,能让其他人复现出这个问题,如果无法复现,肯定无法解决。