You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

350 lines
13 KiB

package com.alibaba.excel.analysis.v07.usermodel;
import org.apache.poi.ooxml.POIXMLException;
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.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.PackagePartName;
import org.apache.poi.openxml4j.opc.PackageRelationship;
import org.apache.poi.openxml4j.opc.PackageRelationshipCollection;
import org.apache.poi.openxml4j.opc.PackagingURIHelper;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
import org.apache.poi.util.XMLHelper;
import org.apache.poi.xssf.model.CommentsTable;
import org.apache.poi.xssf.model.SharedStringsTable;
import org.apache.poi.xssf.model.StylesTable;
import org.apache.poi.xssf.model.ThemesTable;
import org.apache.poi.xssf.usermodel.XSSFDrawing;
import org.apache.poi.xssf.usermodel.XSSFRelation;
import org.apache.poi.xssf.usermodel.XSSFShape;
import org.apache.xmlbeans.XmlException;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.STSheetState;
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 javax.xml.parsers.ParserConfigurationException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* @see org.apache.poi.xssf.eventusermodel.XSSFReader
* @author lucian
*/
public class FineXssfReader {
private static final String RELATIONSHIP_TYPE_1 = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument";
private static final String RELATIONSHIP_TYPE_2 = "http://purl.oclc.org/ooxml/officeDocument/relationships/officeDocument";
private static final Set<String> WORKSHEET_RELS;
private static final POILogger LOGGER;
protected OPCPackage pkg;
protected PackagePart workbookPart;
public FineXssfReader(OPCPackage pkg) throws IOException, OpenXML4JException {
this.pkg = pkg;
PackageRelationship coreDocRelationship = this.pkg.getRelationshipsByType(RELATIONSHIP_TYPE_1).getRelationship(0);
if (coreDocRelationship == null) {
if (this.pkg.getRelationshipsByType(RELATIONSHIP_TYPE_2).getRelationship(0) != null) {
throw new POIXMLException("Strict OOXML isn't currently supported, please see bug #57699");
} else {
throw new POIXMLException("OOXML file structure broken/invalid - no core document found!");
}
} else {
this.workbookPart = this.pkg.getPart(coreDocRelationship);
}
}
public SharedStringsTable getSharedStringsTable() throws IOException, InvalidFormatException {
ArrayList<PackagePart> parts = this.pkg.getPartsByContentType(XSSFRelation.SHARED_STRINGS.getContentType());
return parts.size() == 0 ? null : new SharedStringsTable((PackagePart)parts.get(0));
}
public StylesTable getStylesTable() throws IOException, InvalidFormatException {
ArrayList<PackagePart> parts = this.pkg.getPartsByContentType(XSSFRelation.STYLES.getContentType());
if (parts.size() == 0) {
return null;
} else {
StylesTable styles = new StylesTable((PackagePart)parts.get(0));
parts = this.pkg.getPartsByContentType(XSSFRelation.THEME.getContentType());
if (parts.size() != 0) {
styles.setTheme(new ThemesTable((PackagePart)parts.get(0)));
}
return styles;
}
}
public InputStream getSharedStringsData() throws IOException, InvalidFormatException {
return XSSFRelation.SHARED_STRINGS.getContents(this.workbookPart);
}
public InputStream getStylesData() throws IOException, InvalidFormatException {
return XSSFRelation.STYLES.getContents(this.workbookPart);
}
public InputStream getThemesData() throws IOException, InvalidFormatException {
return XSSFRelation.THEME.getContents(this.workbookPart);
}
public InputStream getWorkbookData() throws IOException, InvalidFormatException {
return this.workbookPart.getInputStream();
}
public InputStream getSheet(String relId) throws IOException, InvalidFormatException {
PackageRelationship rel = this.workbookPart.getRelationship(relId);
if (rel == null) {
throw new IllegalArgumentException("No Sheet found with r:id " + relId);
} else {
PackagePartName relName = PackagingURIHelper.createPartName(rel.getTargetURI());
PackagePart sheet = this.pkg.getPart(relName);
if (sheet == null) {
throw new IllegalArgumentException("No data found for Sheet with r:id " + relId);
} else {
return sheet.getInputStream();
}
}
}
public Iterator<InputStream> getSheetsData() throws IOException, InvalidFormatException {
return new SheetIterator(this.workbookPart);
}
static {
WORKSHEET_RELS = Collections.unmodifiableSet(new HashSet(Arrays.asList(XSSFRelation.WORKSHEET.getRelation(), XSSFRelation.CHARTSHEET.getRelation())));
LOGGER = POILogFactory.getLogger(FineXssfReader.class);
}
private static class XmlSheetRefReader extends DefaultHandler {
private static final String SHEET = "sheet";
private static final String ID = "id";
private static final String NAME = "name";
private static final String STATE = "state";
private final List<XssfSheetRef> sheetRefs;
private XmlSheetRefReader() {
this.sheetRefs = new LinkedList();
}
public void startElement(String uri, String localName, String qName, Attributes attrs) throws SAXException {
if (localName.equalsIgnoreCase(SHEET)) {
String name = null;
String id = null;
STSheetState.Enum state = STSheetState.VISIBLE;
for(int i = 0; i < attrs.getLength(); ++i) {
String attrName = attrs.getLocalName(i);
if (attrName.equalsIgnoreCase(NAME)) {
name = attrs.getValue(i);
} else if (attrName.equalsIgnoreCase(ID)) {
id = attrs.getValue(i);
} else if (attrName.equalsIgnoreCase(STATE)) {
state = STSheetState.Enum.forString(attrs.getValue(i));
}
if (name != null && id != null) {
this.sheetRefs.add(new XssfSheetRef(id, name, state));
break;
}
}
}
}
List<XssfSheetRef> getSheetRefs() {
return Collections.unmodifiableList(this.sheetRefs);
}
}
protected static final class XssfSheetRef {
private final String id;
private final String name;
private final STSheetState.Enum state;
public XssfSheetRef(String id, String name, STSheetState.Enum state) {
this.id = id;
this.name = name;
this.state = state;
}
public String getId() {
return this.id;
}
public String getName() {
return this.name;
}
public STSheetState.Enum getState() {
return state;
}
}
public static class SheetIterator implements Iterator<InputStream> {
private final Map<String, PackagePart> sheetMap;
XssfSheetRef xssfSheetRef;
final Iterator<XssfSheetRef> sheetIterator;
SheetIterator(PackagePart wb) throws IOException {
try {
this.sheetMap = new HashMap();
OPCPackage pkg = wb.getPackage();
Set<String> worksheetRels = this.getSheetRelationships();
Iterator var4 = wb.getRelationships().iterator();
while(var4.hasNext()) {
PackageRelationship rel = (PackageRelationship)var4.next();
String relType = rel.getRelationshipType();
if (worksheetRels.contains(relType)) {
PackagePartName relName = PackagingURIHelper.createPartName(rel.getTargetURI());
this.sheetMap.put(rel.getId(), pkg.getPart(relName));
}
}
this.sheetIterator = this.createSheetIteratorFromWB(wb);
} catch (InvalidFormatException var8) {
throw new POIXMLException(var8);
}
}
Iterator<XssfSheetRef> createSheetIteratorFromWB(PackagePart wb) throws IOException {
XmlSheetRefReader xmlSheetRefReader = new XmlSheetRefReader();
XMLReader xmlReader;
try {
xmlReader = XMLHelper.newXMLReader();
} catch (SAXException var9) {
throw new POIXMLException(var9);
} catch (ParserConfigurationException var9) {
throw new POIXMLException(var9);
}
xmlReader.setContentHandler(xmlSheetRefReader);
try {
xmlReader.parse(new InputSource(wb.getInputStream()));
} catch (SAXException var8) {
throw new POIXMLException(var8);
}
List<XssfSheetRef> validSheets = new ArrayList();
Iterator var5 = xmlSheetRefReader.getSheetRefs().iterator();
while(var5.hasNext()) {
XssfSheetRef xssfSheetRef = (XssfSheetRef)var5.next();
String sheetId = xssfSheetRef.getId();
if (sheetId != null && sheetId.length() > 0) {
validSheets.add(xssfSheetRef);
}
}
return validSheets.iterator();
}
Set<String> getSheetRelationships() {
return WORKSHEET_RELS;
}
public boolean hasNext() {
return this.sheetIterator.hasNext();
}
public InputStream next() {
this.xssfSheetRef = (XssfSheetRef)this.sheetIterator.next();
String sheetId = this.xssfSheetRef.getId();
try {
PackagePart sheetPkg = (PackagePart)this.sheetMap.get(sheetId);
return sheetPkg.getInputStream();
} catch (IOException var3) {
throw new POIXMLException(var3);
}
}
public String getSheetName() {
return this.xssfSheetRef.getName();
}
public STSheetState.Enum getState() {
return this.xssfSheetRef.getState();
}
public CommentsTable getSheetComments() {
PackagePart sheetPkg = this.getSheetPart();
try {
PackageRelationshipCollection commentsList = sheetPkg.getRelationshipsByType(XSSFRelation.SHEET_COMMENTS.getRelation());
if (commentsList.size() > 0) {
PackageRelationship comments = commentsList.getRelationship(0);
PackagePartName commentsName = PackagingURIHelper.createPartName(comments.getTargetURI());
PackagePart commentsPart = sheetPkg.getPackage().getPart(commentsName);
return new CommentsTable(commentsPart);
} else {
return null;
}
} catch (IOException var6) {
LOGGER.log(5, new Object[]{var6});
return null;
} catch (InvalidFormatException var6) {
LOGGER.log(5, new Object[]{var6});
return null;
}
}
public List<XSSFShape> getShapes() {
PackagePart sheetPkg = this.getSheetPart();
LinkedList shapes = new LinkedList();
try {
PackageRelationshipCollection drawingsList = sheetPkg.getRelationshipsByType(XSSFRelation.DRAWINGS.getRelation());
for(int i = 0; i < drawingsList.size(); ++i) {
PackageRelationship drawings = drawingsList.getRelationship(i);
PackagePartName drawingsName = PackagingURIHelper.createPartName(drawings.getTargetURI());
PackagePart drawingsPart = sheetPkg.getPackage().getPart(drawingsName);
if (drawingsPart == null) {
LOGGER.log(5, new Object[]{"Missing drawing: " + drawingsName + ". Skipping it."});
} else {
XSSFDrawing drawing = new XSSFDrawing(drawingsPart);
shapes.addAll(drawing.getShapes());
}
}
return shapes;
} catch (InvalidFormatException var9) {
LOGGER.log(5, new Object[]{var9});
return null;
} catch (IOException e) {
LOGGER.log(5, new Object[]{e});
return null;
} catch (XmlException e) {
LOGGER.log(5, new Object[]{e});
return null;
}
}
public PackagePart getSheetPart() {
String sheetId = this.xssfSheetRef.getId();
return this.sheetMap.get(sheetId);
}
public void remove() {
throw new IllegalStateException("Not supported");
}
}
}