无法使用 apache POI 在工作簿中创建新的 excel sheet
Cannot create new excel sheet in a workbook using apache POI
我正在尝试将多个文件复制到一个 excel 文件中。 excel 文件中的每个 sheet 将携带一个文件的内容。我需要复制大约 6 个文件。所以生成的文件应该包含 6 sheets。但是当我 运行 我的代码只为单个文件生成 1 sheet 时。我尝试调试它但无法找出原因。
这是我的代码。
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);
在阅读每个 sheet(所有行和单元格)结束时,您继续阅读下一个 sheet,依此类推,直到所有 sheet 都已创建并完成在记忆中。然后你通过
将工作簿本身写到输出流
copy_wb.write(bos);
[我知道这是你知道的事情,但万一将来有人来,这将使他们更容易理解发生了什么,而无需花时间]
我在想你第一次说workbook.write(outputstream)
内容写好了。但是您还没有关闭流,并且已经写出了一整本工作簿。下次你想将 另一个工作簿 写入同一个流时,我真的不知道会发生什么。不应该将 sheets 添加到您当前的工作簿(而不是将多个工作簿写入同一输出流)?
我建议创建目标工作簿(如果它不存在)并编写源工作簿的 sheets(不是工作簿本身)。这可能是一个变通办法,但除非我可以将多个工作簿调试到同一个输出流,否则我无法真正建议解决当前问题。
我已将其简化为主要问题:
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
和一个新添加的 sheet 写入 BufferedOutputStream
而没有关闭流。但是编写 XLS 文件很复杂。所以这将无法正常工作。它会将完整 XLS 工作簿的字节附加到流中,首先是 1,然后是 2,最后是 3 sheets。但是每次都是一个完整的XLS工作簿文件。
添加所有 sheet 后,关闭 BufferedOutputStream
。流和生成的文件包含 3 个完整 XLS 文件的字节。第一个有 1 sheet,第二个有 2 sheets,第三个有 3 sheets。如果使用 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
和一个新添加的 sheet 写入 BufferedOutputStream 并关闭它。因此,每个 write
和 close
都会创建一个新的完整 XLS 文件,其中还有一个 sheet。由于它具有相同的名称,它将覆盖现有文件。
但为什么每次添加新的 sheet 时都要写完整的工作簿?
所以这就是我要做的:
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
。添加完所有 sheets.
后,仅写入并关闭 BufferedOutputStream 一次
我正在尝试将多个文件复制到一个 excel 文件中。 excel 文件中的每个 sheet 将携带一个文件的内容。我需要复制大约 6 个文件。所以生成的文件应该包含 6 sheets。但是当我 运行 我的代码只为单个文件生成 1 sheet 时。我尝试调试它但无法找出原因。
这是我的代码。
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);
在阅读每个 sheet(所有行和单元格)结束时,您继续阅读下一个 sheet,依此类推,直到所有 sheet 都已创建并完成在记忆中。然后你通过
将工作簿本身写到输出流copy_wb.write(bos);
[我知道这是你知道的事情,但万一将来有人来,这将使他们更容易理解发生了什么,而无需花时间]
我在想你第一次说workbook.write(outputstream)
内容写好了。但是您还没有关闭流,并且已经写出了一整本工作簿。下次你想将 另一个工作簿 写入同一个流时,我真的不知道会发生什么。不应该将 sheets 添加到您当前的工作簿(而不是将多个工作簿写入同一输出流)?
我建议创建目标工作簿(如果它不存在)并编写源工作簿的 sheets(不是工作簿本身)。这可能是一个变通办法,但除非我可以将多个工作簿调试到同一个输出流,否则我无法真正建议解决当前问题。
我已将其简化为主要问题:
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
和一个新添加的 sheet 写入 BufferedOutputStream
而没有关闭流。但是编写 XLS 文件很复杂。所以这将无法正常工作。它会将完整 XLS 工作簿的字节附加到流中,首先是 1,然后是 2,最后是 3 sheets。但是每次都是一个完整的XLS工作簿文件。
添加所有 sheet 后,关闭 BufferedOutputStream
。流和生成的文件包含 3 个完整 XLS 文件的字节。第一个有 1 sheet,第二个有 2 sheets,第三个有 3 sheets。如果使用 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
和一个新添加的 sheet 写入 BufferedOutputStream 并关闭它。因此,每个 write
和 close
都会创建一个新的完整 XLS 文件,其中还有一个 sheet。由于它具有相同的名称,它将覆盖现有文件。
但为什么每次添加新的 sheet 时都要写完整的工作簿?
所以这就是我要做的:
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
。添加完所有 sheets.