Для проекта мне нужно создать документ .xlsm
excel, автоматически заполняющий файл шаблона. Проблема в том, что вывод поврежден и не может быть прочитан Excel 365 или Apache POI.
Я разобрал его до следующего минимального примера, который можно запустить методом main
. Для полной безопасности используется формат .xlsx
.
public static void main(String[] args) {
XSSFWorkbook document = new XSSFWorkbook();
XSSFSheet spreadsheet = document.createSheet("Test");
spreadsheet.createRow(0).createCell(0).setCellValue("Testie test");
// Output .xlsx file
FileOutputStream stream;
try {
stream = new FileOutputStream("test_output.xlsx");
document.write(stream);
stream.flush();
stream.close();
} catch (IOException e) {
System.err.println("Error" + e.getMessage());
e.printStackTrace();
}
...
Созданный файл test_output.xlsx
не может быть открыт в Excel 365 и имеет размер всего 4 КБ, в то время как созданный вручную файл займет 9 КБ, поэтому в выводе должно быть что-то отсутствующее, которое я не указал?
Я использую Apache POI версии 3.17, импортированный через Gradle, используя
compile('org.apache.poi:poi-ooxml:3.17')
, а также с Apache POI версии 3.13 с версией до 2016 года. В обоих случаях не повезло.
Когда метод main расширяется, чтобы открыть тот же файл, который был только что создан, как показано ниже
...
// Try to read it again
try {
document = new XSSFWorkbook("test_output.xlsx");
System.out.println(document.getSheetAt(0).getRow(0).getCell(0).getStringCellValue());
} catch (IOException e) {
e.printStackTrace();
}
}
тогда я попаду в следующее исключение
java.io.IOException: org.apache.poi.openxml4j.exceptions.InvalidFormatException: Can't read content types part !
at org.apache.poi.POIXMLDocument.openPackage(POIXMLDocument.java:91)
at org.apache.poi.xssf.usermodel.XSSFWorkbook.<init>(XSSFWorkbook.java:340)
...
Если, с другой стороны, все XSSF*
заменены на HSSF*
, а тип файла превращен в файл .xls
, то выводимый документ в порядке, но мне нужно создать рабочий документ Excel 365, а не Excel 2003 один.
Ниже приведен файл [Content_Types].xml
в документе .xlsx
, сделанном вручную
.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">
<Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/>
<Default Extension="xml" ContentType="application/xml"/>
<Override PartName="/xl/workbook.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml"/>
<Override PartName="/xl/worksheets/sheet1.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml"/>
<Override PartName="/xl/theme/theme1.xml" ContentType="application/vnd.openxmlformats-officedocument.theme+xml"/>
<Override PartName="/xl/styles.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml"/>
<Override PartName="/xl/sharedStrings.xml" ContentType="application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml"/>
<Override PartName="/docProps/core.xml" ContentType="application/vnd.openxmlformats-package.core-properties+xml"/>
<Override PartName="/docProps/app.xml" ContentType="application/vnd.openxmlformats-officedocument.extended-properties+xml"/>
</Types>
Пока в файле, созданном POI, указано [Content_Types].xml
.xlsx
<?xml version = '1.0' encoding = 'UTF-8' standalone = 'yes'?>
<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">
<Default ="rels"/>
<Default ="xml"/>
<Override ="/docProps/app.xml"/>
<Override ="/docProps/core.xml"/>
<Override ="/xl/sharedStrings.xml"/>
<Override ="/xl/styles.xml"/>
<Override ="/xl/workbook.xml"/>
<Override ="/xl/worksheets/sheet1.xml"/>
</Types>