web-dev-qa-db-fra.com

Lire le fichier XLSX en Java

Je dois lire un fichier Excel 2007 XLSX dans une application Java. Quelqu'un connaît-il une bonne API pour accomplir cette tâche?

32
MrPortico

AFAIK il n'y a pas encore de bibliothèques xlsx disponibles. Mais il y en a pour les vieux xls:

Une bibliothèque est jxls qui utilise en interne le POI déjà mentionné.

2 autres liens: gérer les fichiers Excel , bibliothèques Java pour lire et écrire des fichiers de document Excel XLS .

5
Tobias Schulte

Apache POI 3.5 ont ajouté le support à tous les OOXML (docx, xlsx, etc.)

Voir le sous-projet XSSF

50
David Rabinowitz

J'ai dû le faire dans .NET et je n'ai trouvé aucune API. Ma solution était de décompresser le .xlsx et de plonger directement dans la manipulation du XML. Ce n'est pas si mal une fois que vous avez créé vos classes d'assistance et autres.

Il y a des "accrochages" comme les nœuds qui doivent tous être triés selon la façon dont Excel les attend, que je n'ai pas trouvé dans les documents officiels. Excel a son propre horodatage de la date, vous devrez donc créer une formule de conversion.

5
hova

Peut-être un peu tard, mais le POI bêta prend désormais en charge xlsx.

5
Galbrezu

Essaye ça:

  1. Décompressez le fichier XLSX
  2. Lire des fichiers XML
  3. Composer et utiliser des données

Exemple de code:

    public Workbook getTemplateData(String xlsxFile) {
    Workbook workbook = new Workbook();
    parseSharedStrings(xlsxFile);
    parseWorkesheet(xlsxFile, workbook);
    parseComments(xlsxFile, workbook);
    for (Worksheet worksheet : workbook.sheets) {
        worksheet.dimension = manager.getDimension(worksheet);
    }

    return workbook;
}

