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