我正在尝试在单个excel文件中复制多个文件。该excel文件中的每个工作表都将包含一个文件的内容。我需要复制大约6个文件。因此,生成的文件应包含6张。但是当我运行我的代码时,只为单个文件生成了1张表。我试过调试它,但无法弄清楚原因。
这是我的代码。
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);
}
答案 0 :(得分:2)
由于你没有提到任何异常或堆栈跟踪,我将采取疯狂猜测 - 对于目录中的每个新excel文件,你正在做
HSSFWorkbook workbook = new HSSFWorkbook(bis);
在阅读每张纸(所有行和单元格)的最后,您将继续前进到下一张纸,依此类推,直到所有纸张都已创建并位于内存中。然后通过
将工作簿本身写入输出流 copy_wb.write(bos);
[我知道你知道这件事但是如果将来有人来,这将使他们更容易理解正在发生的事情而不花时间]
我在想第一次你写workbook.write(outputstream)
的内容。但是你没有关闭流,你已经写完了整本工作簿。下次你想将 另一个工作簿 写入同一个流时,我真的不知道会发生什么。不应该将工作表添加到当前工作簿(而不是将多个工作簿写入同一输出流)?
我建议创建目标工作簿(如果它不存在)并编写源工作簿的工作表(而不是工作簿本身)。这可能是一个解决方法,但除非我可以调试多个工作簿与同一输出流的交易,否则我无法真正建议解决当前问题。
答案 1 :(得分:1)
我已将此问题简化为主要问题:
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
而不关闭该流。但是编写XLS文件很复杂。所以这不会正常工作。它将为完整的XLS工作簿附加字节,其中首先是1,然后是2,最后是3张到流上。但每次都是一个完整的XLS工作簿文件。
添加所有工作表后,关闭BufferedOutputStream
。流和结果文件包含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
的每次调用创建一个新的BufferedOutputStream。将带有一个新添加的工作表的copy_wb
写入BufferedOutputStream并关闭它。因此,每个write
和close
创建一个新的完整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
方法创建BufferedOutputStream。不要将其传递给add_in_excel
。在添加完所有工作表后,只写入并关闭BufferedOutputStream一次。