private void parseComments(String tmpFile, Workbook workbook) {
    try {
        FileInputStream fin = new FileInputStream(tmpFile);
        final ZipInputStream zin = new ZipInputStream(fin);
        InputStream in = getInputStream(zin);
        while (true) {
            ZipEntry entry = zin.getNextEntry();
            if (entry == null)
                break;

            String name = entry.getName();
            if (name.endsWith(".xml")) { //$NON-NLS-1$
                if (name.contains(COMMENTS)) {
                    parseComments(in, workbook);
                }
            }
            zin.closeEntry();
        }
        in.close();
        zin.close();
        fin.close();
    } catch (FileNotFoundException e) {
        System.out.println(e);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

private void parseComments(InputStream in, Workbook workbook) {
    try {
        DefaultHandler handler = getCommentHandler(workbook);
        SAXParser saxParser = getSAXParser();
        saxParser.parse(in, handler);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

private DefaultHandler getCommentHandler(Workbook workbook) {
    final Worksheet ws = workbook.sheets.get(0);
    return new DefaultHandler() {
        String lastTag = "";
        private Cell ccell;

        @Override
        public void startElement(String uri, String localName,
                String qName, Attributes attributes) throws SAXException {
            lastTag = qName;
            if (lastTag.equals("comment")) {
                String cellName = attributes.getValue("ref");
                int r = manager.getRowIndex(cellName);
                int c = manager.getColumnIndex(cellName);
                Row row = ws.rows.get(r);
                if (row == null) {
                    row = new Row();
                    row.index = r;
                    ws.rows.put(r, row);
                }
                ccell = row.cells.get(c);
                if (ccell == null) {
                    ccell = new Cell();
                    ccell.cellName = cellName;
                    row.cells.put(c, ccell);
                }
            }
        }

        @Override
        public void characters(char[] ch, int start, int length)
                throws SAXException {
            String val = "";
            if (ccell != null && lastTag.equals("t")) {
                for (int i = start; i < start + length; i++) {
                    val += ch[i];
                }
                if (ccell.comment == null)
                    ccell.comment = val;
                else {
                    ccell.comment += val;
                }
            }
        }
    };
}

private void parseSharedStrings(String tmpFile) {
    try {
        FileInputStream fin = new FileInputStream(tmpFile);
        final ZipInputStream zin = new ZipInputStream(fin);
        InputStream in = getInputStream(zin);
        while (true) {
            ZipEntry entry = zin.getNextEntry();
            if (entry == null)
                break;
            String name = entry.getName();
            if (name.endsWith(".xml")) { //$NON-NLS-1$
                if (name.startsWith(SHARED_STRINGS)) {
                    parseStrings(in);
                }
            }
            zin.closeEntry();
        }
        in.close();
        zin.close();
        fin.close();
    } catch (FileNotFoundException e) {
        System.out.println(e);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

public void parseWorkesheet(String tmpFile, Workbook workbook) {
    try {
        FileInputStream fin = new FileInputStream(tmpFile);
        final ZipInputStream zin = new ZipInputStream(fin);
        InputStream in = getInputStream(zin);
        while (true) {
            ZipEntry entry = zin.getNextEntry();
            if (entry == null)
                break;

            String name = entry.getName();
            if (name.endsWith(".xml")) { //$NON-NLS-1$
                if (name.contains("worksheets")) {
                    Worksheet worksheet = new Worksheet();
                    worksheet.name = name;
                    parseWorksheet(in, worksheet);
                    workbook.sheets.add(worksheet);
                }
            }
            zin.closeEntry();
        }
        in.close();
        zin.close();
        fin.close();
    } catch (FileNotFoundException e) {
        System.out.println(e);
    } catch (IOException e) {
        e.printStackTrace();
    }
}

public void parseWorksheet(InputStream in, Worksheet worksheet)
        throws IOException {
    // read sheet1 sharedStrings
    // styles, strings, formulas ...
    try {
        DefaultHandler handler = getDefaultHandler(worksheet);
        SAXParser saxParser = getSAXParser();
        saxParser.parse(in, handler);
    } catch (SAXException e) {
        e.printStackTrace();
    } catch (ParserConfigurationException e) {
        e.printStackTrace();
    }
}

où classe Classeur:

public class Workbook {
Integer id = null;
public List<Worksheet> sheets = new ArrayList<Worksheet>();}

et classe Worksheet:

public class Worksheet {
public Integer id = null;
public String name = null;
public String dimension = null;
public Map<Integer, Row> rows = new TreeMap<Integer, Row>();
public Map<Integer, Column> columns = new TreeMap<Integer, Column>();
public List<Span> spans = new ArrayList<Span>();}

et classe Row:

public class Row {
public Integer id = null;
public Integer index = null;
public Row tmpRow = null;
public Style style = null;
public Double height = null;
public Map<Integer,Cell> cells = new TreeMap<Integer, Cell>();
public String spans = null;
public Integer customHeight = null;}

et classe Cell:

public class Cell {
public Integer id = null;
public Integer rowIndex = null;
public Integer colIndex = null;
public String cellName = null;
public String text = null;
public String formula = null;
public String comment = null;
public Style style = null;
public Object value = null;
public Cell tmpCell = null;}

et classe de colonne:

public class Column {
    public Integer index = null;
    public Style style = null;
    public String width = null;
    public Column tmpColumn = null;
}

et classe Span:

public class Span {
    Integer id = null;
    String topLeft = null;
    String bottomRight = null;
}
5
Koss

Celui-ci peut fonctionner pour vous, il peut lire/écrire un fichier xlsx Excel 2007. SmartXLS

3
rya

Je ne suis pas très satisfait de l'une des options, j'ai donc demandé le fichier au format Excel 97. Le POI fonctionne très bien pour cela. Merci à tous pour l'aide.

2
MrPortico

Avez-vous regardé le API mal obscurci ?

Ça ne fait rien:

HSSF est la pure implémentation du projet POI Java du format de fichier Excel 97 (-2007). Il ne prend pas en charge le nouveau format de fichier OOXML Excel 2007 .xlsx, qui n'est pas basé sur OLE2.

Vous pourriez envisager d'utiliser à la place un pont JDBC-ODBC .

1
Josh

Aspose.Cells pour Java prend en charge le format XLSX. Vous pouvez trouver plus de détails et une aide supplémentaire dans Aspose.Cells pour Java Documentation . Veuillez voir si cela aide.

Divulgation: Je travaille comme développeur évangéliste chez Aspose.

1
Shahzad Latif

Je ne sais pas s'il est à jour pour Excel 2007, mais pour les versions antérieures, j'utilise JExcelAPI

1
NR.

docx4j couvre désormais également xlsx.

"Pourquoi voudriez-vous utiliser docx4j pour faire cela", je vous entends demander, "plutôt que POI, qui se concentre sur xlsx et xls binaires?"

Probablement parce que vous aimez JAXB (par opposition aux XML Beans), ou que vous utilisez déjà docx4j pour docx ou pptx, et que vous devez également pouvoir faire des choses avec xlsx.

Une autre raison possible est que le jar XML Beans généré à partir des schémas OpenXML est trop grand pour vos besoins. (Pour contourner ce problème, POI propose un sous-ensemble `` léger '': le `` grand '' ooxml-schemas-1.0.jar fait 14,5 Mo! Mais si vous devez prendre en charge des feuilles de calcul arbitraires, vous aurez probablement besoin du pot complet). En revanche, l'ensemble de docx4j/pptx4j/xlsx4j pèse à peu près le même que le sous-ensemble lite de POI.

Si vous traitez uniquement des feuilles de calcul (c.-à-d. Pas docx ou pptx), et que le paragraphe précédent ne vous concerne pas, alors il vaut mieux utiliser POI.

1
JasonPlutext

Vous pouvez utiliser Apache Tika pour cela:

String parse(File xlsxFile) {
    return new Tika().parseToString(xlsxFile);
}

Tika utilise POI Apache pour analyser les fichiers XLSX.

Voici quelques exemples d'utilisation pour Tiki.

Alternativement, si vous souhaitez gérer chaque cellule de la feuille de calcul individuellement, voici une façon de le faire avec POI:

void parse(File xlsx) {
    try (XSSFWorkbook workbook = new XSSFWorkbook(xlsx)) {
        // Handle each cell in each sheet
        workbook.forEach(sheet -> sheet.forEach(row -> row.forEach(this::handle)));
    }
    catch (InvalidFormatException | IOException e) {
        System.out.println("Can't parse file " + xlsx);
    }
}

void handle(Cell cell) {
    final String cellContent;
    switch (cell.getCellType()) {
        case Cell.CELL_TYPE_STRING:
            cellContent = cell.getStringCellValue();
            break;
        case Cell.CELL_TYPE_NUMERIC:
            cellContent = String.valueOf(cell.getNumericCellValue());
            break;
        case Cell.CELL_TYPE_BOOLEAN:
            cellContent = String.valueOf(cell.getBooleanCellValue());
            break;
        default:
            cellContent = "Don't know how to handle cell " + cell;
    }
    System.out.println(cellContent);
}
1
Matthias Braun

Si vous souhaitez travailler avec xlsx, vous devrez utiliser le package org.Apache.poi.ss. Ce paquet a la classe XSSF, qui peut être utilisée pour analyser le fichier xlxs. Cet exemple de code fonctionne sur Excel 2007 ou version ultérieure (.xlsx)

OPCPackage pkg = OPCPackage.open(new ByteArrayInputStream(data));
            Workbook wb = new XSSFWorkbook(pkg);
            Sheet sheet = wb.getSheetAt(0);
            Iterator<Row> rows = sheet.rowIterator();

        while (rows.hasNext()) {
            int j = 5;
            Person person= new Person ();
            Row row = rows.next();
            if (row.getRowNum() > 0) {
                person.setPersonId((int)(row.getCell(0).getNumericCellValue()));
                person.setFirstName(row.getCell(1).getStringCellValue());
                person.setLastName(row.getCell(2).getStringCellValue());
                person.setGroupId((int)(row.getCell(3).getNumericCellValue()));
                person.setUserName(row.getCell(4).getStringCellValue());
                person.setCreditId((int)(row.getCell(5).getNumericCellValue()));
            }

        }

Excel 1998-2003 file (.xls) - you may use HSSF library.
  just use :  Workbook wb = new HSSFWorkbook(pkg);
0
patidarsnju