当前位置:编程学习 > JAVA >>

poi sax方式读取execl

因为项目需要 导入14W行 100多列的数据 所以改用 poi sax方式解析execl

大家都知道 execl2007 后缀名修改成。zip  就可以看 sheet1.xml





这个execl   我要读取.  但是读取的时候 中间的 B1  读不到. 

我想要的结果 List 中 第2个元素应该是 空字符串 结果 现在是 C1的内容 22 

正确的集合内容应该为 : 11   “”  22   22  333  “” 11

读取后的为 : 11  22  22  333  11


于是我看了一下 sheet1.xml文件




xml中根本没有  B1  F1的标签.  我该如何解决这个问题. 达到我想要的结果! 求助!


--------------------编程问答-------------------- 顶一下..... 着急 在线等大神 --------------------编程问答-------------------- poi之所以没有那个标签是因为那个列上没值。其实楼主只要用row.getLastCellNum();这个就是获取最后一列的序号也就是当前行的列数就是xml里面row的span里面的那个1:7的1代表行,7代表列数
。楼主只要用for循环row.getLastCellNum();就可以了没有列的就是空值 --------------------编程问答--------------------
引用 2 楼 suciver 的回复:
poi之所以没有那个标签是因为那个列上没值。其实楼主只要用row.getLastCellNum();这个就是获取最后一列的序号也就是当前行的列数就是xml里面row的span里面的那个1:7的1代表行,7代表列数
。楼主只要用for循环row.getLastCellNum();就可以了没有列的就是空值


你好. 我看见了.  但是我这个没有row 我用的解析是 

public XMLReader fetchSheetParser(SharedStringsTable sst) throws SAXException {
XMLReader parser =
XMLReaderFactory.createXMLReader(
"org.apache.xerces.parsers.SAXParser"
);
ContentHandler handler = new SheetHandler(sst);
parser.setContentHandler(handler);
return parser;
}

/** 
 * See org.xml.sax.helpers.DefaultHandler javadocs 
 */
