JavaアプリケーションでExcel 2007 XLSXファイルを読み取る必要があります。このタスクを実行するための優れたAPIを知っている人はいますか?
知る限り、xlsx-librariesはまだ利用できません。しかし、古いxlsにはいくつかあります:
1つのライブラリは jxls で、これは既に言及した [〜#〜] poi [〜#〜] を内部的に使用します。
他の2つのリンク: Excelファイルの処理 、 Excel XLSドキュメントファイルを読み書きするJavaライブラリ 。
Apache POI 3.5は、すべてのOOXML(docx、xlsxなど)のサポートを追加しました
XSSFサブプロジェクト を参照してください
.NETでこれを行う必要があり、そこにAPIが見つかりませんでした。私の解決策は、.xlsxを解凍し、XMLを操作することです。ヘルパークラスなどを作成したら、それほど悪くはありません。
Excelが期待する方法に従ってノードをすべてソートする必要があるような「落とし穴」がいくつかありますが、これは公式ドキュメントにはありませんでした。 Excelには独自の日付のタイムスタンプがあるため、変換式を作成する必要があります。
少し遅れるかもしれませんが、ベータPOIは現在xlsxをサポートしています。
これを試して:
サンプルコード:
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>();}
および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;}
および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ブリッジ を使用することを検討してください。
Aspose.Cells for Java はXLSX形式をサポートします。詳細については、 Aspose.Cells for Java Documentation を参照してください。これが役立つかどうかを確認してください。
開示:Asposeで開発者エバンジェリストとして働いています。
Excel 2007が最新かどうかはわかりませんが、以前のバージョンでは JExcelAPI を使用しています
docx4jは、xlsxもカバーするようになりました。
「なぜdocx4jを使用してこれを行うのですか」と聞いたのですが、「xlsxとバイナリxlsに焦点を当てたPOIではなく」
おそらく、XML Beanとは対照的にJAXBが好きか、docxまたはpptxにすでにdocx4jを使用していて、xlsxでも何かできるようにする必要があるからでしょう。
別の考えられる理由は、OpenXMLスキーマから生成されるjar XML Beansが目的に対して大きすぎることです。 (これを回避するために、POIは 'lite'サブセットを提供します: 'big' ooxml-schemas-1.0.jarは14.5 MBです!しかし、任意のスプレッドシートをサポートする必要がある場合は、おそらく完全なjarが必要です)。対照的に、docx4j/pptx4j/xlsx4j全体は、POIのライトサブセットとほぼ同じ重量になります。
スプレッドシートのみを処理する場合(つまり、docxまたはpptxを使用しない場合)、前の段落を気にしない場合は、おそらくPOIを使用するのが最善です。
Apache Tika を使用できます:
String parse(File xlsxFile) {
return new Tika().parseToString(xlsxFile);
}
Tikaは、XLSXファイルの解析に Apache POI を使用します。
以下に、Tikiの 使用例 を示します。
または、スプレッドシートの各セルを個別に処理する場合は、POIでこれを行う1つの方法があります。
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);
}
Xlsxを使用する場合は、org.Apache.poi.ssパッケージを使用する必要があります。このパッケージにはクラスXSSFがあり、xlxsファイルの解析に使用できます。このサンプルコードは、Excel 2007以降(.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);