无法使用apache POI在工作簿中创build新的Excel工作表

我正在尝试复制单个文件中的多个文件。 该excel文件中的每个表单将包含一个文件的内容。 还有大约6个文件需要复制。 所以结果文件应该包含6张。 但是当我运行我的代码时,只有一张纸是为一个文件生成的。 我试着debugging,但无法弄清楚原因。

这是我的代码。

public static void main(String[] args) throws IOException { // TODO Auto-generated method stub CreateSingleExcelFile cef = new CreateSingleExcelFile(); cef.fileIterator(); } public void fileIterator() throws IOException{ File dir = new File("path for files to copy"); File[] dir_listing = dir.listFiles(); HSSFWorkbook my_wb = new HSSFWorkbook(); //creating an output stream to copy all files in combined.xls BufferedOutputStream bos= new BufferedOutputStream(new FileOutputStream("path of resultant excel sheet")); //traversing through a list of files for(File file: dir_listing){ //file: file to be copied. add_in_excel(my_wb,bos,file); System.out.println("In file :" + file.getName()); } bos.close(); System.out.println("Files are copied"); } private void add_in_excel(HSSFWorkbook copy_wb, BufferedOutputStream bos,File file) throws IOException { // TODO Auto-generated method stub //creating a new sheet in the copy workbook HSSFSheet mySheet = copy_wb.createSheet(file.getName()); BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file)); HSSFWorkbook workbook = new HSSFWorkbook(bis); CellStyle cs = copy_wb.createCellStyle(); cs.setWrapText(true); HSSFSheet sheet = null; HSSFRow row = null; HSSFCell cell = null; HSSFRow myRow = null; HSSFCell myCell = null; int sheets = workbook.getNumberOfSheets(); int fRow = 3; int lRow = 0; int count_row=0; //traversing through sheets in the 'file' for (int iSheet = 0; iSheet < sheets; iSheet++) { sheet = workbook.getSheetAt(iSheet); if (sheet != null) { lRow = sheet.getLastRowNum(); for (int iRow = fRow; iRow <= lRow; iRow++) { row = sheet.getRow(iRow); //creating row in the new sheet myRow = mySheet.createRow(count_row++); if (row != null) { for (int iCell = 0; iCell < 4; iCell++) { //creating a column in the new sheet cell = row.getCell(iCell); myCell = myRow.createCell(iCell); myCell.setCellStyle(cs); //setting cell type and adding data in each cell if (cell != null ) { myCell.setCellType(cell.getCellType()); switch (cell.getCellType()) { case HSSFCell.CELL_TYPE_BLANK: myCell.setCellValue(""); break; case HSSFCell.CELL_TYPE_BOOLEAN: myCell.setCellValue(cell.getBooleanCellValue()); break; case HSSFCell.CELL_TYPE_ERROR: myCell.setCellErrorValue(cell.getErrorCellValue()); break; case HSSFCell.CELL_TYPE_FORMULA: myCell.setCellFormula(cell.getCellFormula()); break; case HSSFCell.CELL_TYPE_NUMERIC: if(HSSFDateUtil.isCellDateFormatted(cell)) myCell.setCellValue(cell.getDateCellValue()); else myCell.setCellValue(cell.getNumericCellValue()); break; case HSSFCell.CELL_TYPE_STRING: myCell.setCellValue(cell.getStringCellValue()); break; default: myCell.setCellFormula(cell.getCellFormula()); } } } } } } } bis.close(); copy_wb.write(bos); } 

我已经减less了这个主要问题:

 import org.apache.poi.hssf.usermodel.*; import java.io.FileOutputStream; import java.io.IOException; import java.io.BufferedOutputStream; class CreateSingleExcelFile { public static void main(String[] args) throws IOException { CreateSingleExcelFile cef = new CreateSingleExcelFile(); cef.fileIterator(); } //This is what you actual doing: public void fileIterator() throws IOException{ HSSFWorkbook my_wb = new HSSFWorkbook(); BufferedOutputStream bos= new BufferedOutputStream(new FileOutputStream("copiedWB.xls")); for(int i = 0; i < 3; i++){ add_in_excel(my_wb, bos,"file" + i); System.out.println("In file :" + "file" + i); } bos.close(); //closing the BufferedOutputStream. The resulting file contains bytes for 3 complete XLS files. } private void add_in_excel(HSSFWorkbook copy_wb, BufferedOutputStream bos, String file) throws IOException { HSSFSheet mySheet = copy_wb.createSheet(file); copy_wb.write(bos); //write the copy_wb with one new added sheet into the BufferedOutputStream without closing it. But writing a XLS file is complex. So this will not work properly. It will append bytes for a complete XLS workbook onto the stream. } } 

您可以将一个新添加的工作表copy_wb写入BufferedOutputStream而不closuresstream。 但是编写一个XLS文件是复杂的。 所以这将无法正常工作。 它会将第一个1,然后2和最后3个表单的字节附加到完整的XLS工作簿上。 但每次完整的XLS工作簿文件。

添加完所有工作表后,closuresBufferedOutputStream 。 该stream以及生成的文件包含3个完整的XLS文件的字节。 第一张是1张,第二张是2张,第三张是3张。 如果用Excel打开,只有第一个会被读取。

这将工作,但不推荐。

 //This will work, but is not recommend public void fileIterator() throws IOException{ HSSFWorkbook my_wb = new HSSFWorkbook(); for(int i = 0; i < 3; i++){ BufferedOutputStream bos= new BufferedOutputStream(new FileOutputStream("copiedWB.xls")); // creating a new BufferedOutputStream for each call of add_in_excel add_in_excel(my_wb, bos,"file" + i); System.out.println("In file :" + "file" + i); } } private void add_in_excel(HSSFWorkbook copy_wb, BufferedOutputStream bos, String file) throws IOException { HSSFSheet mySheet = copy_wb.createSheet(file); copy_wb.write(bos); bos.close(); //write the copy_wb with one new added sheet into the BufferedOutputStream and close it. } 

为每个add_in_excel调用创build一个新的BufferedOutputStream。 写一个新添加的工作表的copy_wb到BufferedOutputStream中并closures它。 所以每个writeclose都会创build一个新的完整的XLS文件。 由于它具有相同的名称,它将覆盖现有的文件。

但是,为什么每次添加新工作表时都要编写完整的工作簿?

所以这就是我要做的:

  public void fileIterator() throws IOException{ HSSFWorkbook my_wb = new HSSFWorkbook(); BufferedOutputStream bos= new BufferedOutputStream(new FileOutputStream("copiedWB.xls")); //create the BufferedOutputStream only for the fileIterator method for(int i = 0; i < 3; i++){ add_in_excel(my_wb, "file" + i); System.out.println("In file :" + "file" + i); } my_wb.write(bos); bos.close(); //write into and close the BufferedOutputStream only once after you have added all sheets. } private void add_in_excel(HSSFWorkbook copy_wb, String file) throws IOException { HSSFSheet mySheet = copy_wb.createSheet(file); } 

仅为fileIterator方法创buildBufferedOutputStream。 不要将它传递给add_in_excel 。 在添加完所有工作表之后,只写入一次并closuresBufferedOutputStream。

既然你没有提到任何exception或堆栈跟踪,我会采取疯狂的猜测 – 对于目录中的每个新的excel文件,你正在做

HSSFWorkbook workbook = new HSSFWorkbook(bis);

在阅读每张纸(所有行和单元格)结束时,您将转到下一张纸,依次类推,直到所有纸张被创build并存储在内存中。 然后你通过将输出stream写出工作簿本身

copy_wb.write(bos);

[我知道这是你知道的事情,但是如果有人来了,这会让他们更容易理解发生了什么,而不用花时间]

我在想你第一次说workbook.write(outputstream)的内容是写的。 但是,你还没有closuresstream,你有一个完整的工作簿写出来。 下一次你想写另一个工作簿到同一个stream,我不知道会发生什么。 不应该将工作表添加到当前工作簿(而不是将多个工作簿写入相同的输出stream)?

我build议创build目标工作簿(如果它不存在),并写入源工作簿的工作表(而不是工作簿本身)。 这可能是一个工作,但除非我可以debugging多个工作簿处理到同一个输出stream,我不能真正build议修复当前的问题。