2011-05-04 37 views
4

나는 아파치 poi를 사용하여 엑셀 문서를 만들고 있습니다. 통합 문서에 새 시트를 만들려면 다음 코드를 작성하십시오.Apache POI. 시트 복사

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

이 코드를 만들고 통합 문서에 시트를 추가하십시오. 하지만 이전에 시트를 만든 다음 통합 문서에 추가하려고합니다. 이 같은 매끄러운 : 나는 (통합 문서 인터페이스 방법 Sheet cloneSheet(int)있다) 다른 통합 문서의 다른 시트에 하나의 통합 문서 한 장에서 데이터를 복사 할 때문에

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

나는, 그런 일을해야합니다. 그러나 Workbook 인터페이스에는 addSheet (Sheet sh)와 같은 메소드가 없습니다. 또한 HSSFWorkbook은 최종 클래스이므로 추가 메서드를 구현하기 위해 확장 할 수 없습니다. 어떻게해야합니까?

답변

8

한 통합 문서에서 Sheet 개체를 가져 와서 다른 통합 문서에 추가 할 수는 없습니다.

이전 통합 문서와 새 통합 문서를 동시에 열고 새 통합 문서에 시트를 만드는 것이 필요합니다. 그런 다음 이전 시트에서 사용한 모든 스타일을 새 시트에 복제합니다 (HSSFCellStyle은 한 통합 문서에서 다른 통합 문서로 스타일을 복제하는 방법을가집니다). 마지막으로 모든 셀을 반복하여 복사합니다.

1

좋아, 나는 Gagravarr가 위에서 말한 것을 시도했다. 이 솔루션은 나를 위해 작동합니다. 이 코드는 시트에 테이블 등이없는 경우 작동합니다. 시트에 간단한 텍스트 (String, boolean, int 등), 수식이 포함되어 있으면이 솔루션이 작동합니다.

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(); 
관련 문제