Apache POI。复制表

时间:2011-05-04 20:45:46

标签: java apache-poi

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

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

此代码创建并向工作簿添加工作表。但我想先创建工作表,然后将其添加到工作簿。像这样的Smth:

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

我需要这样的东西,因为我想将数据从一个工作簿的一张工作簿复制到另一张工作簿的另一张工作簿(工作簿界面有方法Sheet cloneSheet(int))。但是,Workbook界面没有像addSheet(Sheet sh)这样的方法。 HSSFWorkbook也是最终类,所以我不能扩展它来实现add方法 我怎么能这样做?

3 个答案:

答案 0 :(得分:9)

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

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

答案 1 :(得分:2)

好吧,我试着去做Gagravarr上面所说的话。这个解决方案适合我。如果工作表没有表格等,此代码将起作用。如果工作表包含简单文本(String,boolean,int等),公式,此解决方案将起作用。

+--------+----------+---------------------------------------------+------+---------------------------------------------------------------------------+---------------+
| Domain | Method   | URI                                         | Name | Action                                                                    | Middleware    |
+--------+----------+---------------------------------------------+------+---------------------------------------------------------------------------+---------------+
|        | GET|HEAD | /                                           |      | Closure                                                                   | web           |
|        | GET|HEAD | api/oauth/authorize                         |      | Laravel\Passport\Http\Controllers\AuthorizationController@authorize       | cors,web,auth |
|        | DELETE   | api/oauth/authorize                         |      | Laravel\Passport\Http\Controllers\DenyAuthorizationController@deny        | cors,web,auth |
|        | POST     | api/oauth/authorize                         |      | Laravel\Passport\Http\Controllers\ApproveAuthorizationController@approve  | cors,web,auth |
|        | GET|HEAD | api/oauth/clients                           |      | Laravel\Passport\Http\Controllers\ClientController@forUser                | cors,web,auth |
|        | POST     | api/oauth/clients                           |      | Laravel\Passport\Http\Controllers\ClientController@store                  | cors,web,auth |
|        | DELETE   | api/oauth/clients/{client_id}               |      | Laravel\Passport\Http\Controllers\ClientController@destroy                | cors,web,auth |
|        | PUT      | api/oauth/clients/{client_id}               |      | Laravel\Passport\Http\Controllers\ClientController@update                 | cors,web,auth |
|        | POST     | api/oauth/personal-access-tokens            |      | Laravel\Passport\Http\Controllers\PersonalAccessTokenController@store     | cors,web,auth |
|        | GET|HEAD | api/oauth/personal-access-tokens            |      | Laravel\Passport\Http\Controllers\PersonalAccessTokenController@forUser   | cors,web,auth |
|        | DELETE   | api/oauth/personal-access-tokens/{token_id} |      | Laravel\Passport\Http\Controllers\PersonalAccessTokenController@destroy   | cors,web,auth |
|        | GET|HEAD | api/oauth/scopes                            |      | Laravel\Passport\Http\Controllers\ScopeController@all                     | cors,web,auth |
|        | POST     | api/oauth/token                             |      | Laravel\Passport\Http\Controllers\AccessTokenController@issueToken        | cors,throttle |
|        | POST     | api/oauth/token/refresh                     |      | Laravel\Passport\Http\Controllers\TransientTokenController@refresh        | cors,web,auth |
|        | GET|HEAD | api/oauth/tokens                            |      | Laravel\Passport\Http\Controllers\AuthorizedAccessTokenController@forUser | cors,web,auth |
|        | DELETE   | api/oauth/tokens/{token_id}                 |      | Laravel\Passport\Http\Controllers\AuthorizedAccessTokenController@destroy | cors,web,auth |
|        | GET|HEAD | api/test                                    |      | Closure                                                                   | api           |
|        | GET|HEAD | api/user                                    |      | Closure                                                                   | api,auth:api  |
+--------+----------+---------------------------------------------+------+---------------------------------------------------------------------------+---------------+

如果您的要求是在不离开或添加任何内容的情况下复制整张纸。我认为消除过程比上面的代码更好,更快。而且您不必担心丢失公式,图纸,表格,样式,字体等。

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();

答案 2 :(得分:0)

您应该使用 RangeCopier。

XSSFWorkbook workbookFrom = new XSSFWorkbook(new File("/path/to/workbookFrom.xlsx"));
    XSSFSheet sheetFrom = workbookFrom.getSheetAt(0);

    XSSFWorkbook workbookTo = new XSSFWorkbook(new File("/path/to/workbookTo.xlsx"));
    XSSFSheet sheetTo = workbookTo.createSheet("sheet1");
    workbookTo.setSheetOrder("sheet1", 0);
    XSSFRangeCopier xssfRangeCopier = new XSSFRangeCopier(sheetFrom, sheetTo);
    int lastRow = sheetFrom.getLastRowNum();
    int lastCol = 0;
    for (int i = 0; i < lastRow; i++) {
        Row row = sheetFrom.getRow(i);
        if (row != null) {
            if (row.getLastCellNum() > lastCol) {
                lastCol = row.getLastCellNum();
            }
            sheetTo.setDefaultRowHeight(sheetFrom.getDefaultRowHeight());
        }
    }

    for (int j = 0; j < lastCol; j++) {
        sheetTo.setColumnWidth(j, sheetFrom.getColumnWidth(j));
    }

    CellRangeAddress cellAddresses = new CellRangeAddress(0, lastRow, 0, lastCol);
    xssfRangeCopier.copyRange(cellAddresses, cellAddresses, true, true);

    workbookTo.write(new FileOutputStream(new File("/path/to/worksheetTo.xlsx")));