2011-05-04 102 views
4

我正在使用apache poi创建一个excel文档。要在工作簿中创建新工作表,我写下一个代码:Apache POI。复制工作表

Workbook wb = new HSSFWorkbook(); 
Sheet sh = wb.createSheet(); 

此代码创建并将工作表添加到工作簿。但我想先创建工作表,然后将其添加到工作簿。水木清华这样的:

Sheet sh = new HSSFSheet(); 
wb.addSheet(sh); 

我需要这样的东西,因为我想将数据从一个工作簿中的一个表复制到另一个工作簿中的另一个工作表(工作簿接口有方法Sheet cloneSheet(int))。但是工作簿界面没有像addSheet(Sheet sh)这样的方法。 另外HSSFWorkbook是final类,所以我不能扩展它来实现添加方法 我该怎么做?

回答

8

您不能只从一个工作簿获取Sheet对象,并将其添加到不同的工作簿。

您需要做的是同时打开旧工作簿和新工作簿,并在新工作簿中创建工作表。接下来,将您在旧工作表中使用的所有样式克隆到新工作表中(HSSFCellStyle具有将样式从一个工作簿克隆到另一个工作簿的方法)。最后,遍历所有的单元格并复制它们。

1

好吧我试着去做Gagravarr上面说的。这个解决方案适用于我。如果工作表没有表格等,如果工作表包含简单的文本(字符串,布尔值,整型等),公式,该解决方案将起作用。

Workbook oldWB = new XSSFWorkbook(new FileInputStream("C:\\input.xlsx")); 
Workbook newWB = new XSSFWorkbook(); 
CellStyle newStyle = newWB.createCellStyle(); // Need this to copy over styles from old sheet to new sheet. Next step will be processed below 
Row row; 
Cell cell; 
for (int i = 0; i < oldWB.getNumberOfSheets(); i++) { 
    XSSFSheet sheetFromOldWB = (XSSFSheet) oldWB.getSheetAt(i); 
    XSSFSheet sheetForNewWB = (XSSFSheet) newWB.createSheet(sheetFromOldWB.getSheetName()); 
    for (int rowIndex = 0; rowIndex < sheetFromOldWB.getPhysicalNumberOfRows(); rowIndex++) { 
     row = sheetForNewWB.createRow(rowIndex); //create row in this new sheet 
     for (int colIndex = 0; colIndex < sheetFromOldWB.getRow(rowIndex).getPhysicalNumberOfCells(); colIndex++) { 
      cell = row.createCell(colIndex); //create cell in this row of this new sheet 
      Cell c = sheetFromOldWB.getRow(rowIndex).getCell(colIndex, Row.CREATE_NULL_AS_BLANK); //get cell from old/original WB's sheet and when cell is null, return it as blank cells. And Blank cell will be returned as Blank cells. That will not change. 
       if (c.getCellType() == Cell.CELL_TYPE_BLANK){ 
        System.out.println("This is BLANK " + ((XSSFCell) c).getReference()); 
       } 
       else { //Below is where all the copying is happening. First It copies the styles of each cell and then it copies the content.    
       CellStyle origStyle = c.getCellStyle(); 
       newStyle.cloneStyleFrom(origStyle); 
       cell.setCellStyle(newStyle);    

       switch (c.getCellTypeEnum()) { 
        case STRING:        
         cell.setCellValue(c.getRichStringCellValue().getString()); 
         break; 
        case NUMERIC: 
         if (DateUtil.isCellDateFormatted(cell)) {        
          cell.setCellValue(c.getDateCellValue()); 
         } else {        
          cell.setCellValue(c.getNumericCellValue()); 
         } 
         break; 
        case BOOLEAN: 

         cell.setCellValue(c.getBooleanCellValue()); 
         break; 
        case FORMULA: 

         cell.setCellValue(c.getCellFormula()); 
         break; 
        case BLANK: 
         cell.setCellValue("who"); 
         break; 
        default: 
         System.out.println(); 
        } 
       } 
      } 
     } 

    } 
    //Write over to the new file 
    FileOutputStream fileOut = new FileOutputStream("C:\\output.xlsx"); 
    newWB.write(fileOut); 
    oldWB.close(); 
    newWB.close(); 
    fileOut.close(); 

如果您的要求是在不留下或添加任何东西的情况下复印整张纸。我认为淘汰的过程比上面的代码更好更快。而且您不必担心会丢失公式,图纸,表格,样式,字体等。

XSSFWorkbook wb = new XSSFWorkbook("C:\\abc.xlsx"); 
for (int i = wb.getNumberOfSheets() - 1; i >= 0; i--) { 
     if (!wb.getSheetName(i).contentEquals("January")) //This is a place holder. You will insert your logic here to get the sheets that you want. 
      wb.removeSheetAt(i); //Just remove the sheets that don't match your criteria in the if statement above    
} 
FileOutputStream out = new FileOutputStream(new File("C:\\xyz.xlsx")); 
wb.write(out); 
out.close();