由于通过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. java⑥

    import java.util.Scanner; /** * 所有在java.lang包下面的所有类 不需要显示的引入包! * java.util.Scanner : 想获取用户的输入 必须引入相关 ...

  2. 稀疏 部分 Checkout

    To easily select only the items you want for the checkout and force the resulting working copy to ke ...

  3. GFS中文翻译

    Google文件系统 GFS是一个可扩展的分布式文件系统,用于大型的.分布式的.对大量数据进行访问的应用.它运行于廉价的普通硬件上,但可以提供容错功能.它可以给大量的用户提供总体性能较高的服务. 1. ...

  4. MicroOrm.Dapper.Repositories 的使用

    https://github.com/geffzhang/MicroOrm.Dapper.Repositories 1.特性标记都是要引用: System.ComponentModel.DataAnn ...

  5. Linux如何从零开始搭建rsync+serync服务器(centOS6)

    一.为什么要用Rsync+sersync架构? 1.sersync是基于Inotify开发的,类似于Inotify-tools的工具 2.sersync可以记录下被监听目录中发生变化的(包括增加.删除 ...

  6. tp配置

    <?php// +----------------------------------------------------------------------// | ThinkPHP [ WE ...

  7. mybatis column 和property

    mybatis map文件中 resultMap中column和sql查询结果对应, property和实体private对应 <resultMap id="VideoYcAppRes ...

  8. cxf http 代码自动生成

    1.下载 cxf 直接进入镜像下载http://mirrors.tuna.tsinghua.edu.cn/apache/cxf/3.1.12/apache-cxf-3.1.12.zip 2.配置 CX ...

  9. mybatis 插入空值时报错 TypeException

    报错内容:nested exception is org.apache.ibatis.type.TypeException: Could not set parameters for mapping: ...

  10. java学习笔记30(IO :缓冲流)

    缓冲流: 读取数据大量的文件时,读取的速度慢,java提供了一套缓冲流,提高IO流的效率: 缓冲流分为字节缓冲流和字符缓冲流: 字节输入缓冲流和字节输出缓冲流如下: package com.zs.De ...