我正在尝试基于通用模板生成新的Excel文件。我正在打开模板excel文件,对其进行编辑并将其保存在新位置。要写入文件,我正在使用FileOutputStream,并且在写入后将其关闭以保存它。整个过程正常工作,但是新创建的Excel文件未正确保存。我的模板文件为35kb,而我新创建的Excel文件仅显示30kb。当打开新创建的excel文件时,可以看到写入的数据,需要保存并关闭它以反映正确的36kb大小。
直接将30kb未保存的excel直接上传到外部应用程序时,必须将新的excels上传到显示“未找到数据”的外部应用程序,而成功保存36kb的文件才能成功上传文件。
我尝试了Internet上建议的各种不同方法来做同样的事情,但没有一个可以生成正确的excel文件。我正在使用Java 1.7和apache-poi 3.17版。
以下是我的代码的示例:-
public void createExcelFiles() throws ParseException, IOException {
File file = new File(ExcelTemplatePath);
FileInputStream fip = new FileInputStream(file);
FileOutputStream fos = new FileOutputStream(excelOutputFile);
XSSFWorkbook workbookOld = new XSSFWorkbook(fip);
try (SXSSFWorkbook workbook = new SXSSFWorkbook(workbookOld, rowAccessWindowSize)) {
if (makeLargeFiles) {
SXSSFSheet sheet = (SXSSFSheet) workbook.getSheetAt(0);
makeExcelFile.makeLargeFile(sheet);
workbook.write(fos);
} else {
Sheet sheet = workbookOld.getSheetAt(0);
makeExcelFile.makeNormalFile(sheet);
workbookOld.write(fos);
}
fos.close();
fip.close();
workbook.close();
}
workbookOld.close();
}
答案 0 :(得分:0)
像XSSFWorkbook
这样的包装好的I / O流应该首先关闭,可能仍然向包装的OutputStream写一个结尾。而且底层流可能会关闭。
请记住,某些包装类将自己在自己的close
内部关闭包装的流。
由于try-with-resources是理想的,因此也可以在发生异常时关闭,最终版本为:
public void createExcelFiles() throws ParseException, IOException {
File file = new File(ExcelTemplatePath);
try (FileInputStream fip = new FileInputStream(file);
FileOutputStream fos = new FileOutputStream(excelOutputFile);
XSSFWorkbook workbookOld = new XSSFWorkbook(fip);
SXSSFWorkbook workbook = new SXSSFWorkbook(workbookOld, rowAccessWindowSize)) {
if (makeLargeFiles) {
SXSSFSheet sheet = (SXSSFSheet) workbook.getSheetAt(0);
makeExcelFile.makeLargeFile(sheet);
workbook.write(fos);
} else {
Sheet sheet = workbookOld.getSheetAt(0);
makeExcelFile.makeNormalFile(sheet);
workbookOld.write(fos);
}
}
// Doing in reverse order of declaration:
// 1. workbook.close();
// 2. workbookOld.close();
// 3. fos.close();
// 4. fip.close();
}
在您的代码中有一个逆转,并且关闭是通过try-with-resources显式发生的。
答案 1 :(得分:0)
已使用excel的共享字符串属性解决了此问题。我更新了工作簿构造函数调用,如下所示:
SXSSFWorkbook工作簿=新的SXSSFWorkbook(workbookOld,rowAccessWindowSize,true,true)
第二个true参数用于共享字符串的使用。使用此属性可使数据对外部应用程序可见,而无需再次打开并保存它。但是,大小问题仍然存在,为什么使用共享字符串仍然有效仍不清楚。 有关共享字符串的更多信息,请查看this。