Advertisement
Guest User

Untitled

a guest
Aug 11th, 2015
583
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 12.26 KB | None | 0 0
  1. /* ====================================================================
  2.    Licensed to the Apache Software Foundation (ASF) under one or more
  3.    contributor license agreements.  See the NOTICE file distributed with
  4.    this work for additional information regarding copyright ownership.
  5.    The ASF licenses this file to You under the Apache License, Version 2.0
  6.    (the "License"); you may not use this file except in compliance with
  7.    the License.  You may obtain a copy of the License at
  8.  
  9.        http://www.apache.org/licenses/LICENSE-2.0
  10.  
  11.    Unless required by applicable law or agreed to in writing, software
  12.    distributed under the License is distributed on an "AS IS" BASIS,
  13.    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.    See the License for the specific language governing permissions and
  15.    limitations under the License.
  16. ==================================================================== */
  17.  
  18. package cz.eurosoftworks.excelimporter;
  19.  
  20.  
  21. import cz.eurosoftworks.excelimporter.model.CellTypes;
  22. import cz.eurosoftworks.excelimporter.model.CellValue;
  23. import cz.eurosoftworks.excelimporter.model.Record;
  24. import org.apache.poi.ss.usermodel.BuiltinFormats;
  25. import org.apache.poi.ss.usermodel.DataFormatter;
  26. import org.apache.poi.xssf.eventusermodel.ReadOnlySharedStringsTable;
  27. import org.apache.poi.xssf.eventusermodel.XSSFSheetXMLHandler;
  28. import org.apache.poi.xssf.model.StylesTable;
  29. import org.apache.poi.xssf.usermodel.XSSFCellStyle;
  30. import org.apache.poi.xssf.usermodel.XSSFRichTextString;
  31. import org.xml.sax.Attributes;
  32. import org.xml.sax.SAXException;
  33. import org.xml.sax.helpers.DefaultHandler;
  34.  
  35. import java.util.ArrayList;
  36. import java.util.List;
  37.  
  38. /**
  39.  * See org.xml.sax.helpers.DefaultHandler javadocs
  40.  */
  41. class SheetHandler extends DefaultHandler {
  42.     enum xssfDataType {
  43.         BOOL,
  44.         ERROR,
  45.         FORMULA,
  46.         INLINESTR,
  47.         SSTINDEX,
  48.         NUMBER,
  49.     }
  50.     private ExcelReader excelReader;
  51.     private List<String> headers = new ArrayList<>();
  52.     private boolean recordRows = false;
  53.  
  54.     /**
  55.      * Table with styles
  56.      */
  57.     private StylesTable stylesTable;
  58.  
  59.     /**
  60.      * Table with unique strings
  61.      */
  62.     private ReadOnlySharedStringsTable sharedStringsTable;
  63.     // Set when V start element is seen
  64.     private boolean vIsOpen;
  65.     // Set when cell start element is seen;
  66.     // used when cell close element is seen.
  67.     private xssfDataType nextDataType;
  68.     // Used to format numeric cell values.
  69.     private short formatIndex;
  70.     private String formatString;
  71.     private final DataFormatter formatter;
  72.     private int thisColumn = -1;
  73.     // The last column printed to the output stream
  74.     private int lastColumnNumber = -1;
  75.     // Gathers characters as they are seen.
  76.     private StringBuffer value;
  77.  
  78.     private String lastColumn;
  79.     private int columns;
  80.     private Record lastRecord;
  81.     private boolean firstColumn;
  82.     private int lastColumnNum;
  83.     private boolean maybeNull;
  84.  
  85.  
  86.     public SheetHandler(ReadOnlySharedStringsTable sst, ExcelReader excelReader, StylesTable styles) {
  87.         this.sharedStringsTable = sst;
  88.         this.excelReader = excelReader;
  89.         this.formatter = new DataFormatter();
  90.         this.stylesTable = styles;
  91.         this.value = new StringBuffer();
  92.     }
  93.  
  94.  
  95.     public void startElement(String uri, String localName, String name,
  96.                              Attributes attributes) throws SAXException {
  97.  
  98.         if ("inlineStr".equals(name) || "v".equals(name)) {
  99.             vIsOpen = true;
  100.             // Clear contents cache
  101.             value.setLength(0);
  102.         }
  103.         // c => cell
  104.         else if ("c".equals(name)) {
  105.             lastColumn = attributes.getValue("r");
  106.             if ( lastColumn.equals("A2")) {
  107.                 recordRows = true;
  108.                 excelReader.setHeaders(headers);
  109.                 columns = headers.size();
  110.                 lastRecord = new Record();
  111.             }
  112.             if (lastColumn.replaceAll("[\\d]", "").equals("A") && !lastColumn.equals("A1")) {
  113.                 if (lastRecord.cellValues.size() > 0) {
  114.                     excelReader.addRecord(lastRecord);
  115.                 }
  116.                 lastRecord = new Record();
  117.                 firstColumn = true;
  118.             } else {
  119.                 firstColumn = false;
  120.             }
  121.  
  122.  
  123.             // Get the cell reference
  124.             String r = attributes.getValue("r");
  125.             int firstDigit = -1;
  126.             for (int c = 0; c < r.length(); ++c) {
  127.                 if (Character.isDigit(r.charAt(c))) {
  128.                     firstDigit = c;
  129.                     break;
  130.                 }
  131.             }
  132.  
  133.             // Set up defaults.
  134.             maybeNull=false;
  135.             this.nextDataType = xssfDataType.NUMBER;
  136.             this.formatIndex = -1;
  137.             this.formatString = null;
  138.             String cellType = attributes.getValue("t");
  139.             String cellStyleStr = attributes.getValue("s");
  140.             if ("b".equals(cellType))
  141.                 nextDataType = xssfDataType.BOOL;
  142.             else if ("e".equals(cellType))
  143.                 nextDataType = xssfDataType.ERROR;
  144.             else if ("inlineStr".equals(cellType))
  145.                 nextDataType = xssfDataType.INLINESTR;
  146.             else if ("s".equals(cellType))
  147.                 nextDataType = xssfDataType.SSTINDEX;
  148.             else if ("str".equals(cellType))
  149.                 nextDataType = xssfDataType.FORMULA;
  150.             else if (cellType == null) {
  151.                 maybeNull=true;
  152.             } else if (cellStyleStr != null) {
  153.                 // It's a number, but almost certainly one
  154.                 //  with a special style or format
  155.                 int styleIndex = Integer.parseInt(cellStyleStr);
  156.                 XSSFCellStyle style = stylesTable.getStyleAt(styleIndex);
  157.                 this.formatIndex = style.getDataFormat();
  158.                 this.formatString = style.getDataFormatString();
  159.                 if (this.formatString == null)
  160.                     this.formatString = BuiltinFormats.getBuiltinFormat(this.formatIndex);
  161.             }
  162.         }
  163.         XSSFSheetXMLHandler sd;
  164.     }
  165.  
  166.     /*
  167.        * (non-Javadoc)
  168.        * @see org.xml.sax.helpers.DefaultHandler#endElement(java.lang.String, java.lang.String, java.lang.String)
  169.        */
  170.     public void endElement(String uri, String localName, String name) throws SAXException {
  171.         String thisStr;
  172.  
  173.         // v => contents of a cell
  174.         if ("v".equals(name)) {
  175.             maybeNull = false;
  176.             if (recordRows) {
  177.                 if (lastColumn.equals("B2")) {
  178.                     System.out.println("stuj");
  179.                 }
  180.                 // Process the value contents as required.
  181.                 // Do now, as characters() may be called more than once
  182.                 lastColumnNum = nameToColumn(lastColumn);
  183.                 CellValue<Object> cv = new CellValue<>();
  184.                 switch (nextDataType) {
  185.                     case BOOL:
  186.                         char first = value.charAt(0);
  187.                         if (first == '0') {
  188.                             cv.set(CellTypes.BOOLEAN, false);
  189.                         } else {
  190.                             cv.set(CellTypes.BOOLEAN, true);
  191.                         }
  192.                         break;
  193.  
  194.                     case ERROR:
  195.                         cv.set(CellTypes.STRING, "ERROR: " + value.toString());
  196.                         break;
  197.  
  198.                     case FORMULA:
  199.                         // A formula could result in a string value,
  200.                         // so always add double-quote characters.
  201.                         cv.set(CellTypes.STRING, value.toString());
  202.                         break;
  203.  
  204.                     case INLINESTR:
  205.                         // TODO: have seen an example of this, so it's untested.
  206.                         XSSFRichTextString rtsi = new XSSFRichTextString(value.toString());
  207.                         cv.set(CellTypes.STRING,  rtsi.toString());
  208.                         break;
  209.  
  210.                     case SSTINDEX:
  211.                         String sstIndex = value.toString();
  212.                         try {
  213.                             int idx = Integer.parseInt(sstIndex);
  214.                             XSSFRichTextString rtss = new XSSFRichTextString(sharedStringsTable.getEntryAt(idx));
  215.                             cv.set(CellTypes.STRING, rtss.toString());
  216.                         }
  217.                         catch (NumberFormatException ex) {
  218.                             ex.printStackTrace();
  219.                         }
  220.                         break;
  221.  
  222.                     case NUMBER:
  223.                         String n = value.toString();
  224.                         if (this.formatString != null) {
  225.                             thisStr = formatter.formatRawCellContents(Double.parseDouble(n), this.formatIndex, this.formatString);
  226.                             try {
  227.                                 int intV = Integer.valueOf(thisStr);
  228.                                 cv.set(CellTypes.INT, intV);
  229.                             } catch (NumberFormatException ignored) {}
  230.                             if (cv.getType() == null) {
  231.                                 try {
  232.                                     Double doubleV = Double.valueOf(thisStr);
  233.                                     cv.set(CellTypes.DOUBLE, doubleV);
  234.                                 } catch (NumberFormatException e) {
  235.                                     cv.set(CellTypes.STRING, thisStr);
  236.                                 }
  237.                             }
  238.                         } else {
  239.                             thisStr = n;
  240.                             try {
  241.                                 int intV = Integer.valueOf(thisStr);
  242.                                 cv.set(CellTypes.INT, intV);
  243.                             } catch (NumberFormatException ignored) {}
  244.                             if (cv.getType() == null) {
  245.                                 try {
  246.                                     Double doubleV = Double.valueOf(thisStr);
  247.                                     cv.set(CellTypes.DOUBLE, doubleV);
  248.                                 } catch (NumberFormatException e) {
  249.                                     cv.set(CellTypes.STRING, thisStr);
  250.                                 }
  251.                             }
  252.                         }
  253.                         break;
  254.  
  255.                     default:
  256.                         cv.set(CellTypes.STRING, "Unexpected type: " + nextDataType);
  257.                         break;
  258.                 }
  259.  
  260.                 lastRecord.cellValues.add(cv);
  261.             } else {
  262.                 String sstIndex = value.toString();
  263.                 try {
  264.                     int idx = Integer.parseInt(sstIndex);
  265.                     XSSFRichTextString rtss = new XSSFRichTextString(sharedStringsTable.getEntryAt(idx));
  266.                     headers.add(rtss.toString());
  267.                 }
  268.                 catch (NumberFormatException ex) {
  269.                     ex.printStackTrace();
  270.                 }
  271.             }
  272.  
  273.             //System.out.println(thisStr);
  274.             // Output after we've seen the string contents
  275.             // Emit commas for any fields that were missing on this row
  276.             if (lastColumnNumber == -1) {
  277.                 lastColumnNumber = 0;
  278.             }
  279.  
  280.             // Update column
  281.             if (thisColumn > -1)
  282.                 lastColumnNumber = thisColumn;
  283.  
  284.         } else if ("c".equals(name) && lastRecord != null && maybeNull) {
  285.             CellValue<Object> cv = new CellValue();
  286.             cv.set(CellTypes.NULL, null);
  287.             lastRecord.cellValues.add(cv);
  288.         }
  289.  
  290.  
  291.     }
  292.  
  293.     /**
  294.      * Captures characters only if a suitable element is open.
  295.      * Originally was just "v"; extended for inlineStr also.
  296.      */
  297.     public void characters(char[] ch, int start, int length)
  298.             throws SAXException {
  299.         if (vIsOpen)
  300.             value.append(ch, start, length);
  301.     }
  302.  
  303.     /**
  304.      *
  305.      *
  306.      * @param name
  307.      * @return Index corresponding to the specified name
  308.      */
  309.     private int nameToColumn(String name) {
  310.         int column = -1;
  311.         for (int i = 0; i < name.length(); ++i) {
  312.             int c = name.charAt(i);
  313.             column = (column + 1) * 26 + c - 'A';
  314.         }
  315.         return column;
  316.     }
  317. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement