2008-11-05 11 views

ответ

5

AFAIK нет XLSX-библиотеки пока недоступны. Но есть некоторые для старых xls:

Одна библиотека jxls, которая внутренне использует уже упомянутые POI.

2 другие ссылки: Handle Excel files, Java libraries to read and write Excel XLS document files.

+0

Посмотрите также на этот: https://code.google.com/p/sjxslx/ Он, похоже, не поддерживается с января 2013 года, но мне понравился код. Он отлично подходит для потоковой передачи больших файлов Excel - он загружает строки за строкой в ​​память + общие строки, а не всю электронную таблицу. – 2015-01-18 16:35:49

5

Я должен был сделать это в .NET, и я не смог найти API. Мое решение состояло в том, чтобы разархивировать .xlsx и погрузиться прямо в управление XML. Это не так плохо, как только вы создаете свои вспомогательные классы и тому подобное.

Есть некоторые «gotchas», такие как узлы, все они должны быть отсортированы в соответствии с тем, как ожидает их excel, чего я не нашел в официальных документах. Excel имеет собственную временную метку даты, поэтому вам нужно будет сделать формулу преобразования.

1

Вы посмотрели poorly obfuscated API?

Nevermind:

HSSF чистая реализация Java ТОИ проекта формата '97 файла (-2007) Excel. Он не поддерживает новый формат файла OXXML формата Excel .xlsx, который не основан на OLE2.

Вместо этого вы можете использовать JDBC-ODBC bridge.

1

Я не знаю, если он до настоящего времени для Excel 2007, но и для более ранних версий я использую JExcelAPI

+3

JExcelApi поддерживает явно только XLS, XLSX не. – Ken 2011-01-05 19:27:45

3

Этот, возможно, работает на вас, он может читать/писать Excel 2007 xlsx. SmartXLS

2

Я не очень доволен ни одним из вариантов, поэтому в итоге я запросил файл в формате Excel 97. POI отлично подходит для этого. Спасибо всем за помощь.

5

Возможно, будет немного поздно, но бета-версия POI теперь поддерживает xlsx.

1

docx4j теперь покрывает XLSX, а также.

«Зачем вам использовать docx4j для этого», я слышал, вы спрашиваете: «а не POI, который фокусируется на xlsx и двоичных xls?»

Возможно, потому что вам нравится JAXB (в отличие от XML Beans), или вы уже используете docx4j для docx или pptx и должны иметь возможность делать некоторые вещи с помощью xlsx.

Другая возможная причина заключается в том, что jar XML Beans, генерируемый из схем OpenXML, слишком велик для ваших целей. (Чтобы обойти это, POI предлагает подпрограмму «lite»: «большой» ooxml-schemas-1.0.jar - 14,5 МБ! Но если вам нужно поддерживать произвольные электронные таблицы, вам, вероятно, понадобится полная банка). Напротив, весь docx4j/pptx4j/xlsx4j весит примерно столько же, сколько подмножество POI.

Если вы обрабатываете только электронные таблицы (т. Е. Не docx или pptx), а предыдущий пункт не является для вас проблемой, тогда вам, вероятно, будет лучше всего использовать POI.

1

Aspose.Cells for Java поддерживает формат XLSX. Вы можете найти более подробную информацию и дополнительную помощь в Aspose.Cells for Java Documentation. Посмотрите, поможет ли это.

Раскрытие информации: Я работаю евангелистом-разработчиком в Aspose.

4

Попробуйте это:

  1. Распакуйте XLSX файл
  2. Чтение XML файлы
  3. Создание и использование данных

Пример кода:

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

где Workbook Класс:

public class Workbook { 
Integer id = null; 
public List<Worksheet> sheets = new ArrayList<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>();} 

и Роу класс:

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

и сотовый класс:

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

и класса Колонка:

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

и класс Span:

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

Что такое классы `Span` и` Column`? – HyperNeutrino 2017-01-15 23:19:26

1

Вы можете использовать Apache Tika для этого:

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

Тика использует Apache POI для разбора XLSX файлов.

Вот несколько usage examples для Tiki.

В качестве альтернативы, если вы хотите обработать каждую ячейку таблицы отдельно, вот один из способов сделать это с помощью 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); 
} 
Смежные вопросы