2008-11-05 45 views

Respuesta

5

yo sepa no hay xlsx-bibliotecas disponibles todavía. Pero hay algunos para xls antiguos:

Una biblioteca es jxls que utiliza internamente el ya mencionado POI.

2 otros enlaces: Handle Excel files, Java libraries to read and write Excel XLS document files.

+0

Eche un vistazo también a este: https://code.google.com/p/sjxslx/ Parece que no se mantiene desde enero de 2013, pero me encantó el código. Es genial para la transmisión de grandes archivos de Excel: carga fila por fila en la memoria + las cadenas compartidas, no toda la hoja de cálculo. –

5

Tuve que hacer esto en .NET y no pude encontrar ninguna API. Mi solución fue descomprimir el .xlsx y sumergirme en la manipulación del XML. No es tan malo una vez que creas tus clases de ayudantes y tal.

Hay algunos "errores" como los nodos, todos tienen que ser ordenados de acuerdo con la forma en que Excel los espera, que no encontré en los documentos oficiales. Excel tiene su propia marca de fecha y hora, por lo que deberá crear una fórmula de conversión.

1

¿Has mirado el poorly obfuscated API?

importa:

HSSF es la implementación Java pura del Proyecto POI del formato '97 (-2007) archivo de Excel. No admite el nuevo formato de archivo .xlsx OOXML de Excel 2007, que no está basado en OLE2.

En su lugar, puede considerar el uso de JDBC-ODBC bridge.

1

No sé si está al día para Excel 2007, pero para las versiones anteriores que utilizan el JExcelAPI

+3

JExcelApi explícitamente sólo admite XLS, XLSX no. – Ken

3

Éste quizás funcione para usted, puede leer/escribir el archivo xlsx de Excel 2007. SmartXLS

2

No estoy muy contento con ninguna de las opciones, así que terminé solicitando el archivo en formato Excel 97. El POI funciona muy bien para eso. Gracias a todos por la ayuda.

5

Podría ser un poco tarde, pero el POI beta ahora es compatible con xlsx.

1

ahora cubre xlsx también.

"¿Por qué usaría docx4j para hacer esto", le escuché preguntar, "en lugar de POI, que se enfoca en xlsx y xls binarios?"

Probablemente porque te gusta JAXB (en contraposición a XML Beans), o ya estás usando docx4j para docx o pptx, y también debes poder hacer algunas cosas con xlsx.

Otra razón posible es que el jar XML Beans generado a partir de los esquemas de OpenXML es demasiado grande para sus propósitos. (Para evitar esto, POI ofrece un subconjunto 'lite': el 'gran' ooxml-schemas-1.0.jar es de 14.5 MB! Pero si necesita soportar hojas de cálculo arbitrarias, probablemente necesite el jar completo). Por el contrario, la totalidad de docx4j/pptx4j/xlsx4j pesa aproximadamente lo mismo que el subconjunto lite de POI.

Si está procesando hojas de cálculo solamente (es decir, no docx o pptx), y el párrafo anterior no es una preocupación para usted, entonces probablemente sea mejor que use POI.

4

Prueba esto: el archivo

  1. Descomprimir XLSX
  2. leer archivos XML
  3. datos de redacción y uso

código Ejemplo:

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(); 
    } 
} 

donde la clase libro de trabajo:

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

y la hoja de trabajo de clase:

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>();} 

y clase 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;} 

y clase 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;} 

y clase Columna:

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

y span class:

public class Span { 
    Integer id = null; 
    String topLeft = null; 
    String bottomRight = null; 
} 
+0

¿Qué son las clases 'Span' y' Column'? – HyperNeutrino

+0

ver la nueva versión – Koss

1

Puede utilizar Apache Tika para ello:

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

Tika utiliza Apache POI para analizar archivos XLSX.

Aquí hay algunos usage examples para Tiki.

Alternativamente, si desea manejar cada celda de la hoja de cálculo de forma individual, esto es una manera de hacer esto con PDI:

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); 
}