用Java读取XLSX文件
我需要在Java应用程序中读取Excel 2007 XLSX文件。 有谁知道一个好的API来完成这项任务?
AFAIK还没有可用的xlsx库。 但有一些旧的xls:
一个库是内部使用已经提到的POI的 jxls 。
2其他链接: 处理Excel文件 , 读取和写入Excel XLS文档文件的Java库 。
Apache POI 3.5增加了对所有OOXML(docx,xlsx等)的支持。
请参阅XSSF子项目
我不得不在.NET中这样做,我找不到任何API。 我的解决scheme是解压缩.xlsx,并直接操纵XML。 一旦你创build了你的帮助类等等,这并不是那么糟糕。
还有一些像节点一样的“陷阱”,都要按照excel期望的方式sorting,这在官方文档中是没有find的。 Excel有它自己的date时间戳,所以你需要做一个转换公式。
可能会有点晚,但testing版POI现在支持xlsx。
尝试这个:
- 解压缩XLSX文件
- 阅读XML文件
- 撰写和使用数据
示例代码:
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>();}
和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;}
和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;}
和Column类:
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; }
这个可能适合你,它可以读/写Excel 2007 xlsx文件。 SmartXLS
我不是很满意任何选项,所以我最终要求在Excel 97成员的文件。 这个POI非常适合。 感谢大家的帮助。
你看过糟糕混淆的API吗?
没关系:
HSSF是POI项目的纯粹Java实现Excel 97(-2007)文件格式。 它不支持新的基于OLE2的Excel 2007 .xlsx OOXML文件格式。
您可以考虑使用JDBC-ODBC桥 。
我不知道它是否是Excel 2007的最新版本,但是对于早期版本,我使用JExcelAPI
docx4j现在也涵盖了xlsx。
“为什么你会用docx4j来做到这一点?”我听到你问,“而不是POI,它着重于xlsx和binary xls?
可能是因为您喜欢JAXB(而不是XML Beans),或者您已经在使用docx4j作为docx或pptx,并且需要能够使用xlsx来做一些事情。
另一个可能的原因是,由于OpenXML模式而产生的jar XML Beans对于您的目的来说太大了。 (为了解决这个问题,POI提供了一个'lite'子集:'big'ooxml-schemas-1.0.jar是14.5 MB!但是如果你需要支持任意的电子表格,你可能需要完整的jar。 相比之下,整个docx4j / pptx4j / xlsx4j与POI的精简子集大致相同。
如果您仅处理电子表格(即不是docx或pptx),并且前面的段落不是您关心的问题,那么您最好使用POI。
Aspose.Cells for Java支持XLSX格式。 您可以在Aspose.Cells for Java文档中find更多的细节和进一步的帮助。 请看看这是否有帮助。
披露:我在Aspose担任开发者传道人。
你可以使用Apache Tika :
String parse(File xlsxFile) { return new Tika().parseToString(xlsxFile); }
Tika使用Apache POI来分析XLSX文件。
以下是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); }