Comments (2)
我使用sax导入使用class类型选择map,发现有错位现象,列无法对应
from easypoi.
已修改,方法可测
`package com.chengkun.utils;
/**
- sungrow all right reserved
**/
import cn.afterturn.easypoi.excel.entity.enmus.CellValueType;
import cn.afterturn.easypoi.excel.entity.sax.SaxReadCellEntity;
import cn.afterturn.easypoi.excel.imports.sax.parse.ISaxRowRead;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.xssf.model.SharedStringsTable;
import org.apache.poi.xssf.model.StylesTable;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import static cn.afterturn.easypoi.excel.entity.sax.SaxConstant.*;
/**
-
@description map回调接口
-
@author chengkun
-
@Date 2020/3/19 19:01
**/
public class MapSheetHandler extends DefaultHandler {
private SharedStringsTable sharedStringsTable;
private StylesTable stylesTable;
private String lastContents;/**
- @description 标题行校验标题是否正确
- @author chengkun
- @Date 2020/3/19 19:54
- @param null
- @return
/
public List titleList;
/ - 当前行
/
private int curRow = 0;
/ - 当前列
**/
private int curCol = 0;
private CellValueType type;
private String currentLocation, prevLocation;
private String lastIndex; //开始标签 只记录c,出现两次c说明有空单元格
private ISaxRowRead read;private List rowList = new ArrayList<>();
public MapSheetHandler(SharedStringsTable sharedStringsTable, StylesTable stylesTable, ISaxRowRead rowRead) {
this.sharedStringsTable = sharedStringsTable;
this.stylesTable = stylesTable;
this.read = rowRead;
}@OverRide
public void startElement(String uri, String localName, String name,
Attributes attributes) throws SAXException {
lastIndex = name;
// 置空
lastContents = "";
if (COL.equals(name)) {
String cellType = attributes.getValue(TYPE);
prevLocation = currentLocation;
currentLocation = attributes.getValue(ROW_COL);
if (STRING.equals(cellType)) {
type = CellValueType.String;
return;
}
if (BOOLEAN.equals(cellType)) {
type = CellValueType.Boolean;
return;
}
if (DATE.equals(cellType)) {
type = CellValueType.Date;
return;
}
if (INLINE_STR.equals(cellType)) {
type = CellValueType.InlineStr;
return;
}
if (FORMULA.equals(cellType)) {
type = CellValueType.Formula;
return;
}
if (NUMBER.equals(cellType)) {
type = CellValueType.Number;
return;
}
try {
short nfId = (short) stylesTable.getCellXfAt(Integer.parseInt(attributes.getValue(STYLE))).getNumFmtId();
String numberFormat = stylesTable.getNumberFormats().get(nfId).toUpperCase();
if (StringUtils.isNotEmpty(numberFormat)) {
if (numberFormat.contains("Y") || numberFormat.contains("M") || numberFormat.contains("D")
|| numberFormat.contains("H") || numberFormat.contains("S") || numberFormat.contains("年")
|| numberFormat.contains("月") || numberFormat.contains("日") || numberFormat.contains("时")
|| numberFormat.contains("分") || numberFormat.contains("秒")) {
type = CellValueType.Date;
return;
}
}
} catch (Exception e) {} // 没别的了就是数字了 type = CellValueType.Number; } else if (T_ELEMENT.equals(name)) { type = CellValueType.TElement; }
}
@OverRide
public void endElement(String uri, String localName, String name) throws SAXException {
// 根据SST的索引值的到单元格的真正要存储的字符串
// 这时characters()方法可能会被调用多次
if (CellValueType.String.equals(type)) {
try {
int idx = Integer.parseInt(lastContents);
lastContents = sharedStringsTable.getItemAt(idx).getString();
} catch (Exception e) {
}
}
if (VALUE.equals(name) && StringUtils.isNotEmpty(prevLocation)) {
addNullCell(prevLocation, currentLocation);
}
//t元素也包含字符串
if (CellValueType.TElement.equals(type)) {
String value = lastContents.trim();
rowList.add(curCol, new SaxReadCellEntity(CellValueType.String, value));
curCol++;
type = CellValueType.None;
// v => 单元格的值,如果单元格是字符串则v标签的值为该字符串在SST中的索引
// 将单元格内容加入rowlist中,在这之前先去掉字符串前后的空白符
} else if (VALUE.equals(name)) {
String value = lastContents.trim();
// value = "".equals(value) ? " " : value;
if (CellValueType.Date.equals(type)) {
Date date = HSSFDateUtil.getJavaDate(Double.valueOf(value));
rowList.add(curCol, new SaxReadCellEntity(CellValueType.Date, date));
} else if (CellValueType.Number.equals(type)) {
BigDecimal bd = new BigDecimal(value);
rowList.add(curCol, new SaxReadCellEntity(CellValueType.Number, bd));
} else if (CellValueType.String.equals(type) || CellValueType.InlineStr.equals(type)) {
rowList.add(curCol, new SaxReadCellEntity(CellValueType.String, value));
}
curCol++;
//如果标签名称为 row ,这说明已到行尾,调用 optRows() 方法
} else if (COL.equals(name) && StringUtils.isEmpty(lastContents)) {
if (name.equals(lastIndex)) { //如果与上次标签相同说明有空行
rowList.add(curCol, new SaxReadCellEntity(CellValueType.String, ""));
curCol++;
}
} else if (ROW.equals(name)) {
read.parse(curRow, rowList);
rowList.clear();
curRow++;
curCol = 0;
}}
private void addNullCell(String prevLocation, String currentLocation) {
// 拆分行和列
String[] prev = getRowCell(prevLocation);
String[] current = getRowCell(currentLocation);
if (prev[1].equalsIgnoreCase(current[1])) {
int prevCell = getCellNum(prev[0]) + 1;
int currentCell = getCellNum(current[0]);
for (int i = prevCell; i < currentCell; i++) {
rowList.add(curCol, new SaxReadCellEntity(CellValueType.String, ""));
curCol++;
}
}
}private int getCellNum(String cell) {
if (StringUtils.isEmpty(cell)) {
return 0;
}
char[] chars = cell.toUpperCase().toCharArray();
int n = 0;
for (int i = cell.length() - 1, j = 1; i >= 0; i--, j *= 26) {
char c = (chars[i]);
if (c < 'A' || c > 'Z') {
return 0;
}
n += ((int) c - 64) * j;
}
return n;
}private String[] getRowCell(String prevLocation) {
StringBuilder row = new StringBuilder();
StringBuilder cell = new StringBuilder();
char[] chars = prevLocation.toCharArray();
for (int i = 0; i < chars.length; i++) {
if (chars[i] >= '0' && chars[i] <= '9') {
cell.append(chars[i]);
} else {
row.append(chars[i]);
}
}
return new String[]{row.toString(), cell.toString()};
}@OverRide
public void characters(char[] ch, int start, int length) throws SAXException {
//得到单元格内容的值
lastContents += new String(ch, start, length);
}
}`
from easypoi.
Related Issues (20)
- 遇到变量名如iName这样第二个大写的,在导入excel的时候会报错
- excel表头字段如果是带下划线的比如 : (达标文案_en) , 然后excel就解析不了这个表头所对应的值 HOT 1
- PoiValidationUtil 自定义校验返回message字段名重复问题
- ExcelExportEntity 排序bug
- csv 文件导出没有那种¥或者%格式
- 大数据量导出ExcelBatchExportService 不支持 插入下拉列表
- 4.4.0版本excel导出图片失败,excel里没有图片显示,4.3.0版本可以正常导出图片 HOT 1
- 丢失数据&导出数据速度很慢
- When using sax import, fixedIndex will result in entity's property is null HOT 1
- cn.afterturn.easypoi.excel.imports.CellValueService#getValue 方法优化
- 复杂表头时列名映射错误
- easypoi-spring-boot-starter 导出图片,4.4.0无,4.2.0有
- 模板导出,个别合并单元格不合并
- excle导入数值,String接收精度丢失问题 HOT 1
- 老哥 ExcelImportService.importExcelByIs 这个地方有一个needMore的参数为true的时候异常的慢
- poi 3.0.3 使用 ExcelExportUtil.exportExcel 报错
- 老哥,替换占位符内容为ImageEntity类型的List时,不能使用 HOT 1
- 导出空集合,需要设置超过10的宽度,不然会报空指针
- ExcelExportOfTemplateUtil可能有内存泄漏风险
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from easypoi.