由于通过new XSSFWorkbook 这种方式导入导致生产环境端口宕机、通过dump文件和javacore文件分析是导入功能导致的。
解决办法:自己通过网上写的工具类,不知道是否存在bug。

package com.yygx.impexptemplate.utils;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map; import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.xssf.eventusermodel.XSSFReader;
import org.apache.poi.xssf.eventusermodel.XSSFReader.SheetIterator;
import org.apache.poi.xssf.model.SharedStringsTable;
import org.apache.poi.xssf.usermodel.XSSFRichTextString;
import org.springframework.beans.factory.annotation.Autowired;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
import org.xml.sax.helpers.XMLReaderFactory; public class ExcelReaderParse extends DefaultHandler { private List<String> rowData = new ArrayList<String>();
private List<String[]> sheetData = new ArrayList<String[]>();
private Map<Integer, Object> map = new HashMap<Integer, Object>();
private String lastContents;
private SharedStringsTable sst;
private boolean nextIsString;
private Integer limit = 0;
// 定义前一个元素和当前元素的位置,用来计算其中空的单元格数量,如A6和A8等
private String preRef = null, ref = null;
// 定义该文档一行最大的单元格数,用来补全一行最后可能缺失的单元格
private String maxRef = null;
private int curRow = 0;
private int maxlimit = 0;
private List<String[]> sheetNames ; private int titleRow = 2; public int getSheetRow() {
return titleRow;
} public void setSheetRow(int sheetRow) {
this.titleRow = sheetRow;
} public List<String[]> getSheetNames() {
return sheetNames;
} public void setSheetNames(List<String[]> sheetNames) {
this.sheetNames = sheetNames;
} public Map<Integer, Object> getMap() {
return map;
} public void setMap(Map<Integer, Object> map) {
this.map = map;
} /**
* 读取所有工作簿的入口方法
*
* @param path
* @throws Exception
*/
@Autowired
public void process(InputStream inputStream) {
OPCPackage pkg = null;
InputStream sheet = null;
try {
pkg = OPCPackage.open(inputStream);
XSSFReader r = new XSSFReader(pkg);
SharedStringsTable sst = r.getSharedStringsTable(); XMLReader parser = fetchSheetParser(sst); // Iterator<InputStream> sheets = r.getSheetsData();
SheetIterator sheets = (SheetIterator) r.getSheetsData();
String sheetName = null;
int sheetNum = 0;
while (sheets.hasNext()) {
sheet = sheets.next();
if(sheetNum == 0){
sheetName = sheets.getSheetName();
}
InputSource sheetSource = new InputSource(sheet);
parser.parse(sheetSource);
sheet.close(); map.put(sheetNum, this.sheetData);
this.sheetData = new ArrayList<String[]>();
sheetNum++;
curRow = 0;
}
List<String[]> list = new ArrayList<String[]>();
list.add(new String[]{sheetName});
this.setSheetNames(list);
} catch (InvalidFormatException e) {
throw new RuntimeException(e.getMessage());
} catch (IOException e) {
throw new RuntimeException(e.getMessage());
} catch (OpenXML4JException e) {
throw new RuntimeException(e.getMessage());
} catch (SAXException e) {
throw new RuntimeException(e.getMessage());
} finally {
try {
pkg.close();
sheet.close();
} catch (IOException e) {
// TODO Auto-generated catch block
throw new RuntimeException(e.getMessage());
}
}
} /**
* 读取第一个工作簿的入口方法
*
* @param path
* @throws RuntimeException
*/
private void readOneSheet(String path) throws RuntimeException {
// TODO Auto-generated method stub
OPCPackage pkg = null;
InputStream sheet = null;
try {
pkg = OPCPackage.open(path);
XSSFReader r = new XSSFReader(pkg);
SharedStringsTable sst = r.getSharedStringsTable();
XMLReader parser = fetchSheetParser(sst);
sheet = r.getSheet("rId1");
InputSource sheetSource = new InputSource(sheet);
parser.parse(sheetSource);
map.put(0, this.sheetData);
this.sheetData.clear();
} catch (InvalidFormatException e) {
throw new RuntimeException(e.getMessage());
} catch (IOException e) {
throw new RuntimeException(e.getMessage());
} catch (OpenXML4JException e) {
throw new RuntimeException(e.getMessage());
} catch (SAXException e) {
throw new RuntimeException(e.getMessage());
} finally {
try {
pkg.close();
sheet.close();
} catch (IOException e) {
// TODO Auto-generated catch block
throw new RuntimeException(e.getMessage());
}
}
} private XMLReader fetchSheetParser(SharedStringsTable sst)
throws RuntimeException {
// TODO Auto-generated method stub
XMLReader parser;
try {
parser = XMLReaderFactory
.createXMLReader("org.apache.xerces.parsers.SAXParser");
this.sst = sst;
parser.setContentHandler(this);
return parser;
} catch (SAXException e) {
// TODO Auto-generated catch block
throw new RuntimeException(e.getMessage());
} } public void startElement(String uri, String localName, String name,
Attributes attributes) throws SAXException {
// c => 单元格
if (name.equals("c")) {
// 前一个单元格的位置
if (preRef == null) {
preRef = attributes.getValue("r");
} else {
preRef = ref;
}
// 当前单元格的位置
ref = attributes.getValue("r"); // 如果下一个元素是 SST 的索引,则将nextIsString标记为true
String cellType = attributes.getValue("t");
if (cellType != null && cellType.equals("s")) {
nextIsString = true;
} else {
nextIsString = false;
}
}
// 置空
lastContents = "";
} public void endElement(String uri, String localName, String name)
throws SAXException {
// 根据SST的索引值的到单元格的真正要存储的字符串
// 这时characters()方法可能会被调用多次
if (nextIsString) {
try {
int idx = Integer.parseInt(lastContents);
lastContents = new XSSFRichTextString(sst.getEntryAt(idx))
.toString();
nextIsString = false;
} catch (Exception e) {
e.printStackTrace();
}
} // v => 单元格的值,如果单元格是字符串则v标签的值为该字符串在SST中的索引
// 将单元格内容加入rowlist中,在这之前先去掉字符串前后的空白符
if (name.equals("v")) {
String value = lastContents.trim();
// if (value.equals("销售与客服支撑")) {
// System.out.println();
// } // 补全单元格之间的空单元格
if (!ref.equals(preRef)) {
int len = countNullCell(ref, preRef);
for (int i = 0; i < len; i++) {
rowData.add(limit, "");
limit++;
}
} else if (ref.equals(preRef) && limit == 0 && !ref.contains("A")) {
int len = letterToNum(ref);
for(int i=0;i<len-1;i++){
rowData.add(limit,"");
limit++;
}
} rowData.add(limit, value);
limit++;
} else if (name.equals("row")) {
// 如果标签名称为 row ,这说明已到行尾,调用 optRows() 方法
// System.out.println(rowData);
if(curRow == titleRow) {
maxlimit = limit;
}else if(curRow == 0) {
maxlimit = limit;
}
if (limit != maxlimit) {
int len = maxlimit - limit;
for (int i = 0; i < len; i++) {
rowData.add(limit, "");
limit++;
}
}
sheetData.add(rowData.toArray(new String[limit]));
rowData.clear();
limit = 0;
curRow++;
preRef = null;
ref = null;
}
} /**
* 计算两个单元格之间的单元格数目(同一行)
*
* @param ref
* @param preRef
* @return
*/
public int countNullCell(String ref, String preRef) {
// excel2007最大行数是1048576,最大列数是16384,最后一列列名是XFD
String xfd = ref.replaceAll("\\d+", "");
String xfd_1 = preRef.replaceAll("\\d+", ""); xfd = fillChar(xfd, 3, '@', true);
xfd_1 = fillChar(xfd_1, 3, '@', true); char[] letter = xfd.toCharArray();
char[] letter_1 = xfd_1.toCharArray();
int res = (letter[0] - letter_1[0]) * 26 * 26
+ (letter[1] - letter_1[1]) * 26 + (letter[2] - letter_1[2]);
return res - 1;
} /**
* 字符串的填充
*
* @param str
* @param len
* @param let
* @param isPre
* @return
*/
String fillChar(String str, int len, char let, boolean isPre) {
int len_1 = str.length();
if (len_1 < len) {
if (isPre) {
for (int i = 0; i < (len - len_1); i++) {
str = let + str;
}
} else {
for (int i = 0; i < (len - len_1); i++) {
str = str + let;
}
}
}
return str;
} public void characters(char[] ch, int start, int length)
throws SAXException {
// 得到单元格内容的值
lastContents += new String(ch, start, length);
} // 将字母转换成数字
public int letterToNum(String input) { StringBuffer sb = new StringBuffer();
for (int i = 0; i < input.length(); i++) {
char c = input.charAt(i);
if ((c <= 'z' && c >= 'a') || (c <= 'Z' && c >= 'A')) {
sb.append(c);
}
} StringBuilder builder = new StringBuilder();
for (byte b : sb.toString().toLowerCase().getBytes()) {
builder.append(b - 96);
}
return Integer.valueOf(builder.toString());
}
}

  