private static class SheetHandler extends DefaultHandler {
private SharedStringsTable sst;
private String lastContents;
private boolean nextIsString;

private SheetHandler(SharedStringsTable sst) {
this.sst = sst;
}

public void startElement(String uri, String localName, String name,
Attributes attributes) throws SAXException {
// c => cell
if(name.equals("c")) {
// Print the cell reference
System.out.print(attributes.getValue("r") + " - ");
// Figure out if the value is an index in the SS
String cellType = attributes.getValue("t");
if(cellType != null && cellType.equals("s")) {
nextIsString = true;
} else {
nextIsString = false;
}
}
// Clear contents cache
lastContents = "";
}

public void endElement(String uri, String localName, String name)
throws SAXException {
// Process the last contents as required.
// Do now, as characters() may be called more than once

if(nextIsString) {
int idx = Integer.parseInt(lastContents);
lastContents = new XSSFRichTextString(sst.getEntryAt(idx)).toString();
}

// v => contents of a cell
// Output after we've seen the string contents
if(name.equals("v")) {
System.out.println(lastContents);
nextIsString=false;
}
}


没有row对象 我知道  是7列. 但是我不知道 哪个中间有 空单元格 .  --------------------编程问答--------------------
引用 3 楼 q826qq1878 的回复:
没有row对象 我知道  是7列. 但是我不知道 哪个中间有 空单元格 . 

刚才我说了spans里面的1:7就是行号和列数,根据这一特点解析row的spans属性获得列数楼主可以用个List<String> list=new LinkedList<String>();用于记录列该有的标题即row中c元素的r属性,例如spans的列数为7行号为1的那么list的值就是["A1","B1","C1","D1","E1","F1","G1"]。
例如spans的列数为7行号为2的那么list的值就是["A2","B2","C2","D2","E2","F2","G2"]
楼主到这里应该有头绪了吧
楼主可以在你的代码里面的startElement事件里面加入
if(name.equals("row")){//解析row节点的spans属性
  String[] spans=attributes.getValue("spans").spilt(":");
  String rowNum=spans[0];//行号
  int cellNum=spans[1];//列数
  list.clear();//每次记入时先把list清空下由于频繁的删改所以用LinkedList
//把他们放入list中,后面你name.equals("c")解析到列的时候只要根据这个list就知道哪个列少了
  for(int i=0;i<cellNum;i++){
     list.add((char)('A'+i)+rowNum);
  }
} --------------------编程问答--------------------
引用 4 楼 suciver 的回复:
Quote: 引用 3 楼 q826qq1878 的回复:


没有row对象 我知道  是7列. 但是我不知道 哪个中间有 空单元格 . 

刚才我说了spans里面的1:7就是行号和列数,根据这一特点解析row的spans属性获得列数楼主可以用个List<String> list=new LinkedList<String>();用于记录列该有的标题即row中c元素的r属性,例如spans的列数为7行号为1的那么list的值就是["A1","B1","C1","D1","E1","F1","G1"]。
例如spans的列数为7行号为2的那么list的值就是["A2","B2","C2","D2","E2","F2","G2"]
楼主到这里应该有头绪了吧
楼主可以在你的代码里面的startElement事件里面加入
if(name.equals("row")){//解析row节点的spans属性
  String[] spans=attributes.getValue("spans").spilt(":");
  String rowNum=spans[0];//行号
  int cellNum=spans[1];//列数
  list.clear();//每次记入时先把list清空下由于频繁的删改所以用LinkedList
//把他们放入list中,后面你name.equals("c")解析到列的时候只要根据这个list就知道哪个列少了
  for(int i=0;i<cellNum;i++){
     list.add((char)('A'+i)+rowNum);
  }
}


我看见你的第一次回复我就知道可以这么弄了. 但是- - .. 我这113行. 我觉得太麻烦了. ..我先去试试吧 实在没有办法了 --------------------编程问答--------------------
引用 5 楼 q826qq1878 的回复:
我看见你的第一次回复我就知道可以这么弄了. 但是- - .. 我这113行. 我觉得太麻烦了. ..我先去试试吧 实在没有办法了

跟你有多少行有什么关系又不是你一行写一次代码直接startElement里面写上代码通用的 --------------------编程问答--------------------
引用 6 楼 suciver 的回复:
Quote: 引用 5 楼 q826qq1878 的回复:

我看见你的第一次回复我就知道可以这么弄了. 但是- - .. 我这113行. 我觉得太麻烦了. ..我先去试试吧 实在没有办法了

跟你有多少行有什么关系又不是你一行写一次代码直接startElement里面写上代码通用的


我说错了 我是113列.  --------------------编程问答--------------------
引用 7 楼 q826qq1878 的回复:
Quote: 引用 6 楼 suciver 的回复:

Quote: 引用 5 楼 q826qq1878 的回复:

我看见你的第一次回复我就知道可以这么弄了. 但是- - .. 我这113行. 我觉得太麻烦了. ..我先去试试吧 实在没有办法了

跟你有多少行有什么关系又不是你一行写一次代码直接startElement里面写上代码通用的


我说错了 我是113列. 

管你多少列代码是通用的for循环里面做了又不叫你自己手写113次。你这个excel也太变态了113列有哪个excel一行有113列的看都看不过来了 --------------------编程问答--------------------
引用 8 楼 suciver 的回复:
Quote: 引用 7 楼 q826qq1878 的回复:

Quote: 引用 6 楼 suciver 的回复:

Quote: 引用 5 楼 q826qq1878 的回复:

我看见你的第一次回复我就知道可以这么弄了. 但是- - .. 我这113行. 我觉得太麻烦了. ..我先去试试吧 实在没有办法了

跟你有多少行有什么关系又不是你一行写一次代码直接startElement里面写上代码通用的


我说错了 我是113列. 

管你多少列代码是通用的for循环里面做了又不叫你自己手写113次。你这个excel也太变态了113列有哪个excel一行有113列的看都看不过来了


周五没怎么弄 脑袋大了. 现在正在弄呢.  113列 14W的数据.. 太恶心了. 
补充:Java ,  Java SE
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,