Apache POI.Копирование листов - PullRequest
4 голосов
/ 05 мая 2011

Я использую Apache Poi для создания документа Excel.Чтобы создать новый лист в книге, я пишу следующий код:

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

, этот код создайте и добавьте лист в книгу.Но я хочу создать лист раньше, а затем добавить его в книгу.Что-то вроде этого:

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

Мне нужна такая вещь, потому что я хочу скопировать данные с одного листа одной рабочей книги на другой лист другой рабочей книги (интерфейс рабочей книги имеет метод Sheet cloneSheet(int)).Но интерфейс Workbook не имеет такого метода, как addSheet (Sheet sh).Также HSSFWorkbook является последним классом, поэтому я не могу расширить его для реализации метода добавления. Как я могу это сделать?

Ответы [ 2 ]

9 голосов
/ 05 мая 2011

Вы не можете просто взять объект листа из одной рабочей книги и добавить его в другую рабочую книгу.

Вам нужно будет открыть старую рабочую книгу и новые рабочие книги одновременно.время, и создайте лист в новой книге.Затем, клонируйте все стили, которые вы использовали в старом листе, на новый (HSSFCellStyle имеет метод для клонирования стиля из одной рабочей книги в другую).Наконец, переберите все ячейки и скопируйте их.

2 голосов
/ 21 декабря 2016

Хорошо, я пытался сделать то, что сказал Гаграварр выше.Это решение работает для меня.Этот код будет работать, если на листах нет таблиц и т. Д. Если листы содержат простой текст (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();
...