forked from fanruan/easyexcel
lucian
3 years ago
4 changed files with 389 additions and 5 deletions
@ -0,0 +1,350 @@
|
||||
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"); |
||||
} |
||||
} |
||||
} |
||||
|
Loading…
Reference in new issue