Clase de herramienta XLSXCovertCSVReader (XML)

import cn.com.amway.msgcenter.console.util.StringUtil;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
importar 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;
importar 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;
importar javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.File;
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.List;

/ **

  • El uso del modo CVS para resolver archivos XLSX puede resolver eficazmente el problema del desbordamiento de la memoria del modo de usuario. POI recomienda oficialmente este modo para leer grandes datos. En el modo de usuario, la cantidad de datos es grande, la hoja es grande o hay muchos inútiles Linea en blanco
  • , Desbordamiento de memoria fácil de aparecer, el código típico para leer Excel en modo de usuario es el siguiente: FileInputStream file = new FileInputStream ("c: \ test.xlsx"); Libro de trabajo
  • wb = nuevo XSSFWorkbook (archivo);
  • @author 山人
    * /
    public class XLSXCovertCSVReader {

    / **

    • El tipo de valor de los datos se indica mediante un atributo en la celda. El valor suele estar en
    • un elemento "v" dentro de la celda.
      * /
      enum xssfDataType {
      BOOL, ERROR, FORMULA, INLINESTR, SSTINDEX, NUMBER,
      }

    / **

    • Utilice xssf_sax_API para procesar Excel, consulte: http://poi.apache.org/spreadsheet/how-to.html#xssf_sax_api
    • <p />
    • Consulte también la Norma ECMA-376, 1.a edición, parte 4, páginas 1928 y siguientes, en
    • http://www.ecma-international.org/publications/standards/Ecma-376.htm
    • <p />
    • Una versión compatible con la web es http://openiso.org/Ecma/376/Part4
      * /
      class MyXSSFSheetHandler extensions DefaultHandler {

      / **

      • Tabla con estilos
        * /
        privada StylesTable stylesTable;

      / **

      • Tabla con cadenas únicas
        * /
        private ReadOnlySharedStringsTable sharedStringsTable;

      / **

      • Destino de datos
        * /
        salida PrintStream final privada;

      / **

      • Número de columnas para leer comenzando por el extremo izquierdo
        * /
        private final int minColumnCount;

      // Establecer cuando se ve el elemento de inicio V
      private boolean vIsOpen;

      // Establecer cuando se ve el elemento de inicio de celda;
      // se usa cuando se ve el elemento de cierre de celda.
      private xssfDataType nextDataType;

      // Se utiliza para formatear valores de celda numéricos.
      formatIndex corto privado;
      private String formatString;
      formateador final privado de DataFormatter;

      privado int thisColumn = -1;
      // La última columna impresa en el flujo de salida
      private int lastColumnNumber = -1;

      // Reúne personajes tal como se ven.
      valor de StringBuffer privado;
      registro de cadena [] privado;
      Lista privada <Cadena []> filas = new ArrayList <Cadena []> ();
      private boolean isCellNull = false;

      / **

      • Acepta los objetos necesarios durante el análisis.
      • @param styles Tabla de estilos
      • @param strings Tabla de cadenas compartidas
      • @param cols Número mínimo de columnas para mostrar
      • @param target Receptor para salida
        * /
        public MyXSSFSheetHandler (estilos StylesTable, cadenas ReadOnlySharedStringsTable, int cols, PrintStream target) {
        this.stylesTable = styles;
        this.sharedStringsTable = cadenas;
        this.minColumnCount = cols;
        this.output = objetivo;
        this.value = new StringBuffer ();
        this.nextDataType = xssfDataType.NUMBER;
        this.formatter = new DataFormatter ();
        record = new String [this.minColumnCount];
        filas.clear (); // 每次 读取 都 清空 行 集合
        }

      / *

      • (no Javadoc)
      • @ver 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 atributos) arroja SAXException {

        if ("inlineStr" .equals (nombre) || "v" .equals (nombre)) {
        vIsOpen = true;
        // Limpiar el contenido de la caché
        value.setLength (0);
        }
        // c => celda
        else if ("c" .equals (nombre)) {
        // Obtiene la referencia de celda
        String r = attribute.getValue ("r");
        int firstDigit = -1;
        for (int c = 0; c <r.length (); ++ c) {
        if (Character.isDigit (r.charAt (c))) {
        firstDigit = c;
        rotura;
        }
        }
        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");
        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);
        }

        }

      }

      / *

      • (no Javadoc)
      • @ver org.xml.sax.helpers.DefaultHandler # endElement (java.lang.String, java.lang.String,
      • java.lang.String)
        * /
        public void endElement (String uri, String localName, String name) lanza SAXException {

        String thisStr = null;

        // v => contenido de una celda
        if ("v" .equals (nombre)) {
        // Procesar el contenido del valor según sea necesario.
        // Hazlo ahora, ya que los caracteres () pueden ser llamados más de una vez
        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;// 设置单元格是否为空值
        }
        record[thisColumn] = thisStr;
        // Update column
        if (thisColumn > -1) lastColumnNumber = thisColumn;

        } else if ("fila" .equals (nombre)) {

        // Print out any missing commas if needed
        if (minColumns > 0) {
            // Columns are 0 based
            if (lastColumnNumber == -1) {
                lastColumnNumber = 0;
            }
            if (isCellNull == false)// 判断是否空行
            {
                rows.add(record.clone());
                isCellNull = false;
                for (int i = 0; i < record.length; i++) {
                    record[i] = null;
                }
            }
        }
        lastColumnNumber = -1;

        }

      }

      Lista pública <String []> getRows () {
      filas de retorno;
      }

      public void setRows (Lista <String []> filas) {
      this.rows = filas;
      }

      / **

      • Captura personajes solo si un elemento adecuado está abierto. Originalmente era solo "v"; extendido
      • para inlineStr también.
        * /
        public void characters (char [] ch, int start, int length) lanza SAXException {
        if (vIsOpen) value.append (ch, start, length);
        }

      / **

      • Convierte un nombre de columna de Excel como "C" en un índice de base cero.
      • @param nombre
      • @return Índice correspondiente al nombre especificado
        /
        private int nameToColumn (String name) {
        int column = -1;
        for (int i = 0; i <name.length (); ++ i) {
        int c = name.charAt (i);
        columna = (columna + 1)
        26 + c - 'A';
        }
        columna de retorno;
        }

      private String formateDateToString (Fecha fecha) {
      SimpleDateFormat sdf = new SimpleDateFormat ("aaaa-MM-dd HH: mm: ss"); // 格式化 日期
      return sdf.format (fecha);

      }

    }

    // ///////////////////////////////////////

    OPCPackage privado xlsxPackage;
    private int minColumns;
    salida PrintStream privada;

    / **

    • Crea un nuevo convertidor XLSX -> CSV
    • @param pkg El paquete XLSX para procesar
    • Salida de @param El PrintStream para generar el CSV
    • @param minColumns El número mínimo de columnas para generar, o -1 para ningún mínimo
      * /
      public XLSXCovertCSVReader (OPCPackage pkg, PrintStream output, int minColumns) {
      this.xlsxPackage = pkg;
      this.output = salida;
      this.minColumns = minColumns;
      }

    / **

    • Analiza y muestra el contenido de una hoja usando los estilos y cadenas compartidas especificados
    • mesas.
    • @param styles
    • @param cadenas
    • @param sheetInputStream
      * /
      public List <String []> processSheet (StylesTable styles, ReadOnlySharedStringsTable strings,
      InputStream sheetInputStream) lanza IOException, ParserConfigurationException, SAXException {

      InputSource sheetSource = nuevo InputSource (sheetInputStream);
      SAXParserFactory saxFactory = SAXParserFactory.newInstance ();
      SAXParser saxParser = saxFactory.newSAXParser ();
      XMLReader sheetParser = saxParser.getXMLReader ();
      Controlador MyXSSFSheetHandler = new MyXSSFSheetHandler (estilos, cadenas, this.minColumns, this.output);
      sheetParser.setContentHandler (controlador);
      sheetParser.parse (sheetSource);
      return handler.getRows ();
      }

    / **

    • La inicialización de este controlador
    • @throws IOException
    • @throws OpenXML4JException
    • @throws ParserConfigurationException
    • @throws SAXException
      * /
      public List <String []> process () lanza IOException, OpenXML4JException, ParserConfigurationException, SAXException {

      ReadOnlySharedStringsTable strings = new ReadOnlySharedStringsTable (this.xlsxPackage);
      XSSFReader xssfReader = nuevo XSSFReader (this.xlsxPackage);
      Lista <Cadena []> lista = nulo;
      StylesTable styles = xssfReader.getStylesTable ();
      XSSFReader.SheetIterator iter = (XSSFReader.SheetIterator) xssfReader.getSheetsData ();
      while (iter.hasNext ()) {
      flujo InputStream = iter.next ();
      list = processSheet (estilos, cadenas, flujo);
      stream.close ();
      rotura;
      }
      lista de retorno;
      }

    / **

    • Leer Excel
    • @param ruta ruta del archivo
    • @param sheetName hoja 名称
    • @param minColumns Número total de columnas
    • @regreso
    • @throws SAXException
    • @throws ParserConfigurationException
    • @throws OpenXML4JException
    • @throws IOException
      * /
      public static List <String []> readerExcel (String path, int minColumns) lanza IOException, OpenXML4JException,
      ParserConfigurationException, SAXException {
      OPCPackage p = OPCPackage.open (ruta, PackageAccess.READ);
      XLSXCovertCSVReader xlsx2csv = nuevo XLSXCovertCSVReader (p, System.out, minColumns);
      Lista <Cadena []> lista = xlsx2csv.process ();
      p.close ();
      lista de retorno;
      }

    / **

    • archivo @param
    • @param minColumnas
    • @regreso
    • @throws IOException
    • @throws OpenXML4JException
    • @throws ParserConfigurationException
    • @throws SAXException
      * /
      public static List <String []> readerExcel (File file, int minColumns) lanza IOException, OpenXML4JException,
      ParserConfigurationException, SAXException {
      OPCPackage p = OPCPackage.open (file, PackageAccess.READ);
      XLSXCovertCSVReader xlsx2csv = nuevo XLSXCovertCSVReader (p, System.out, minColumns);
      Lista <Cadena []> lista = xlsx2csv.process ();
      p.close ();
      lista de retorno;
      }

    / **

    • Leer Excel
    • @param ruta ruta del archivo
    • @param sheetName hoja 名称
    • @param minColumns Número total de columnas
    • @regreso
    • @throws SAXException
    • @throws ParserConfigurationException
    • @throws OpenXML4JException
    • @throws IOException
      * /
      public static List <String []> readerExcel (InputStream in, int minColumns) lanza IOException, OpenXML4JException,
      ParserConfigurationException, SAXException {

      OPCPackage p = OPCPackage.open (in);
      XLSXCovertCSVReader xlsx2csv = new XLSXCovertCSVReader (p, System.out, minColumns);
      List <String []> list = xlsx2csv.process ();
      List <String []> newlist <= new ArrayList > ();
      p.close ();
      for (String [] str: list) {
      // Determine si hay una excepción causada por Todos los elementos son nulos en la colección excle
      if (! StringUtil.isEmpty (str [0])) {
      newlist .add (str);
      }
      }
      return newlist;
      }

}

Supongo que te gusta

Origin blog.51cto.com/7218743/2544685
Recomendado
Clasificación