mirror of https://github.com/apache/poi.git
[bug-65096] XLSX Streaming XML not correctly reading multiple inline Strings
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1885770 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
4a632f9389
commit
4013ffa220
|
@ -204,7 +204,9 @@ public class XSSFSheetXMLHandler extends DefaultHandler {
|
||||||
if (isTextTag(localName)) {
|
if (isTextTag(localName)) {
|
||||||
vIsOpen = true;
|
vIsOpen = true;
|
||||||
// Clear contents cache
|
// Clear contents cache
|
||||||
|
if (!isIsOpen) {
|
||||||
value.setLength(0);
|
value.setLength(0);
|
||||||
|
}
|
||||||
} else if ("is".equals(localName)) {
|
} else if ("is".equals(localName)) {
|
||||||
// Inline string outer tag
|
// Inline string outer tag
|
||||||
isIsOpen = true;
|
isIsOpen = true;
|
||||||
|
@ -307,12 +309,68 @@ public class XSSFSheetXMLHandler extends DefaultHandler {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
String thisStr = null;
|
|
||||||
|
|
||||||
// v => contents of a cell
|
// v => contents of a cell
|
||||||
if (isTextTag(localName)) {
|
if (isTextTag(localName)) {
|
||||||
vIsOpen = false;
|
vIsOpen = false;
|
||||||
|
|
||||||
|
if (!isIsOpen) {
|
||||||
|
outputCell();
|
||||||
|
}
|
||||||
|
} else if ("f".equals(localName)) {
|
||||||
|
fIsOpen = false;
|
||||||
|
} else if ("is".equals(localName)) {
|
||||||
|
isIsOpen = false;
|
||||||
|
outputCell();
|
||||||
|
value.setLength(0);
|
||||||
|
} else if ("row".equals(localName)) {
|
||||||
|
// Handle any "missing" cells which had comments attached
|
||||||
|
checkForEmptyCellComments(EmptyCellCommentsCheckType.END_OF_ROW);
|
||||||
|
|
||||||
|
// Finish up the row
|
||||||
|
output.endRow(rowNum);
|
||||||
|
|
||||||
|
// some sheets do not have rowNum set in the XML, Excel can read them so we should try to read them as well
|
||||||
|
nextRowNum = rowNum + 1;
|
||||||
|
} else if ("sheetData".equals(localName)) {
|
||||||
|
// Handle any "missing" cells which had comments attached
|
||||||
|
checkForEmptyCellComments(EmptyCellCommentsCheckType.END_OF_SHEET_DATA);
|
||||||
|
|
||||||
|
// indicate that this sheet is now done
|
||||||
|
output.endSheet();
|
||||||
|
}
|
||||||
|
else if("oddHeader".equals(localName) || "evenHeader".equals(localName) ||
|
||||||
|
"firstHeader".equals(localName)) {
|
||||||
|
hfIsOpen = false;
|
||||||
|
output.headerFooter(headerFooter.toString(), true, localName);
|
||||||
|
}
|
||||||
|
else if("oddFooter".equals(localName) || "evenFooter".equals(localName) ||
|
||||||
|
"firstFooter".equals(localName)) {
|
||||||
|
hfIsOpen = false;
|
||||||
|
output.headerFooter(headerFooter.toString(), false, localName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Captures characters only if a suitable element is open.
|
||||||
|
* Originally was just "v"; extended for inlineStr also.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void characters(char[] ch, int start, int length)
|
||||||
|
throws SAXException {
|
||||||
|
if (vIsOpen) {
|
||||||
|
value.append(ch, start, length);
|
||||||
|
}
|
||||||
|
if (fIsOpen) {
|
||||||
|
formula.append(ch, start, length);
|
||||||
|
}
|
||||||
|
if (hfIsOpen) {
|
||||||
|
headerFooter.append(ch, start, length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void outputCell() {
|
||||||
|
String thisStr = null;
|
||||||
|
|
||||||
// Process the value contents as required, now we have it all
|
// Process the value contents as required, now we have it all
|
||||||
switch (nextDataType) {
|
switch (nextDataType) {
|
||||||
case BOOLEAN:
|
case BOOLEAN:
|
||||||
|
@ -383,54 +441,6 @@ public class XSSFSheetXMLHandler extends DefaultHandler {
|
||||||
|
|
||||||
// Output
|
// Output
|
||||||
output.cell(cellRef, thisStr, comment);
|
output.cell(cellRef, thisStr, comment);
|
||||||
} else if ("f".equals(localName)) {
|
|
||||||
fIsOpen = false;
|
|
||||||
} else if ("is".equals(localName)) {
|
|
||||||
isIsOpen = false;
|
|
||||||
} else if ("row".equals(localName)) {
|
|
||||||
// Handle any "missing" cells which had comments attached
|
|
||||||
checkForEmptyCellComments(EmptyCellCommentsCheckType.END_OF_ROW);
|
|
||||||
|
|
||||||
// Finish up the row
|
|
||||||
output.endRow(rowNum);
|
|
||||||
|
|
||||||
// some sheets do not have rowNum set in the XML, Excel can read them so we should try to read them as well
|
|
||||||
nextRowNum = rowNum + 1;
|
|
||||||
} else if ("sheetData".equals(localName)) {
|
|
||||||
// Handle any "missing" cells which had comments attached
|
|
||||||
checkForEmptyCellComments(EmptyCellCommentsCheckType.END_OF_SHEET_DATA);
|
|
||||||
|
|
||||||
// indicate that this sheet is now done
|
|
||||||
output.endSheet();
|
|
||||||
}
|
|
||||||
else if("oddHeader".equals(localName) || "evenHeader".equals(localName) ||
|
|
||||||
"firstHeader".equals(localName)) {
|
|
||||||
hfIsOpen = false;
|
|
||||||
output.headerFooter(headerFooter.toString(), true, localName);
|
|
||||||
}
|
|
||||||
else if("oddFooter".equals(localName) || "evenFooter".equals(localName) ||
|
|
||||||
"firstFooter".equals(localName)) {
|
|
||||||
hfIsOpen = false;
|
|
||||||
output.headerFooter(headerFooter.toString(), false, localName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Captures characters only if a suitable element is open.
|
|
||||||
* Originally was just "v"; extended for inlineStr also.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void characters(char[] ch, int start, int length)
|
|
||||||
throws SAXException {
|
|
||||||
if (vIsOpen) {
|
|
||||||
value.append(ch, start, length);
|
|
||||||
}
|
|
||||||
if (fIsOpen) {
|
|
||||||
formula.append(ch, start, length);
|
|
||||||
}
|
|
||||||
if (hfIsOpen) {
|
|
||||||
headerFooter.append(ch, start, length);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
package org.apache.poi.xssf.eventusermodel;
|
||||||
|
|
||||||
|
import org.apache.poi.POIDataSamples;
|
||||||
|
import org.apache.poi.openxml4j.opc.OPCPackage;
|
||||||
|
import org.apache.poi.util.XMLHelper;
|
||||||
|
import org.apache.poi.xssf.eventusermodel.XSSFSheetXMLHandler.SheetContentsHandler;
|
||||||
|
import org.apache.poi.xssf.usermodel.XSSFComment;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.xml.sax.InputSource;
|
||||||
|
import org.xml.sax.XMLReader;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
public class TestXSSFSheetXMLHandler {
|
||||||
|
private static final POIDataSamples _ssTests = POIDataSamples.getSpreadSheetInstance();
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testInlineString() throws Exception {
|
||||||
|
try (OPCPackage xlsxPackage = OPCPackage.open(_ssTests.openResourceAsStream("InlineString.xlsx"))) {
|
||||||
|
final XSSFReader reader = new XSSFReader(xlsxPackage);
|
||||||
|
|
||||||
|
final Iterator<InputStream> iter = reader.getSheetsData();
|
||||||
|
|
||||||
|
try (InputStream stream = iter.next()) {
|
||||||
|
final XMLReader sheetParser = XMLHelper.getSaxParserFactory().newSAXParser().getXMLReader();
|
||||||
|
|
||||||
|
sheetParser.setContentHandler(new XSSFSheetXMLHandler(reader.getStylesTable(),
|
||||||
|
new ReadOnlySharedStringsTable(xlsxPackage), new SheetContentsHandler() {
|
||||||
|
|
||||||
|
int cellCount = 0;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void startRow(final int rowNum) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void endRow(final int rowNum) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cell(final String cellReference, final String formattedValue,
|
||||||
|
final XSSFComment comment) {
|
||||||
|
assertEquals("\uD83D\uDE1Cmore text", formattedValue);
|
||||||
|
assertEquals(cellCount++, 0);
|
||||||
|
}
|
||||||
|
}, false));
|
||||||
|
|
||||||
|
sheetParser.parse(new InputSource(stream));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
Loading…
Reference in New Issue