[英]Creating New Sheet In Existing Excel Workbook Using Apache POI for Java
[英]Cannot create new excel sheet in a workbook using apache POI
我正在嘗試將一個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);
}
既然您沒有提到任何異常或堆棧跟蹤,那么我將大膽猜測-對於目錄中的每個新excel文件,您都在做
HSSFWorkbook workbook = new HSSFWorkbook(bis);
在讀取每張紙(所有行和單元格)結束時,您將繼續到下一張紙,依此類推,直到創建了所有紙並將其存儲在內存中。 然后您通過以下方式將工作簿本身寫到輸出流中
copy_wb.write(bos);
[我知道這一點,但是如果將來有人來,這將使他們更容易理解正在發生的事情而無需花費時間]
我在想您第一次說到workbook.write(outputstream)
內容被寫入。 但是您尚未關閉流程,並且已經寫完了整個工作簿。 下次您想在同一流中編寫另一個工作簿時 ,我真的不知道會發生什么。 不應該在當前工作簿中添加工作表(而不是將多個工作簿寫入同一輸出流)嗎?
我建議創建目標工作簿(如果不存在)並編寫源工作簿的工作表(而不是工作簿本身)。 這可能是一種變通方法,但是除非我可以將多個工作簿的調試工作放到同一個輸出流中,否則我無法真正建議解決當前問題的方法。
我已將其簡化為主要問題:
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一次。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.