POI事件模型处理execl导入功能(只支持07版本的execl)的更多相关文章

  1. 让C# Excel导入导出,支持不同版本的Office

    问题:最近在项目中遇到,不同客户机安装不同Office版本,在导出Excel时,发生错误. 找不到Excel Com组件,错误信息如下. 未能加载文件或程序集“Microsoft.Office.Int ...

  2. JXL读取Excel(只支持xls版本)——(二)

    注意:jxl是不支持xlsx后缀的excel的.因此建议用POI读取excel. Jar包 同一一样 Java代码 package JXL; import java.io.File; import j ...

  3. 让C# Excel导入导出,支持不同版本的Office(转)

    问题:最近在项目中遇到,不同客户机安装不同Office版本,在导出Excel时,发生错误. 找不到Excel Com组件,错误信息如下. 未能加载文件或程序集“Microsoft.Office.Int ...

  4. JXL导出Excel(只支持xls版本)——(一)

    注意: 导出的后缀是xls可以直接打开,如果导出的后缀是xlsx打开报错,需要手动将名字改为xls才可以打开.也就是JXL不可以导出xlsx的excel. Jar包

  5. javascript 事件传播与事件冒泡,W3C事件模型

    说实话笔者在才工作的时候就听说了什么"事件冒泡",弄了很久才弄个大概,当时理解意思是子级dom元素和父级dom元素都绑定了相同类型的事件,这时如果子级事件触发了父级也会触发,然后这 ...

  6. [JS学习笔记]浅谈Javascript事件模型

    DOM0级事件模型 element.on[type] = function(){} 兼容性:全部支持   lay1 lay2 lay3 e.target:直接触发事件的元素[IE8及以下不支持tage ...

  7. 同时绑定onpropertychange 和 oninput 事件,实时检测 input、textarea输入改变事件,支持低版本IE,支持复制粘贴

    实时检测 input.textarea输入改变事件,支持低版本IE,支持复制粘贴 检测input.textarea输入改变事件有以下几种: 1.onkeyup/onkeydown 捕获用户键盘输入事件 ...

  8. java中poi解析excel(兼容07版本以上及以下:.xls和.xlsx格式)

    package com.genersoft.cbms.ysbz.ExcelDr.cmd; import com.genersoft.cbms.ysbz.ExcelDr.dao.ExcelDrDao; ...

  9. ExtJS框架基础:事件模型及其常用功能

    前言 工作中用ExtJS有一段时间了,Ext丰富的UI组件大大的提高了开发B/S应用的效率.虽然近期工作中天天都用到ExtJS,但很少对ExtJS框架原理性的东西进行过深入学习,这两天花了些时间学习了 ...

随机推荐

  1. OOP⑵

    1.问题? 怎么创建对象? 类名 对象名=new 类名(); 在java中只要是看到了()! 这就是方法! 2.构造方法: 创建某个对象的方法! Student stu=new Student(); ...

  2. java 实现简单循环队列

    package www.queue; import java.util.Arrays; /** * 循环队列: * 循环队列的出现是为了解决顺序队列出队列后,首指针向后移动后前面的存储过程浪费不能使用 ...

  3. 《Python》模块和包

    一.模块 1.什么是模块: 一个模块就是一个包含了Python定义和声明的文件,文件名就是模块名字加上.py的后缀. 但其实import加载的模块分为四个通用类别: 1.使用Python编写的代码(. ...

  4. CSS特性

    css的特性 css具有两大特性:继承性和层叠性 1.继承性 指的是子元素继承父元素的样式,但没有所有的样式都可以继承(那样就太可怕了) 所以具有继承性的属性主要分为三大类 a.文本属性 font-s ...

  5. 实力封装:Unity打包AssetBundle(番外篇)

    前情提要:第二种打包方式. 自定义AssetBundle包扩展名 在之前的教程中,我们已经多次提到过扩展名了,并且也已经说明了如何设置自定义的AssetBundle扩展名.至于为什么还要把它单独拿出来 ...

  6. 进阶ES6 点滴认知

    1.let--不允许重复声明 根据http://es6.ruanyifeng.com/#docs/let 的例子,我竟然 报格式错误 说实话,我也没见过函数这样的写法......然后我就随意加了函数名 ...

  7. mac下python2.7升级到3.6

    1. 前言 Mac系统自带python2.7,本文目的是将自带的python升级到3.6版本. 网上有本多的做法是让python2.7和python3.X两个版本共存,博主并不知道,是两版本共存好,还 ...

  8. mysql增删改查练习

    Mysql增删改查sql语句练习 关于数据库的一些操作: 进入mysql 命令行: mysql -uroot –p 查看所有数据库: show databases; 创建数据库: create dat ...

  9. Python 内置函数2

    print(list("胡辣汤")) lst = ["河南话", "四川话", "东北", "山东" ...

  10. SQL注入之Sqli-labs系列第二十五关(过滤 OR & AND)和第二十五A关(过滤逻辑运算符注释符)

    开始挑战第二十五关(Trick with OR & AND) 第二十五关A(Trick with comments) 0x1先查看源码 (1)这里的or和and采用了i正则匹配,大小写都无法绕 ...