POI API 的事件模型是否在 3.15 版本中不适用(出现编译错误)?
Is Event model of POI API not applicable(getting compilation error) in version 3.15?
我已经实现了一个程序,我尝试使用 SAX 和 XSSF(POI API) 以及 jar 版本 4.1 读取 excel 文件 (.xlsx),它工作正常。
但是它在 POI 3.15 版本中给出了编译错误。
代码看起来像这样(在 4.10 中运行良好):
默认处理程序实现(SAXExcelSheetHandler.java):
import org.apache.poi.xssf.model.SharedStringsTable;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class SAXExcelSheetHandler extends DefaultHandler {
private SharedStringsTable sst;
private String lastContents;
private boolean nextIsString;
public SAXExcelSheetHandler(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 SST
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 = sst.getItemAt(idx).getString();
nextIsString = false;
}
// v => contents of a cell
// Output after we've seen the string contents
if(name.equals("v")) {
System.out.println(lastContents);
}
}
public void characters(char[] ch, int start, int length) {
lastContents += new String(ch, start, length);
}
}
实际驱动程序 Class(POISaxXaafV2.java):
import java.io.File;
import java.io.InputStream;
import java.util.Iterator;
import org.apache.poi.ooxml.util.SAXHelper;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.xssf.eventusermodel.XSSFReader;
import org.apache.poi.xssf.model.SharedStringsTable;
import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;
public class POISaxXaafV2 {
public static void main(String[] args) throws Exception {
String fullFilePath = "E:\Downloads\6038_Open_AR.XLSX";
File file = new File(fullFilePath);
OPCPackage opcPackage = OPCPackage.open(file);
XSSFReader xssfReader = new XSSFReader(opcPackage);
SharedStringsTable sharedStringsTable = xssfReader.getSharedStringsTable();
XMLReader xmlParser = SAXHelper.newXMLReader();
ContentHandler contentHandler = new SAXExcelSheetHandler(sharedStringsTable);
xmlParser.setContentHandler(contentHandler);
Iterator<InputStream> sheetsIterator = xssfReader.getSheetsData();
while(sheetsIterator.hasNext()) {
System.out.println("Processing new sheet:\n");
InputStream sheet = sheetsIterator.next();
InputSource sheetSource = new InputSource(sheet);
xmlParser.parse(sheetSource);
sheet.close();
System.out.println("");
}
}
}
目前一切顺利,运行良好。
现在我尝试在我的工作场所实施此操作,他们使用的是 3.15 版本的 POI 而不是 4.1.0。唉,我遇到了编译错误
第一次编译错误:
在默认处理程序实现中 class:SAXExcelSheetHandler.java
第 39 行:
lastContents = sst.getItemAt(idx).getString();
它说
The method getItemAt(int) is undefined for the type SharedStringsTable
第二次编译错误
这在驱动程序中 class : POISaxXaafV2.java
在第 4 行:
import org.apache.poi.ooxml.util.SAXHelper
它说:
The import org.apache.poi.ooxml cannot be resolved
由于上述错误,最终我在第 22 行再次出现编译错误:
XMLReader xmlParser = SAXHelper.newXMLReader();
因为导入失败:
SAXHelper cannot be resolved
对于 3.15 版,这是否需要与我在 4.10 中编写的不同?
请帮忙。
正如评论中所说,请不要坚持使用过时的软件版本。这样做不是我们在软件开发方面取得进步的方式。
当然,XSSF and SAX (Event API)
版本 3.15
也存在。
但是在这个旧版本SharedStringsTable
中没有方法getItemAt
。它只有 getEntryAt
个 return 个 org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRst
。因此 class SAXExcelSheetHandler
中的代码必须更改为:
...
import org.apache.poi.xssf.usermodel.XSSFRichTextString;
...
...
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 = sst.getItemAt(idx).getString();
lastContents = new XSSFRichTextString(sst.getEntryAt(idx)).toString();
nextIsString = false;
}
// v => contents of a cell
// Output after we've seen the string contents
if(name.equals("v")) {
System.out.println(lastContents);
}
}
...
还没有SAXHelper
。因此 class POISaxXaafV2
的代码必须更改为:
...
import java.io.File;
import java.io.InputStream;
import java.util.Iterator;
//import org.apache.poi.ooxml.util.SAXHelper;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.xssf.eventusermodel.XSSFReader;
import org.apache.poi.xssf.model.SharedStringsTable;
import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.parsers.SAXParser;
...
...
OPCPackage opcPackage = OPCPackage.open(file);
XSSFReader xssfReader = new XSSFReader(opcPackage);
SharedStringsTable sharedStringsTable = xssfReader.getSharedStringsTable();
//XMLReader xmlParser = SAXHelper.newXMLReader();
SAXParserFactory parserFactory = SAXParserFactory.newInstance();
SAXParser parser = parserFactory.newSAXParser();
XMLReader xmlParser = parser.getXMLReader();
ContentHandler contentHandler = new SAXExcelSheetHandler(sharedStringsTable);
xmlParser.setContentHandler(contentHandler);
...
我已经实现了一个程序,我尝试使用 SAX 和 XSSF(POI API) 以及 jar 版本 4.1 读取 excel 文件 (.xlsx),它工作正常。 但是它在 POI 3.15 版本中给出了编译错误。
代码看起来像这样(在 4.10 中运行良好):
默认处理程序实现(SAXExcelSheetHandler.java):
import org.apache.poi.xssf.model.SharedStringsTable;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class SAXExcelSheetHandler extends DefaultHandler {
private SharedStringsTable sst;
private String lastContents;
private boolean nextIsString;
public SAXExcelSheetHandler(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 SST
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 = sst.getItemAt(idx).getString();
nextIsString = false;
}
// v => contents of a cell
// Output after we've seen the string contents
if(name.equals("v")) {
System.out.println(lastContents);
}
}
public void characters(char[] ch, int start, int length) {
lastContents += new String(ch, start, length);
}
}
实际驱动程序 Class(POISaxXaafV2.java):
import java.io.File;
import java.io.InputStream;
import java.util.Iterator;
import org.apache.poi.ooxml.util.SAXHelper;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.xssf.eventusermodel.XSSFReader;
import org.apache.poi.xssf.model.SharedStringsTable;
import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;
public class POISaxXaafV2 {
public static void main(String[] args) throws Exception {
String fullFilePath = "E:\Downloads\6038_Open_AR.XLSX";
File file = new File(fullFilePath);
OPCPackage opcPackage = OPCPackage.open(file);
XSSFReader xssfReader = new XSSFReader(opcPackage);
SharedStringsTable sharedStringsTable = xssfReader.getSharedStringsTable();
XMLReader xmlParser = SAXHelper.newXMLReader();
ContentHandler contentHandler = new SAXExcelSheetHandler(sharedStringsTable);
xmlParser.setContentHandler(contentHandler);
Iterator<InputStream> sheetsIterator = xssfReader.getSheetsData();
while(sheetsIterator.hasNext()) {
System.out.println("Processing new sheet:\n");
InputStream sheet = sheetsIterator.next();
InputSource sheetSource = new InputSource(sheet);
xmlParser.parse(sheetSource);
sheet.close();
System.out.println("");
}
}
}
目前一切顺利,运行良好。
现在我尝试在我的工作场所实施此操作,他们使用的是 3.15 版本的 POI 而不是 4.1.0。唉,我遇到了编译错误
第一次编译错误:
在默认处理程序实现中 class:SAXExcelSheetHandler.java
第 39 行:
lastContents = sst.getItemAt(idx).getString();
它说
The method getItemAt(int) is undefined for the type SharedStringsTable
第二次编译错误
这在驱动程序中 class : POISaxXaafV2.java
在第 4 行:
import org.apache.poi.ooxml.util.SAXHelper
它说:
The import org.apache.poi.ooxml cannot be resolved
由于上述错误,最终我在第 22 行再次出现编译错误:
XMLReader xmlParser = SAXHelper.newXMLReader();
因为导入失败:
SAXHelper cannot be resolved
对于 3.15 版,这是否需要与我在 4.10 中编写的不同?
请帮忙。
正如评论中所说,请不要坚持使用过时的软件版本。这样做不是我们在软件开发方面取得进步的方式。
当然,XSSF and SAX (Event API)
版本 3.15
也存在。
但是在这个旧版本SharedStringsTable
中没有方法getItemAt
。它只有 getEntryAt
个 return 个 org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRst
。因此 class SAXExcelSheetHandler
中的代码必须更改为:
...
import org.apache.poi.xssf.usermodel.XSSFRichTextString;
...
...
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 = sst.getItemAt(idx).getString();
lastContents = new XSSFRichTextString(sst.getEntryAt(idx)).toString();
nextIsString = false;
}
// v => contents of a cell
// Output after we've seen the string contents
if(name.equals("v")) {
System.out.println(lastContents);
}
}
...
还没有SAXHelper
。因此 class POISaxXaafV2
的代码必须更改为:
...
import java.io.File;
import java.io.InputStream;
import java.util.Iterator;
//import org.apache.poi.ooxml.util.SAXHelper;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.xssf.eventusermodel.XSSFReader;
import org.apache.poi.xssf.model.SharedStringsTable;
import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.parsers.SAXParser;
...
...
OPCPackage opcPackage = OPCPackage.open(file);
XSSFReader xssfReader = new XSSFReader(opcPackage);
SharedStringsTable sharedStringsTable = xssfReader.getSharedStringsTable();
//XMLReader xmlParser = SAXHelper.newXMLReader();
SAXParserFactory parserFactory = SAXParserFactory.newInstance();
SAXParser parser = parserFactory.newSAXParser();
XMLReader xmlParser = parser.getXMLReader();
ContentHandler contentHandler = new SAXExcelSheetHandler(sharedStringsTable);
xmlParser.setContentHandler(contentHandler);
...