XlsxSaxAnalyser.java 5.9 KB
Newer Older
1 2
package com.alibaba.excel.analysis.v07;

Z
zhuangjiaju 已提交
3
import java.io.File;
Z
zhuangjiaju 已提交
4 5 6
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
Z
zhuangjiaju 已提交
7
import java.util.HashMap;
Z
zhuangjiaju 已提交
8
import java.util.List;
Z
zhuangjiaju 已提交
9 10
import java.util.Map;
import java.util.UUID;
Z
zhuangjiaju 已提交
11 12 13 14

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

15 16
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.xssf.eventusermodel.XSSFReader;
Z
zhuangjiaju 已提交
17
import org.apache.poi.xssf.usermodel.XSSFRelation;
Z
zhuangjiaju 已提交
18 19 20
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorkbook;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorkbookPr;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.WorkbookDocument;
21 22 23 24
import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;

Z
zhuangjiaju 已提交
25 26
import com.alibaba.excel.analysis.ExcelExecutor;
import com.alibaba.excel.cache.Ehcache;
Z
zhuangjiaju 已提交
27 28
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.exception.ExcelAnalysisException;
29 30
import com.alibaba.excel.read.metadata.ReadSheet;
import com.alibaba.excel.read.metadata.holder.ReadWorkbookHolder;
Z
zhuangjiaju 已提交
31
import com.alibaba.excel.util.FileUtils;
32 33

/**
34
 *
35 36
 * @author jipengfei
 */
Z
zhuangjiaju 已提交
37 38
public class XlsxSaxAnalyser implements ExcelExecutor {
    private AnalysisContext analysisContext;
39
    private List<ReadSheet> sheetList;
Z
zhuangjiaju 已提交
40
    private Map<Integer, InputStream> sheetMap;
41

Z
zhuangjiaju 已提交
42 43
    public XlsxSaxAnalyser(AnalysisContext analysisContext) throws Exception {
        this.analysisContext = analysisContext;
44 45 46 47
        // Initialize cache
        ReadWorkbookHolder readWorkbookHolder = analysisContext.readWorkbookHolder();
        if (readWorkbookHolder.getReadCache() == null) {
            readWorkbookHolder.setReadCache(new Ehcache());
Z
zhuangjiaju 已提交
48
        }
49
        readWorkbookHolder.getReadCache().init(analysisContext);
Z
zhuangjiaju 已提交
50

51
        OPCPackage pkg = readOpcPackage(readWorkbookHolder);
52

Z
zhuangjiaju 已提交
53
        // Analysis sharedStringsTable.xml
54
        analysisSharedStringsTable(pkg, readWorkbookHolder);
55

Z
zhuangjiaju 已提交
56
        XSSFReader xssfReader = new XSSFReader(pkg);
57

58
        analysisUse1904WindowDate(xssfReader, readWorkbookHolder);
59

60
        sheetList = new ArrayList<ReadSheet>();
Z
zhuangjiaju 已提交
61 62 63
        sheetMap = new HashMap<Integer, InputStream>();
        XSSFReader.SheetIterator ite = (XSSFReader.SheetIterator)xssfReader.getSheetsData();
        int index = 0;
64 65 66
        if (!ite.hasNext()) {
            throw new ExcelAnalysisException("Can not find any sheet!");
        }
67 68
        while (ite.hasNext()) {
            InputStream inputStream = ite.next();
69
            sheetList.add(new ReadSheet(index, ite.getSheetName()));
Z
zhuangjiaju 已提交
70 71
            sheetMap.put(index, inputStream);
            index++;
72 73 74
        }
    }

75 76 77 78 79
    private void analysisUse1904WindowDate(XSSFReader xssfReader, ReadWorkbookHolder readWorkbookHolder)
        throws Exception {
        if (readWorkbookHolder.globalConfiguration().getUse1904windowing() != null) {
            return;
        }
Z
zhuangjiaju 已提交
80 81 82 83 84
        InputStream workbookXml = xssfReader.getWorkbookData();
        WorkbookDocument ctWorkbook = WorkbookDocument.Factory.parse(workbookXml);
        CTWorkbook wb = ctWorkbook.getWorkbook();
        CTWorkbookPr prefix = wb.getWorkbookPr();
        if (prefix != null && prefix.getDate1904()) {
85
            readWorkbookHolder.getGlobalConfiguration().setUse1904windowing(Boolean.TRUE);
86 87
        } else {
            readWorkbookHolder.getGlobalConfiguration().setUse1904windowing(Boolean.FALSE);
Z
zhuangjiaju 已提交
88 89 90
        }
    }

91 92
    private void analysisSharedStringsTable(OPCPackage pkg, ReadWorkbookHolder readWorkbookHolder) throws Exception {
        ContentHandler handler = new SharedStringsTableHandler(readWorkbookHolder.getReadCache());
Z
zhuangjiaju 已提交
93 94
        parseXmlSource(pkg.getPartsByContentType(XSSFRelation.SHARED_STRINGS.getContentType()).get(0).getInputStream(),
            handler);
95
        readWorkbookHolder.getReadCache().putFinished();
Z
zhuangjiaju 已提交
96 97
    }

98 99 100
    private OPCPackage readOpcPackage(ReadWorkbookHolder readWorkbookHolder) throws Exception {
        if (readWorkbookHolder.getFile() != null) {
            return OPCPackage.open(readWorkbookHolder.getFile());
Z
zhuangjiaju 已提交
101
        }
102 103
        if (readWorkbookHolder.getMandatoryUseInputStream()) {
            return OPCPackage.open(readWorkbookHolder.getInputStream());
104
        }
Z
zhuangjiaju 已提交
105
        File readTempFile = FileUtils.createCacheTmpFile();
106
        readWorkbookHolder.setTempFile(readTempFile);
Z
zhuangjiaju 已提交
107
        File tempFile = new File(readTempFile.getPath(), UUID.randomUUID().toString() + ".xlsx");
108
        FileUtils.writeToFile(readTempFile, readWorkbookHolder.getInputStream());
Z
zhuangjiaju 已提交
109
        return OPCPackage.open(tempFile);
110 111
    }

Z
zhuangjiaju 已提交
112
    @Override
113
    public List<ReadSheet> sheetList() {
Z
zhuangjiaju 已提交
114 115 116 117 118
        return sheetList;
    }

    private void parseXmlSource(InputStream inputStream, ContentHandler handler) {
        InputSource inputSource = new InputSource(inputStream);
119 120 121 122 123 124 125 126
        try {
            SAXParserFactory saxFactory = SAXParserFactory.newInstance();
            saxFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
            saxFactory.setFeature("http://xml.org/sax/features/external-general-entities", false);
            saxFactory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
            SAXParser saxParser = saxFactory.newSAXParser();
            XMLReader xmlReader = saxParser.getXMLReader();
            xmlReader.setContentHandler(handler);
Z
zhuangjiaju 已提交
127
            xmlReader.parse(inputSource);
128 129 130
            inputStream.close();
        } catch (Exception e) {
            throw new ExcelAnalysisException(e);
Z
zhuangjiaju 已提交
131 132 133 134 135 136 137 138
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    throw new ExcelAnalysisException("Can not close 'inputStream'!");
                }
            }
139 140 141
        }
    }

142 143 144 145 146 147
    @Override
    public void execute() {
        parseXmlSource(sheetMap.get(analysisContext.readSheetHolder().getSheetNo()),
            new XlsxRowHandler(analysisContext));
    }

148
}