因工作需要,把上百个excel文件合并成一个excel文件。
失败方案一:一个输入流 + 一个输出流,循环读取源文件然后直接写入目标文件。
这种方案有个问题,流是无记忆的。同一个输入流,读取一个指针自动后移一位,但是不同的输入流,完全不知道上个流在做什么。最后的结果就是,目标文件的内容和循环中的最后一个源文件的内容相同....
方案二:为了让写入Excel的内容是接着上一次的位置继续写入的,选择使用HSSFWorkbook。
实现的思路是:在页面里,用户填写源文件地址、目标文件地址和目标文件名,提交后,后台先建立一个Excel目标文件,并且把目标文件和源文件都包装成HSSFWorkbook,然后迭代读取源文件的每个cell并将值存入到目标文件HSSFWorkbook对象中,最终数据写入到目标文件中。这样用户可以在填写的目标目标中找到合并文件。
不过在用HSSFWorkbook包装新创建的.xlsx目标文件时遇到了一个小问题:Unable to read entire header; 0 bytes read; expected 512 bytes,就是说包装对象没有没有表头。
问题语句:File file=File.createTempFile(targetPath+File.separator+fileName);
FileInputStream fis = new FileInputStream(file);
HSSFWorkbook targetWork = new HSSFWorkbook(fis);//出问题语句
所以直接创建的.xlsx是不能用HSSFWorkbook包装的,这种办法也不行。
方案三:在页面里,用户只填写源文件地址,提交后文件直接下载。后台不用再创建目标文件,直接把目标HSSFWorkbook对象写入到response流中。代码如下
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
public void excelMerge(HttpServletResponse response, String sourcePath) throws Exception {
// 创建HSSFWorkbook,暂时存放数据
HSSFWorkbook targetWork =