Classe d'outils XLSXCovertCSVReader (XML)

import cn.com.amway.msgcenter.console.util.StringUtil;
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;

import javax.xml.parsers.ParserConfigurationException;
import 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;

/ **

  • L'utilisation du mode CVS pour résoudre les fichiers XLSX peut résoudre efficacement le problème du débordement de mémoire en mode utilisateur. Ce mode est officiellement recommandé par POI pour lire des données volumineuses. En mode utilisateur, la quantité de données est importante, la feuille est volumineuse ou il y en a beaucoup qui sont inutiles Ligne blanche
  • , Facile à afficher le débordement de mémoire, le code typique pour lire Excel en mode utilisateur est le suivant: FileInputStream file = new FileInputStream ("c: \ test.xlsx"); Workbook
  • wb = nouveau XSSFWorkbook (fichier);
  • @author 山人
    * /
    classe publique XLSXCovertCSVReader {

    / **

    • Le type de la valeur de données est indiqué par un attribut sur la cellule. La valeur est généralement en
    • un élément "v" dans la cellule.
      * /
      enum xssfDataType {
      BOOL, ERROR, FORMULA, INLINESTR, SSTINDEX, NUMBER,
      }

    / **

    • Utilisez xssf_sax_API pour traiter Excel, veuillez vous référer à: http://poi.apache.org/spreadsheet/how-to.html#xssf_sax_api
    • <p />
    • Voir également la norme ECMA-376, 1ère édition, partie 4, pages 1928ff, à
    • http://www.ecma-international.org/publications/standards/Ecma-376.htm
    • <p />
    • Une version Web est http://openiso.org/Ecma/376/Part4
      * /
      class MyXSSFSheetHandler extend DefaultHandler {

      / **

      • Tableau avec styles
        * /
        privé StylesTable stylesTable;

      / **

      • Table avec des chaînes uniques
        * /
        private ReadOnlySharedStringsTable sharedStringsTable;

      / **

      • Destination des données
        * /
        sortie PrintStream finale privée;

      / **

      • Nombre de colonnes à lire en commençant par l' extrême gauche
        * /
        private final int minColumnCount;

      // Défini lorsque l'élément de démarrage V est vu
      private boolean vIsOpen;

      // Défini lorsque l'élément de début de cellule est vu;
      // utilisé lorsque l'élément de fermeture de cellule est vu.
      private xssfDataType nextDataType;

      // Utilisé pour mettre en forme les valeurs numériques des cellules.
      privé court formatIndex;
      private String formatString;
      formateur DataFormatter final privé;

      private int thisColumn = -1;
      // La dernière colonne imprimée dans le flux de sortie
      private int lastColumnNumber = -1;

      // Rassemble les caractères tels qu'ils sont vus.
      valeur StringBuffer privée;
      enregistrement de chaîne privé [];
      Liste privée <String []> rows = new ArrayList <String []> ();
      private boolean isCellNull = false;

      / **

      • Accepte les objets nécessaires lors de l'analyse.
      • @param styles Tableau des styles
      • @param strings Tableau des chaînes partagées
      • @param cols Nombre minimum de colonnes à afficher
      • @param target Sink pour la sortie
        * /
        public MyXSSFSheetHandler (StylesTable styles, ReadOnlySharedStringsTable strings, int cols, PrintStream target) {
        this.stylesTable = styles;
        this.sharedStringsTable = chaînes;
        this.minColumnCount = cols;
        this.output = cible;
        this.value = new StringBuffer ();
        this.nextDataType = xssfDataType.NUMBER;
        this.formatter = new DataFormatter ();
        record = new String [this.minColumnCount];
        rows.clear (); // 每次 读取 都 清空 行 集合
        }

      / *

      • (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) lève SAXException {

        if ("inlineStr" .equals (name) || "v" .equals (name)) {
        vIsOpen = true;
        // Effacer le cache de contenu
        value.setLength (0);
        }
        // c => cell
        else if ("c" .equals (name)) {
        // Récupère la référence de la cellule
        String r = attributes.getValue ("r");
        int firstDigit = -1;
        pour (int c = 0; c <r.length (); ++ c) {
        if (Character.isDigit (r.charAt (c))) {
        firstDigit = c;
        Pause;
        }
        }
        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);
        }

        }

      }

      / *

      • (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) lève SAXException {

        String thisStr = null;

        // v => contenu d'une cellule
        if ("v" .equals (name)) {
        // Traite le contenu de la valeur selon les besoins.
        // Faites maintenant, car les caractères () peuvent être appelés plus d'une fois
        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 ("ligne" .equals (nom)) {

        // 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;

        }

      }

      public List <String []> getRows () {
      return rows;
      }

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

      / **

      • Capture les caractères uniquement si un élément approprié est ouvert. A l'origine était juste "v"; élargi
      • pour inlineStr également.
        * /
        public void characters (char [] ch, int start, int length) lance SAXException {
        if (vIsOpen) value.append (ch, start, length);
        }

      / **

      • Convertit un nom de colonne Excel tel que «C» en un index de base zéro.
      • @param nom
      • @return Index correspondant au nom spécifié
        /
        int privé nameToColumn (String name) {
        int column = -1;
        pour (int i = 0; i <nom.longueur (); ++ i) {
        int c = nom.charAt (i);
        colonne = (colonne + 1)
        26 + c - 'A';
        }
        colonne de retour;
        }

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

      }

    }

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

    OPCPackage privé xlsxPackage;
    private int minColumns;
    sortie PrintStream privée;

    / **

    • Crée un nouveau convertisseur XLSX -> CSV
    • @param pkg Le package XLSX à traiter
    • @param output Le PrintStream pour sortir le CSV
    • @param minColumns Le nombre minimum de colonnes à afficher, ou -1 pour aucun minimum
      * /
      public XLSXCovertCSVReader (OPCPackage pkg, PrintStream output, int minColumns) {
      this.xlsxPackage = pkg;
      this.output = sortie;
      this.minColumns = minColumns;
      }

    / **

    • Analyse et affiche le contenu d'une feuille en utilisant les styles et les chaînes partagées spécifiés
    • les tables.
    • @param styles
    • @param chaînes
    • @param sheetInputStream
      * /
      public List <String []> processSheet (StylesTable styles, ReadOnlySharedStringsTable strings,
      InputStream sheetInputStream) lève 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, chaînes, this.minColumns, this.output);
      sheetParser.setContentHandler (gestionnaire);
      sheetParser.parse (sheetSource);
      return handler.getRows ();
      }

    / **

    • L'initialisation de ce gestionnaire
    • @throws IOException
    • @throws OpenXML4JException
    • @throws ParserConfigurationException
    • @throws SAXException
      * /
      public List <String []> process () lève IOException, OpenXML4JException, ParserConfigurationException, SAXException {

      ReadOnlySharedStringsTable strings = new ReadOnlySharedStringsTable (this.xlsxPackage);
      XSSFReader xssfReader = nouveau XSSFReader (this.xlsxPackage);
      List <String []> list = null;
      StylesTable styles = xssfReader.getStylesTable ();
      XSSFReader.SheetIterator iter = (XSSFReader.SheetIterator) xssfReader.getSheetsData ();
      while (iter.hasNext ()) {
      Flux InputStream = iter.next ();
      list = processSheet (styles, chaînes, flux);
      stream.close ();
      Pause;
      }
      liste de retour;
      }

    / **

    • Lire Excel
    • @param path chemin du fichier
    • @param sheetName Sheet 名称
    • @param minColumns Nombre total de colonnes
    • @revenir
    • @throws SAXException
    • @throws ParserConfigurationException
    • @throws OpenXML4JException
    • @throws IOException
      * /
      public static List <String []> readerExcel (String path, int minColumns) jette IOException, OpenXML4JException,
      ParserConfigurationException, SAXException {
      OPCPackage p = OPCPackage.open (path, PackageAccess.READ);
      XLSXCovertCSVReader xlsx2csv = nouveau XLSXCovertCSVReader (p, System.out, minColumns);
      List <String []> list = xlsx2csv.process ();
      p.close ();
      liste de retour;
      }

    / **

    • Fichier @param
    • @param minColonnes
    • @revenir
    • @throws IOException
    • @throws OpenXML4JException
    • @throws ParserConfigurationException
    • @throws SAXException
      * /
      public static List <String []> readerExcel (File file, int minColumns) jette IOException, OpenXML4JException,
      ParserConfigurationException, SAXException {
      OPCPackage p = OPCPackage.open (fichier, PackageAccess.READ);
      XLSXCovertCSVReader xlsx2csv = nouveau XLSXCovertCSVReader (p, System.out, minColumns);
      List <String []> list = xlsx2csv.process ();
      p.close ();
      liste de retour;
      }

    / **

    • Lire Excel
    • @param path chemin du fichier
    • @param sheetName Sheet 名称
    • @param minColumns Nombre total de colonnes
    • @revenir
    • @throws SAXException
    • @throws ParserConfigurationException
    • @throws OpenXML4JException
    • @throws IOException
      * /
      public static List <String []> readerExcel (InputStream in, int minColumns) jette 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 ();
      pour (String [] str: liste) {
      // Déterminer s'il y a une exception provoquée par tous les éléments sont nuls dans la excle collection
      if (StringUtil.isEmpty (str [0])) {
      newlist .add (str);
      }
      }
      return newlist;
      }

}

Je suppose que tu aimes

Origine blog.51cto.com/7218743/2544685
conseillé
Classement