美文网首页
6、poi eventUserModel快速读取数据

6、poi eventUserModel快速读取数据

作者: ltjxwxz | 来源:发表于2017-09-02 11:44 被阅读0次

    apache官方的链接,看了几遍还是觉得很模糊,如果有相关的资料,请推荐一下。
    https://poi.apache.org/spreadsheet/examples.html
    https://svn.apache.org/repos/asf/poi/trunk/src/examples/src/org/apache/poi/xssf/eventusermodel/XLSX2CSV.java
    https://svn.apache.org/repos/asf/poi/trunk/src/examples/src/org/apache/poi/hssf/eventusermodel/examples/XLS2CSVmra.java
    xls和xlsx在usermodel下可以用同一套代码处理,eventUserModel好像不行。不过速度真的很快,2,3 秒就可以处理300多条数据。
    处理xlsx如下:

    import java.io.IOException;
    import java.io.InputStream;
    import java.io.PrintStream;
    import java.text.SimpleDateFormat;
    import java.util.ArrayList;
    import java.util.Date;
    import java.util.HashMap;
    import java.util.LinkedList;
    import java.util.List;
    import java.util.Map;
    
    import javax.xml.parsers.ParserConfigurationException;
    import javax.xml.parsers.SAXParser;
    import javax.xml.parsers.SAXParserFactory;
    
    import org.apache.poi.hssf.usermodel.HSSFDateUtil;
    import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
    import org.apache.poi.openxml4j.opc.OPCPackage;
    import org.apache.poi.openxml4j.opc.PackageAccess;
    import org.apache.poi.ss.usermodel.BuiltinFormats;
    import org.apache.poi.ss.usermodel.DataFormatter;
    import org.apache.poi.xssf.eventusermodel.ReadOnlySharedStringsTable;
    import org.apache.poi.xssf.eventusermodel.XSSFReader;
    import org.apache.poi.xssf.model.StylesTable;
    import org.apache.poi.xssf.usermodel.XSSFCellStyle;
    import org.apache.poi.xssf.usermodel.XSSFRichTextString;
    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;  
      
    /** 
     * 使用CVS模式解决XLSX文件,可以有效解决用户模式内存溢出的问题 
     * 该模式是POI官方推荐的读取大数据的模式,在用户模式下,数据量较大、Sheet较多、或者是有很多无用的空行的情况 
     * ,容易出现内存溢出,用户模式读取Excel的典型代码如下: FileInputStream file=new 
     * FileInputStream("c:\\test.xlsx"); Workbook wb=new XSSFWorkbook(file); 
     *  
     *  
     */  
    public class XLSXCovertCSVReader {  
      
        /** 
         * The type of the data value is indicated by an attribute on the cell. The 
         * value is usually in a "v" element within the cell. 
         */  
        enum xssfDataType {  
            BOOL, ERROR, FORMULA, INLINESTR, SSTINDEX, NUMBER,  
        }  
      
        /** 
         * 使用xssf_sax_API处理Excel,请参考: http://poi.apache.org/spreadsheet/how-to.html#xssf_sax_api 
         * <p/> 
         * Also see Standard ECMA-376, 1st edition, part 4, pages 1928ff, at 
         * http://www.ecma-international.org/publications/standards/Ecma-376.htm 
         * <p/> 
         * A web-friendly version is http://openiso.org/Ecma/376/Part4 
         */  
        class MyXSSFSheetHandler extends DefaultHandler {  
    //      private XSSFFormulaEvaluator evaluator;
    
            
            /** 
             * Table with styles 
             */  
            private StylesTable stylesTable;  
      
            /** 
             * Table with unique strings 
             */  
            private ReadOnlySharedStringsTable sharedStringsTable;  
      
            /** 
             * Destination for data 
             */  
            private final PrintStream output;  
      
            /** 
             * Number of columns to read starting with leftmost 
             */  
            private final int minColumnCount;  
      
            // Set when V start element is seen  
            private boolean vIsOpen;  
      
            // Set when cell start element is seen;  
            // used when cell close element is seen.  
            private xssfDataType nextDataType;  
      
            // Used to format numeric cell values.  
            private short formatIndex;  
            private String formatString;  
            private final DataFormatter formatter;  
      
            private int thisColumn = -1;   // 当前列
            private int requireHeadColumn = 99;  // 需求标题所在列
            private int exTaskHead = 99;  //任务标题所在列
            private List<String> nullRowList;   // 包含"需求标题", "任务标题"
            
            // The last column printed to the output stream  
            private int lastColumnNumber = -1;  
      
            // Gathers characters as they are seen.  
            private StringBuffer value;  
            private String[] record;  
            private List<String[]> rows = new ArrayList<String[]>();  
            private boolean isCellNull = false;  
      
            /** 
             * Accepts objects needed while parsing. 
             *  
             * @param styles 
             *            Table of styles 
             * @param strings 
             *            Table of shared strings 
             * @param cols 
             *            Minimum number of columns to show 
             * @param target 
             *            Sink for output 
             */  
            public MyXSSFSheetHandler(StylesTable styles,  
                    ReadOnlySharedStringsTable strings, int cols, PrintStream target, List<String> nullRowList) {  
                this.stylesTable = styles;  
                this.sharedStringsTable = strings;  
                this.minColumnCount = cols;  
                this.output = target;  
                this.value = new StringBuffer();  
                this.nextDataType = xssfDataType.NUMBER;  
                this.formatter = new DataFormatter();  
    //            record = new String[100];  
                record = new String[this.minColumnCount];  
                rows.clear();// 每次读取都清空行集合  
                this.nullRowList = nullRowList;
            }  
      
            /* 
             * (non-Javadoc) 
             *  
             * @see 
             * org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String, 
             * java.lang.String, java.lang.String, org.xml.sax.Attributes) 
             */  
            public void startElement(String uri, String localName, String name,  
                    Attributes attributes) throws SAXException {  
      
                if ("inlineStr".equals(name) || "v".equals(name)) {  
                    vIsOpen = true;  
                    // Clear contents cache  
                    value.setLength(0);  
                }  
    //            else if("f".equals(name)) {
    //              nextDataType = xssfDataType.FORMULA;  
    //            }
                // c => cell  
                else if ("c".equals(name)) {  
                    // Get the cell reference  
                    String r = attributes.getValue("r");  
                    int firstDigit = -1;  
                    for (int c = 0; c < r.length(); ++c) {  
                        if (Character.isDigit(r.charAt(c))) {  
                            firstDigit = c;  
                            break;  
                        }  
                    }  
                    thisColumn = nameToColumn(r.substring(0, firstDigit));  
      
                    // Set up defaults.  
                    this.nextDataType = xssfDataType.NUMBER;  
                    this.formatIndex = -1;  
                    this.formatString = null;  
                    String cellType = attributes.getValue("t");  
                    String cellStyleStr = attributes.getValue("s");  
                    
    //                int styleIndex2 = Integer.parseInt(cellStyleStr);  
    //                XSSFCellStyle style2 = stylesTable.getStyleAt(styleIndex2);  
    //                System.out.println("styleDataFormat:" + style2.getDataFormat());
                    
                    if ("b".equals(cellType))  
                        nextDataType = xssfDataType.BOOL;  
                    else if ("e".equals(cellType))  
                        nextDataType = xssfDataType.ERROR;  
                    else if ("inlineStr".equals(cellType))  
                        nextDataType = xssfDataType.INLINESTR;  
                    else if ("s".equals(cellType))  
                        nextDataType = xssfDataType.SSTINDEX;  
                    else if ("str".equals(cellType))  
                        nextDataType = xssfDataType.FORMULA;  
                    else if (cellStyleStr != null) {  
                        // It's a number, but almost certainly one  
                        // with a special style or format  
                        int styleIndex = Integer.parseInt(cellStyleStr);  
                        XSSFCellStyle style = stylesTable.getStyleAt(styleIndex);  
                        this.formatIndex = style.getDataFormat();  
                        this.formatString = style.getDataFormatString(); 
                        if (this.formatString == null)  
                            this.formatString = BuiltinFormats  
                                    .getBuiltinFormat(this.formatIndex);  
                    }  
                }  
      
            }  
      
            /* 
             * (non-Javadoc) 
             *  
             * @see org.xml.sax.helpers.DefaultHandler#endElement(java.lang.String, 
             * java.lang.String, java.lang.String) 
             */  
            public void endElement(String uri, String localName, String name)  
                    throws SAXException {  
      
                String thisStr = null;  
      
                // v => contents of a cell  
                if ("v".equals(name)) {  
                    // Process the value contents as required.  
                    // Do now, as characters() may be called more than once  
                    switch (nextDataType) {  
      
                    case BOOL:  
                        char first = value.charAt(0);  
                        thisStr = first == '0' ? "FALSE" : "TRUE";  
                        break;  
      
                    case ERROR:  
                        thisStr = "ERROR:" + value.toString();  
                        break;  
      
                    case FORMULA:  
                        // A formula could result in a string value,  
                        // so always add double-quote characters.  
                        thisStr = value.toString();  
                        break;  
      
                    case INLINESTR:  
                        // TODO: have seen an example of this, so it's untested.  
                        XSSFRichTextString rtsi = new XSSFRichTextString(  
                                value.toString());  
                        thisStr = rtsi.toString();  
                        break;  
      
                    case SSTINDEX:  
                        String sstIndex = value.toString();  
                        try {  
                            int idx = Integer.parseInt(sstIndex);  
                            XSSFRichTextString rtss = new XSSFRichTextString(  
                                    sharedStringsTable.getEntryAt(idx));  
                            thisStr = rtss.toString();  
                        } catch (NumberFormatException ex) {  
                            output.println("Failed to parse SST index '" + sstIndex  
                                    + "': " + ex.toString());  
                        }  
                        break;  
      
                    case NUMBER:  
                        String n = value.toString();  
                        // 判断是否是日期格式  
                        if (HSSFDateUtil.isADateFormat(this.formatIndex, n)) {  
                            Double d = Double.parseDouble(n);  
                            Date date=HSSFDateUtil.getJavaDate(d);  
                            thisStr=formateDateToString(date);  
                        } else if (this.formatString != null)  
                            thisStr = formatter.formatRawCellContents(  
                                    Double.parseDouble(n), this.formatIndex,  
                                    this.formatString);  
                        else  
                            thisStr = n;  
                        break;  
      
                    default:  
                        thisStr = "(TODO: Unexpected type: " + nextDataType + ")";  
                        break;  
                    }  
      
                    // Output after we've seen the string contents  
                    // Emit commas for any fields that were missing on this row  
                    if (lastColumnNumber == -1) {  
                        lastColumnNumber = 0;  
                    }  
                    //判断单元格的值是否为空  
                    if (thisStr == null || "".equals(isCellNull)) {  
                        isCellNull = true;// 设置单元格是否为空值  
                    }  
                    // 判断 单元格内容是否为 "需求标题"
                    if(nullRowList.get(0).equals(thisStr)) {
                        // 记录需求标题所在列
                        requireHeadColumn = thisColumn;
                        System.out.println("requireTitleColumn:" + requireHeadColumn);
                    }
                    // 判断 单元格内容是否为 "任务标题"
                    if(nullRowList.get(1).equals(thisStr)) {
                        // 记录任务标题所在列
                        exTaskHead = thisColumn;
                        System.out.println("exTaskHead:" + exTaskHead);
                    }
                    record[thisColumn] = thisStr;  
                    // Update column  
                    if (thisColumn > -1)  {
                        lastColumnNumber = thisColumn;
                    }
    //                System.out.println("thisStr:" + thisStr);
                } else if ("row".equals(name)) {  
      
                    // Print out any missing commas if needed  
                    if (minColumns > 0) {  
                        // Columns are 0 based  
                        if (lastColumnNumber == -1) {  
                            lastColumnNumber = 0;  
                        }  
                        
                        if (isCellNull == false && 
                                (record[requireHeadColumn] != null && !"".equals(record[requireHeadColumn].trim())) || 
                                (record[exTaskHead] != null && !"".equals(record[exTaskHead].trim())))// 判断是否空行  
                        {  
                            rows.add(record.clone());  
                            isCellNull = false;  
                            for (int i = 0; i < record.length; i++) {  
                                record[i] = null;  
                            }  
                        }  
                    }  
                    lastColumnNumber = -1;  
                }  
      
            }  
      
            public List<String[]> getRows() {  
                return rows;  
            }  
      
            public void setRows(List<String[]> rows) {  
                this.rows = rows;  
            }  
      
            /** 
             * Captures characters only if a suitable element is open. Originally 
             * was just "v"; extended for inlineStr also. 
             */  
            public void characters(char[] ch, int start, int length)  
                    throws SAXException {  
                if (vIsOpen)  
                    value.append(ch, start, length);  
            }  
      
            /** 
             * Converts an Excel column name like "C" to a zero-based index. 
             *  
             * @param name 
             * @return Index corresponding to the specified name 
             */  
            private int nameToColumn(String name) {  
                int column = -1;  
                for (int i = 0; i < name.length(); ++i) {  
                    int c = name.charAt(i);  
                    column = (column + 1) * 26 + c - 'A';  
                }  
                return column;  
            }  
      
            private String formateDateToString(Date date) {  
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");//格式化日期  
                return sdf.format(date);  
            }  
      
        }  
      
        // /////////////////////////////////////  
      
        private OPCPackage xlsxPackage;  
        private int minColumns;  
        private PrintStream output;  
        private String sheetName;  
      
        /** 
         * Creates a new XLSX -> CSV converter 
         *  
         * @param pkg 
         *            The XLSX package to process 
         * @param output 
         *            The PrintStream to output the CSV to 
         * @param minColumns 
         *            The minimum number of columns to output, or -1 for no minimum 
         */  
        public XLSXCovertCSVReader(OPCPackage pkg, PrintStream output,  
                String sheetName, int minColumns) {  
            this.xlsxPackage = pkg;  
            this.output = output;  
            this.minColumns = minColumns;  
            this.sheetName = sheetName;  
        }  
      
        /** 
         * Parses and shows the content of one sheet using the specified styles and 
         * shared-strings tables. 
         *  
         * @param styles 
         * @param strings 
         * @param sheetInputStream 
         */  
        public List<String[]> processSheet(StylesTable styles,  
                ReadOnlySharedStringsTable strings, InputStream sheetInputStream, List<String> nullRowList)  
                throws IOException, ParserConfigurationException, SAXException {  
      
            InputSource sheetSource = new InputSource(sheetInputStream);  
            SAXParserFactory saxFactory = SAXParserFactory.newInstance();  
            SAXParser saxParser = saxFactory.newSAXParser();  
            XMLReader sheetParser = saxParser.getXMLReader();  
            MyXSSFSheetHandler handler = new MyXSSFSheetHandler(styles, strings,  
                    this.minColumns, this.output, nullRowList);  
            sheetParser.setContentHandler(handler);  
            sheetParser.parse(sheetSource);  
            return handler.getRows();  
        }  
      
        /** 
         * 初始化这个处理程序 将 
         *  
         * @throws IOException 
         * @throws OpenXML4JException 
         * @throws ParserConfigurationException 
         * @throws SAXException 
         */  
        public List<String[]> process(List<String> nullRowList) throws IOException, OpenXML4JException,  
                ParserConfigurationException, SAXException {  
      
            ReadOnlySharedStringsTable strings = new ReadOnlySharedStringsTable(  
                    this.xlsxPackage);  
            XSSFReader xssfReader = new XSSFReader(this.xlsxPackage);  
            List<String[]> list = null;  
            StylesTable styles = xssfReader.getStylesTable();  
            XSSFReader.SheetIterator iter = (XSSFReader.SheetIterator) xssfReader.getSheetsData();  
            int index = 0;  
            while (iter.hasNext()) {  
                InputStream stream = iter.next();  
                String sheetNameTemp = iter.getSheetName();  
                if (this.sheetName.equals(sheetNameTemp)) {  
                    list = processSheet(styles, strings, stream, nullRowList);  
                    stream.close();  
                    ++index;  
                }  
            }  
            return list;  
        }  
      
        /** 
         * 读取Excel 
         *  
         * @param path 
         *            文件路径 
         * @param sheetName 
         *            sheet名称 
         * @param minColumns 
         *            列总数 
         * @return 
         * @throws SAXException 
         * @throws ParserConfigurationException 
         * @throws OpenXML4JException 
         * @throws IOException 
         */  
        public static List<String[]> readerExcel(String path, String sheetName, List<String> nullRowList) throws IOException, OpenXML4JException,  
                ParserConfigurationException, SAXException {  
            OPCPackage p = OPCPackage.open(path, PackageAccess.READ);  
            XLSXCovertCSVReader xlsx2csv = new XLSXCovertCSVReader(p, System.out,  
                    sheetName, 100);  
            List<String[]> list = xlsx2csv.process(nullRowList);  
            p.close();  
            return list;  
        }  
      
        public static void main(String[] args) throws Exception {  
            long a=System.currentTimeMillis();  
            List<String> nullRowList = new ArrayList<>();
            nullRowList.add("需求标题");
            nullRowList.add("任务标题");
            
            List<String[]> list = XLSXCovertCSVReader  
                    .readerExcel(  
                            "C:/Users/Administrator/Desktop/说明文档2/文档标准/2017ttt.xlsx",  
                            "未安排", nullRowList);  
    //        List<String[]> list = XLSXCovertCSVReader  
    //                .readerExcel(  
    //                        "C:/Users/Administrator/Desktop/说明文档2/2017需求列表.xlsx",  
    //                        "需求矩阵");  
    //        List<String[]> list = XLSXCovertCSVReader  
    //              .readerExcel(  
    //                      "D:/profiles/sts-bundle/workspace20170628/ermss/target/classes/bbb.xlsx",  
    //                      "月版本和周版本");  
            List<Map<String, String>> resultList = new LinkedList<Map<String, String>>();
            for (int i=0; i<list.size(); i++) {  
                Map<String, String> valueMap = new HashMap<String, String>();
                for (int j=0; j<list.get(i).length; j++) {  
                    if(list.get(0)[j] != null && !"".equals(list.get(0)[j])) {
                        valueMap.put(list.get(0)[j], list.get(i)[j]);  
                    }
                }  
                // 只获取数据,不要标题
                if(i > 0) {
                    resultList.add(valueMap);
                }
            }  
            System.out.println("resultList.size():" + resultList);  
            System.out.println("执行耗时 :"+(System.currentTimeMillis()-a)/1000f+" 秒 "); 
            
        }  
    }  
    

    处理xlx如下:

    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    import java.io.PrintStream;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.LinkedList;
    import java.util.List;
    import java.util.Map;
    
    import org.apache.poi.hssf.eventusermodel.EventWorkbookBuilder.SheetRecordCollectingListener;
    import org.apache.poi.hssf.eventusermodel.FormatTrackingHSSFListener;
    import org.apache.poi.hssf.eventusermodel.HSSFEventFactory;
    import org.apache.poi.hssf.eventusermodel.HSSFListener;
    import org.apache.poi.hssf.eventusermodel.HSSFRequest;
    import org.apache.poi.hssf.eventusermodel.MissingRecordAwareHSSFListener;
    import org.apache.poi.hssf.eventusermodel.dummyrecord.LastCellOfRowDummyRecord;
    import org.apache.poi.hssf.eventusermodel.dummyrecord.MissingCellDummyRecord;
    import org.apache.poi.hssf.model.HSSFFormulaParser;
    import org.apache.poi.hssf.record.BOFRecord;
    import org.apache.poi.hssf.record.BlankRecord;
    import org.apache.poi.hssf.record.BoolErrRecord;
    import org.apache.poi.hssf.record.BoundSheetRecord;
    import org.apache.poi.hssf.record.CellValueRecordInterface;
    import org.apache.poi.hssf.record.ExtendedFormatRecord;
    import org.apache.poi.hssf.record.FormatRecord;
    import org.apache.poi.hssf.record.FormulaRecord;
    import org.apache.poi.hssf.record.LabelRecord;
    import org.apache.poi.hssf.record.LabelSSTRecord;
    import org.apache.poi.hssf.record.NoteRecord;
    import org.apache.poi.hssf.record.NumberRecord;
    import org.apache.poi.hssf.record.RKRecord;
    import org.apache.poi.hssf.record.Record;
    import org.apache.poi.hssf.record.SSTRecord;
    import org.apache.poi.hssf.record.StringRecord;
    import org.apache.poi.hssf.usermodel.HSSFDataFormat;
    import org.apache.poi.hssf.usermodel.HSSFWorkbook;
    import org.apache.poi.poifs.filesystem.POIFSFileSystem;
    import org.apache.poi.ss.formula.SheetNameFormatter;
    import org.apache.poi.ss.usermodel.DataFormatter;
    import org.apache.poi.util.POILogger;
    
    /**
     * A XLS -> CSV processor, that uses the MissingRecordAware
     *  EventModel code to ensure it outputs all columns and rows.
     * @author Nick Burch
     */
    public class XLS2CSVmra implements HSSFListener {
        private int minColumns;
        private POIFSFileSystem fs;
        private PrintStream output;
    
        private int lastRowNumber;
        private int lastColumnNumber;
    
        /** Should we output the formula, or the value it has? */
        private boolean outputFormulaValues = true;
    
        /** For parsing Formulas */
        private SheetRecordCollectingListener workbookBuildingListener;
        private HSSFWorkbook stubWorkbook;
    
        // Records we pick up as we process
        private SSTRecord sstRecord;
        private FormatTrackingHSSFListener formatListener;
        
        /** So we known which sheet we're on */
        private int sheetIndex = -1;
        private BoundSheetRecord[] orderedBSRs;
        private List<BoundSheetRecord> boundSheetRecords = new ArrayList<BoundSheetRecord>();
    
        // For handling formulas with string results
        private int nextRow;
        private int nextColumn;
        private boolean outputNextStringRecord;
        
        String[] recordArray = new String[100];  ;   // 每行为一个数组  
        List<String[]> rowsList = new ArrayList<String[]>();  //当前sheet页的所有行 
        
        private int requireHeadColumn = 99;  // 需求标题所在列
        private int exTaskHead = 99;  //任务标题所在列
        private List<String> nullRowList;   // 包含"需求标题", "任务标题"
        
        private String sheetName = "";
        private final List<ExtendedFormatRecord> _xfRecords = new ArrayList<ExtendedFormatRecord>();
        private final Map<Integer, FormatRecord> _customFormatRecords = new HashMap<Integer, FormatRecord>();
    
        /**
         * Creates a new XLS -> CSV converter
         * @param fs The POIFSFileSystem to process
         * @param output The PrintStream to output the CSV to
         * @param minColumns The minimum number of columns to output, or -1 for no minimum
         */
        public XLS2CSVmra(POIFSFileSystem fs, PrintStream output, List<String> nullRowList, String sheetName) {
            this.fs = fs;
            this.output = output;
            this.minColumns = 100;
            this.nullRowList = nullRowList;
            this.sheetName = sheetName;
        }
    
        /**
         * Creates a new XLS -> CSV converter
         * @param filename The file to process
         * @param minColumns The minimum number of columns to output, or -1 for no minimum
         * @throws IOException
         * @throws FileNotFoundException
         */
        public XLS2CSVmra(String filename, String sheetName, List<String> nullRowList) throws IOException, FileNotFoundException {
            this(new POIFSFileSystem(new FileInputStream(filename)), System.out, nullRowList, sheetName);
        }
    
        /**
         * Initiates the processing of the XLS file to CSV
         */
        public List<String[]> readerExcel() throws IOException {
            MissingRecordAwareHSSFListener listener = new MissingRecordAwareHSSFListener(this);
            formatListener = new FormatTrackingHSSFListener(listener);
            HSSFEventFactory factory = new HSSFEventFactory();
            HSSFRequest request = new HSSFRequest();
            if(outputFormulaValues) {
                request.addListenerForAllRecords(formatListener);
            } else {
                workbookBuildingListener = new SheetRecordCollectingListener(formatListener);
                request.addListenerForAllRecords(workbookBuildingListener);
            }
            factory.processWorkbookEvents(request, fs);
            return rowsList;
        }
    
        /**
         * Main HSSFListener method, processes events, and outputs the
         *  CSV as the file is processed.
         */
        @Override
        public void processRecord(Record record) {
            int thisRow = -1;
            int thisColumn = -1;   // 当前cell所在列
            String thisStr = null;  // 单元格内容
            
            processRecordInternally(record);
            
            switch (record.getSid()) {
            case BoundSheetRecord.sid:
                boundSheetRecords.add((BoundSheetRecord)record);
                break;
            case BOFRecord.sid:
                BOFRecord br = (BOFRecord)record;
                if(br.getType() == BOFRecord.TYPE_WORKSHEET) {
                    // Create sub workbook if required
                    if(workbookBuildingListener != null && stubWorkbook == null) {
                        stubWorkbook = workbookBuildingListener.getStubHSSFWorkbook();
                    }
                    
                    // Output the worksheet name
                    // Works by ordering the BSRs by the location of
                    //  their BOFRecords, and then knowing that we
                    //  process BOFRecords in byte offset order
                    sheetIndex++;
                    if(orderedBSRs == null) {
                        orderedBSRs = BoundSheetRecord.orderByBofPosition(boundSheetRecords);
                    }
    //              output.println();
                    //output.println(orderedBSRs[sheetIndex].getSheetname() +" [" + (sheetIndex+1) + "]:");
                }
                break;
    
            case SSTRecord.sid:
                sstRecord = (SSTRecord) record;
                break;
    
            case BlankRecord.sid:
                BlankRecord brec = (BlankRecord) record;
    
                thisRow = brec.getRow();
                thisColumn = brec.getColumn();
                thisStr = "";
                break;
            case BoolErrRecord.sid:
                BoolErrRecord berec = (BoolErrRecord) record;
    
                thisRow = berec.getRow();
                thisColumn = berec.getColumn();
                thisStr = "";
                break;
    
            case FormulaRecord.sid:
                FormulaRecord frec = (FormulaRecord) record;
    
                thisRow = frec.getRow();
                thisColumn = frec.getColumn();
    
                if(outputFormulaValues) {
                    if(Double.isNaN( frec.getValue() )) {
                        // Formula result is a string
                        // This is stored in the next record
                        outputNextStringRecord = true;
                        nextRow = frec.getRow();
                        nextColumn = frec.getColumn();
                    } else {
                        thisStr = formatListener.formatNumberDateCell(frec);
                    }
                } else {
                    thisStr = HSSFFormulaParser.toFormulaString(stubWorkbook, frec.getParsedExpression());
                }
                break;
            case StringRecord.sid:
                if(outputNextStringRecord) {
                    // String for formula
                    StringRecord srec = (StringRecord)record;
                    thisStr = srec.getString();
                    thisRow = nextRow;
                    thisColumn = nextColumn;
                    outputNextStringRecord = false;
                }
                break;
    
            case LabelRecord.sid:
                LabelRecord lrec = (LabelRecord) record;
    
                thisRow = lrec.getRow();
                thisColumn = lrec.getColumn();
                thisStr = lrec.getValue();
                break;
            case LabelSSTRecord.sid:
                LabelSSTRecord lsrec = (LabelSSTRecord) record;
    
                thisRow = lsrec.getRow();
                thisColumn = lsrec.getColumn();
                if(sstRecord == null) {
                    thisStr ="(No SST Record, can't identify string)";
                } else {
                    thisStr = sstRecord.getString(lsrec.getSSTIndex()).toString();
                }
                break;
            case NoteRecord.sid:
                NoteRecord nrec = (NoteRecord) record;
    
                thisRow = nrec.getRow();
                thisColumn = nrec.getColumn();
                // TODO: Find object to match nrec.getShapeId()
                thisStr = "(TODO)";
                break;
            case NumberRecord.sid:
                NumberRecord numrec = (NumberRecord) record;
                thisRow = numrec.getRow();
                thisColumn = numrec.getColumn();
                // Format
                thisStr = formatNumberDateCell(numrec);
    //          thisStr = formatListener.formatNumberDateCell(numrec);
                break;
            case RKRecord.sid:
                RKRecord rkrec = (RKRecord) record;
    
                thisRow = rkrec.getRow();
                thisColumn = rkrec.getColumn();
                thisStr = "(TODO)";
                break;
            default:
                break;
            }
    
            // Handle new row
            if(thisRow != -1 && thisRow != lastRowNumber) {
                lastColumnNumber = -1;
            }
    
            // Handle missing column
            if(record instanceof MissingCellDummyRecord) {
                MissingCellDummyRecord mc = (MissingCellDummyRecord)record;
                thisRow = mc.getRow();
                thisColumn = mc.getColumn();
                thisStr = "";
            }
    
            // If we got something to print out, do so
            if(thisStr != null) {
                if(thisColumn > 0) {
                    output.print(',');
                }
                
                // 判断 单元格内容是否为 "需求标题"
                if(nullRowList.get(0).equals(thisStr)) {
                    // 记录需求标题所在列
                    requireHeadColumn = thisColumn;
                    System.out.println("requireTitleColumn:" + requireHeadColumn);
                }
                // 判断 单元格内容是否为 "任务标题"
                if(nullRowList.get(1).equals(thisStr)) {
                    // 记录任务标题所在列
                    exTaskHead = thisColumn;
                    System.out.println("exTaskHead:" + exTaskHead);
                }
    //            output.print(thisStr);
                recordArray[thisColumn] = thisStr;  
            }
    
            // Update column and row count
            if(thisRow > -1)
                lastRowNumber = thisRow;
            if(thisColumn > -1)
                lastColumnNumber = thisColumn;
    
            // Handle end of row
            if(record instanceof LastCellOfRowDummyRecord) {
                // Print out any missing commas if needed
                if(minColumns > 0) {
                    // Columns are 0 based
                    if(lastColumnNumber == -1) { lastColumnNumber = 0; }
                    for(int i=lastColumnNumber; i<(minColumns); i++) {
    //                  output.print(',');
                    }
                    // 判断是不是指定sheet页下的内容
                    if(sheetName.equals(orderedBSRs[sheetIndex].getSheetname())) {
                        // 判断是否空行  
                        if ((recordArray[requireHeadColumn] != null && !"".equals(recordArray[requireHeadColumn].trim())) || 
                                (recordArray[exTaskHead] != null && !"".equals(recordArray[exTaskHead].trim()))) {  
                            output.println();
                            rowsList.add(recordArray.clone());  
                            for (int i = 0; i < recordArray.length; i++) {  
                                recordArray[i] = null;  
                            }  
                        } 
                    }
                }
                lastColumnNumber = -1;
            }
        }
        public int getFormatIndex(CellValueRecordInterface cell) {
            ExtendedFormatRecord xfr = _xfRecords.get(cell.getXFIndex());
            if (xfr == null) {
                return -1;
            }
            return xfr.getFormatIndex();
        }
        public String formatNumberDateCell(CellValueRecordInterface cell) {
            double value;
            if (cell instanceof NumberRecord) {
                value = ((NumberRecord) cell).getValue();
            } else if (cell instanceof FormulaRecord) {
                value = ((FormulaRecord) cell).getValue();
            } else {
                throw new IllegalArgumentException("Unsupported CellValue Record passed in " + cell);
            }
            // Format, using the nice new
            // HSSFDataFormatter to do the work for us"yyyy/MM/dd"
            DataFormatter _formatter = new DataFormatter();
            return _formatter.formatRawCellContents(value, getFormatIndex(cell), getFormatString(cell));
        }
        public String getFormatString(CellValueRecordInterface cell) {
            int formatIndex = getFormatIndex(cell);
            if (formatIndex == -1) {
                // Not found
                return null;
            }
            return getFormatString(formatIndex);
        }
        public String getFormatString(int formatIndex) {
            String format = null;
            if (formatIndex >= HSSFDataFormat.getNumberOfBuiltinBuiltinFormats()) {
                FormatRecord tfr = _customFormatRecords.get(Integer.valueOf(formatIndex));
                if (tfr == null) {
                } else {
                    format = tfr.getFormatString();
                }
            } else if(formatIndex == 14) {
                format = "yyyy/MM/dd";
            } else {
                // "yyyy/MM/dd"
                format = HSSFDataFormat.getBuiltinFormat((short) formatIndex);
            }
            return format;
        }
        public void processRecordInternally(Record record) {
            if (record instanceof FormatRecord) {
                FormatRecord fr = (FormatRecord) record;
                _customFormatRecords.put(Integer.valueOf(fr.getIndexCode()), fr);
            }
            if (record instanceof ExtendedFormatRecord) {
                ExtendedFormatRecord xr = (ExtendedFormatRecord) record;
                _xfRecords.add(xr);
            }
        }
    
        public static void main(String[] args) throws Exception {
            List<String> nullRowList = new ArrayList<>();
            nullRowList.add("需求内容");
            nullRowList.add("任务标题");
            XLS2CSVmra xls2csv = new XLS2CSVmra(
                    "C:/Users/Administrator/Desktop/说明文档2/XXX.xls", 
                    "电销系统", nullRowList);
            List<String[]> list = xls2csv.readerExcel();
            
            List<Map<String, String>> resultList = new LinkedList<Map<String, String>>();
            for (int i=0; i<list.size(); i++) {  
                Map<String, String> valueMap = new HashMap<String, String>();
                for (int j=0; j<list.get(i).length; j++) {  
                    if(list.get(0)[j] != null && !"".equals(list.get(0)[j])) {
                        valueMap.put(list.get(0)[j], list.get(i)[j]);  
                    }
                }  
                // 只获取数据,不要标题
                if(i > 0) {
                    resultList.add(valueMap);
                }
            }  
            System.out.println("\nresultList.size():" + resultList.size());  
            System.out.println("\nresultList:" + resultList);  
        }
    }
    

    相关文章

      网友评论

          本文标题:6、poi eventUserModel快速读取数据

          本文链接:https://www.haomeiwen.com/subject/uvwljxtx.html