我有一个巨大的 Excel 文件,我正在尝试使用 JAVA 中的 SAX 解析器对其进行解析。我主要使用 Apache POI 库并处理 .XLSX 文件。以下是我正在尝试读取的 /xl/worksheets/sheet1.xml
压缩 excel 文件夹中 xml 内容的外观:
<row r="1">
<c r="A1" t="inlineStr"><is><t>my value 1</t></is></c>
<c r="B1" t="inlineStr"><is><t>my value 2</t></is></c>
<c r="C1" t="inlineStr"><is><t>my value 3</t></is></c>
</row>
这个特定的 Excel 文件正在使用内联字符串值,如上所示。
这是我的函数,它执行程序来读取文件:
public void executeExcelDataExtraction() throws IOException, OpenXML4JException, SAXException, ParserConfigurationException, XMLStreamException, FactoryConfigurationError {
OPCPackage pkg = OPCPackage.open(XLSX_INPUT_FILE.xlsx);
XSSFReader r = new XSSFReader( pkg );
SharedStringsTable sst = r.getSharedStringsTable();
ImportArticleDataProcessorExcelFileReaderFactory handlerFactory = new
ImportArticleDataProcessorExcelFileReaderFactory(sst);
XMLReader parser = fetchSheetParser(handlerFactory);
Iterator<InputStream> sheets = r.getSheetsData();
if (sheets instanceof XSSFReader.SheetIterator) {
XSSFReader.SheetIterator sheetiterator =
(XSSFReader.SheetIterator)sheets;
while(sheetiterator.hasNext()) {
System.out.println("Processing new sheet:\n");
InputStream sheet = sheets.next();
InputSource sheetSource = new InputSource(sheet);
parser.parse(sheetSource);
rowCache = handlerFactory.getRowCache();
sheet.close();
pkg.close();
if(!rowCache.isEmpty())
createCategoryMap(rowCache);
}
}
}
这是我的工作表处理程序工厂类,用于上面的函数。
import java.util.LinkedList;
import java.util.List;
import org.xml.sax.Attributes;
import org.apache.poi.xssf.model.SharedStringsTable;
import org.apache.poi.xssf.usermodel.XSSFRichTextString;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class ImportArticleDataProcessorExcelFileReaderFactory extends DefaultHandler{
private static final String ROW_EVENT = "row";
private static final String CELL_EVENT = "c";
private SharedStringsTable sst;
private String lastContents;
private boolean nextIsString;
private List<String> cellCache = new LinkedList<>();
private List<String[]> rowCache = new LinkedList<>();
ImportArticleDataProcessorExcelFileReaderFactory(SharedStringsTable sst) {
this.sst = sst;
}
public void startElement(String uri, String localName, String name,
Attributes attributes) throws SAXException {
// c => cell
if (CELL_EVENT.equals(name)) {
String cellType = attributes.getValue("t");
if(cellType != null && cellType.equals("s")) {
nextIsString = true;
} else {
nextIsString = false;
}
} else if (ROW_EVENT.equals(name)) {
if (!cellCache.isEmpty()) {
rowCache.add(cellCache.toArray(new String[cellCache.size()]));
}
cellCache.clear();
}
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();
nextIsString = false;
}
// v => contents of a cell
// Output after we've seen the string contents
if(name.equals("v")) {
cellCache.add(lastContents.trim());
}
}
public void characters(char[] ch, int start, int length)
throws SAXException {
lastContents += new String(ch, start, length);
}
public List<String[]> getRowCache() {
return rowCache;
}
}
所有其他不具有内联字符串的 Excel 文件都能够成功读取,但是对于内部具有内联字符串的文件,该算法仅读取 cellType=inlineStr
但永远不会获取正确的值。
我想要什么:
我想要的只是打印位于内联字符串单元格内的值,例如就我而言,它是“我的值(value) 1”、“我的值(value) 2”和“我的值(value) 3”
最佳答案
如果有人正在寻找类似的解决方案,只是想让您知道我已经通过在上面的 ImportArticleDataProcessorExcelFileReaderFactory
类中添加以下几行来解决它:
public void startElement(String uri, String localName, String name){
// rest of the code...
inlineStr = false;
if(cellType != null && cellType.equals("inlineStr")) {
inlineStr = true;
}
...
}
public void endElement(String uri, String localName, String name){
// rest of the code...
if(name.equals("t") && inlineStr) {
cellCache.add(lastContents.trim());
}
...
}
上述工厂类中的 void strings
函数正确识别单元格的内容,并且我的答案中给出的更改成功使用内联字符串单元格中的所有值填充 cellCache
列表.
请引用上面评论中@Axel的答案,并按照此答案获取来源:How to check a number in a string contains a date and exponential numbers while parsing excel file using apache event model in java
关于java - 在 Java 中使用 SAX 解析检测 'Inline String' 单元格值时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56597082/