我有两个Java程序:一个用于创建数据并将数据写入XLSX文件,另一个用于读取同一文件中的数据。
在我的第一个程序中,我使用下面的语句将数据写入XLSX文件。
FileOutputStream prelimOut = new FileOutputStream(new File("D:\\News\\Prelim.xlsx"));
XSSFWorkbook out = new XSSFWorkbook();
XSSFSheet spreadSheet = out.createSheet("ResultSheet");
在我的驱动器上,我按照预期创建了文件。
当我尝试使用此代码从其他程序读取同一文件时
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Iterator;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
public class GetCellCount {
public static void main(String[] args) throws IOException {
FileInputStream input_document = new FileInputStream(new File("D:\\News\\Prelim.xlsx"));
XSSFWorkbook my_xlsx_workbook = new XSSFWorkbook(input_document);
XSSFSheet my_worksheet = my_xlsx_workbook.getSheetAt(0);
Iterator<Row> rowIterator = my_worksheet.iterator();
while (rowIterator.hasNext()) {
Row row = rowIterator.next();
Iterator<Cell> cellIterator = row.cellIterator();
while (cellIterator.hasNext()) {
Cell cell = cellIterator.next();
switch (cell.getCellType()) {
case Cell.CELL_TYPE_NUMERIC:
System.out.print(cell.getNumericCellValue() + "\t\t");
break;
case Cell.CELL_TYPE_STRING:
System.out.print(cell.getStringCellValue() + "\t\t");
break;
}
}
System.out.println("");
}
my_xlsx_workbook.close();
input_document.close();
}
}
它抛出以下错误
Exception in thread "main" org.apache.poi.POIXMLException: org.apache.poi.openxml4j.exceptions.InvalidFormatException: Package should contain a content type part [M1.13]
at org.apache.poi.util.PackageHelper.open(PackageHelper.java:39)
at org.apache.poi.xssf.usermodel.XSSFWorkbook.<init>(XSSFWorkbook.java:258)
at GetCellCount.main(GetCellCount.java:14)
Caused by: org.apache.poi.openxml4j.exceptions.InvalidFormatException: Package should contain a content type part [M1.13]
at org.apache.poi.openxml4j.opc.ZipPackage.getPartsImpl(ZipPackage.java:203)
at org.apache.poi.openxml4j.opc.OPCPackage.getParts(OPCPackage.java:673)
at org.apache.poi.openxml4j.opc.OPCPackage.open(OPCPackage.java:274)
at org.apache.poi.util.PackageHelper.open(PackageHelper.java:37)
... 2 more
更改路径并访问另一个XLSX文件(直接在Excel中创建)时,数据会正确显示。
此外,当我通过右键单击它们来检查这两个Excel文件的属性时,我看到&#34;文件类型&#34;为MS Office Excel OpenXML (.xlsx)
,两个文件都相同。
答案 0 :(得分:0)
以下代码演示了如何使用数据创建一个新的XLSX文件,将其写入磁盘以及从文件中读取数据。它是使用Java 9和Apache POI 3.17构建的。
该示例使用一个简单的Person
类,其中包含一个String
,一个LocalDate
和一个Int
来生成测试数据。
这是在我们将测试数据写入其中之后,使用LibreOffice查看的已创建的XLSX文件:
写入文件后,我们读回其内容并创建Person
对象:
Could not parse row 0 to person
Person from file: Khaled, born 1988-03-26, pets: 1
Person from file: Hans, born 1998-09-20, pets: 2
Person from file: Alena, born 1977-01-12, pets: 0
由于我们无法将标题行Name Date of Birth Nr of Pets
转换为Person
对象,因此出现第一行警告。
代码如下:
/**
* Writes person data to an XLSX file and reads it back out.
* <p>
* Created by Matthias Braun on 2018-07-10.
*/
public class ReadWriteTests {
public static void main(String... args) {
List<Person> people = List.of(
new Person("Khaled", LocalDate.of(1988, 3, 26), 1),
new Person("Hans", LocalDate.of(1998, 9, 20), 2),
new Person("Alena", LocalDate.of(1977, 1, 12), 0)
);
String xlsxFileName = System.getenv("HOME") + "/people.xlsx";
writeToXlsxFile(people, xlsxFileName);
List<Person> peopleFromFile = readFromXlsxFile(xlsxFileName);
peopleFromFile.forEach(person ->
System.out.println("Person from file: " + person));
}
private static List<Person> readFromXlsxFile(String xlsxFileName) {
return getRows(new File(xlsxFileName)).stream()
.map(row -> rowToPerson(row))
// Remove empty Optionals
.flatMap(Optional::stream)
.collect(Collectors.toList());
}
private static Optional<Person> rowToPerson(Row row) {
Optional<Person> personMaybe;
try {
String name = row.getCell(0).getStringCellValue();
Date date = row.getCell(1).getDateCellValue();
// Convert from Date to LocalDate
LocalDate dateOfBirth = LocalDate.ofInstant(
date.toInstant(), ZoneId.systemDefault());
int nrOfPets = (int) row.getCell(2).getNumericCellValue();
personMaybe = Optional.of(new Person(name, dateOfBirth, nrOfPets));
} catch (IllegalStateException ex) {
System.err.println("Could not parse row " + row.getRowNum()
+ " to person");
personMaybe = Optional.empty();
}
return personMaybe;
}
private static List<Row> getRows(final File xlsx) {
final List<Row> rows = new ArrayList<>();
try (XSSFWorkbook workbook = new XSSFWorkbook(xlsx)) {
// Get each row from each sheet
workbook.forEach(sheet -> sheet.forEach(rows::add));
// If Apache POI tries to open a non-existent file it will throw
// an InvalidOperationException, if it's an unrecognized format
// it will throw a NotOfficeXmlFileException.
// We catch them all to be safe.
} catch (Exception e) {
System.err.println("Could not get rows from "
+ xlsx.getAbsolutePath());
e.printStackTrace();
}
return rows;
}
private static void writeToXlsxFile(List<Person> people, String fileName) {
try (OutputStream fileStream = new FileOutputStream(fileName)) {
Workbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet("Test People Sheet");
// Create a header row describing what the columns mean
CellStyle boldStyle = workbook.createCellStyle();
Font font = workbook.createFont();
font.setBold(true);
boldStyle.setFont(font);
Row headerRow = sheet.createRow(0);
addStringCells(headerRow,
List.of("Name", "Date of Birth", "Nr of Pets"),
boldStyle);
// Define how a cell containing a date is displayed
CellStyle dateCellStyle = workbook.createCellStyle();
CreationHelper createHelper = workbook.getCreationHelper();
dateCellStyle.setDataFormat(createHelper.createDataFormat()
.getFormat("yyyy/m/d"));
// Add the person data as rows
for (int i = 0; i < people.size(); i++) {
// Add one due to the header row
Row row = sheet.createRow(i + 1);
Person person = people.get(i);
addCells(person, row, dateCellStyle);
}
workbook.write(fileStream);
workbook.close();
} catch (IOException e) {
System.err.println("Could not create XLSX file at " + fileName);
e.printStackTrace();
}
}
private static void addCells(Person person, Row row,
CellStyle dateCellStyle) {
Cell classCell = row.createCell(0, CellType.STRING);
classCell.setCellValue(person.getName());
Cell dateOfBirthCell = row.createCell(1, CellType.NUMERIC);
// Convert LocalDate to a legacy Date object
Date dateOfBirth = Date.from(person.getDateOfBirth()
.atStartOfDay(ZoneId.systemDefault()).toInstant());
dateOfBirthCell.setCellValue(dateOfBirth);
dateOfBirthCell.setCellStyle(dateCellStyle);
Cell petCell = row.createCell(2, CellType.NUMERIC);
petCell.setCellValue(person.getNrOfPets());
}
// Adds strings as styled cells to a row
private static void addStringCells(Row row, List<String> strings,
CellStyle style) {
for (int i = 0; i < strings.size(); i++) {
Cell cell = row.createCell(i, CellType.STRING);
cell.setCellValue(strings.get(i));
cell.setCellStyle(style);
}
}
static class Person {
private final String name;
private final LocalDate dateOfBirth;
private final int nrOfPets;
Person(String name, LocalDate dateOfBirth, int nrOfPets) {
this.name = name;
this.dateOfBirth = dateOfBirth;
this.nrOfPets = nrOfPets;
}
String getName() {
return name;
}
LocalDate getDateOfBirth() {
return dateOfBirth;
}
int getNrOfPets() {
return nrOfPets;
}
@Override
public String toString() {
return name + ", born " + dateOfBirth + ", pets: " + nrOfPets;
}
}
}
包含依赖性的build.gradle
,用./gradle run
启动应用程序:
apply plugin: "application"
apply plugin: "java"
mainClassName = "com.bullbytes.ReadWriteTests"
sourceCompatibility = 9
repositories {
mavenCentral()
}
dependencies {
// Read and write Microsoft Office files: https://poi.apache.org
// https://mvnrepository.com/artifact/org.apache.poi/poi
compile "org.apache.poi:poi:3.17"
compile "org.apache.poi:poi-ooxml:3.17"
}
Here's more关于使用Apache POI创建电子表格。