Как транспонировать лист с POI SS / XSSF? - PullRequest
6 голосов
/ 04 мая 2011

Я использую POI XSSF API, и я хотел бы переместить лист.

как я могу это сделать?

Спасибо.

Ответы [ 2 ]

4 голосов
/ 04 мая 2011

Транспонировать, как при замене A2 на B1 и A3 на C1 (таким образом, столбцы становятся строками)?

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

См. Краткое руководство если вы не уверены во всех аспектах чтения / записи.

2 голосов
/ 19 февраля 2015

Я искал тот же ответ и сам должен был его кодировать.Я приложил свое решение, которое довольно просто:

  1. Определите количество строк
  2. Определите максимальное количество используемых столбцов
  3. Итератор для каждой строки, икаждый столбец
  4. Сохранение ячейки из этой строки / столбца в простой список в виде типа 'CellModel'
  5. После завершения переберите все CellModels
  6. Переключение столбца и индекса строкии сохраните CellModel на листе

Код, который я использовал:

public static void transpose(Workbook wb, int sheetNum, boolean replaceOriginalSheet) {
    Sheet sheet = wb.getSheetAt(sheetNum);

    Pair<Integer, Integer> lastRowColumn = getLastRowAndLastColumn(sheet);
    int lastRow = lastRowColumn.getFirst();
    int lastColumn = lastRowColumn.getSecond();

    LOG.debug("Sheet {} has {} rows and {} columns, transposing ...", new Object[] {sheet.getSheetName(), 1+lastRow, lastColumn});

    List<CellModel> allCells = new ArrayList<CellModel>();
    for (int rowNum = 0; rowNum <= lastRow; rowNum++) {
        Row row = sheet.getRow(rowNum);
        if (row == null) {
            continue;
        }
        for (int columnNum = 0; columnNum < lastColumn; columnNum++) {
            Cell cell = row.getCell(columnNum);
            allCells.add(new CellModel(cell));
        }
    }
    LOG.debug("Read {} cells ... transposing them", allCells.size());

    Sheet tSheet = wb.createSheet(sheet.getSheetName() + "_transposed");
    for (CellModel cm : allCells) {
        if (cm.isBlank()) {
            continue;
        }

        int tRow = cm.getColNum();
        int tColumn = cm.getRowNum();

        Row row = tSheet.getRow(tRow);
        if (row == null) {
            row = tSheet.createRow(tRow);
        }

        Cell cell = row.createCell(tColumn);
        cm.insertInto(cell);
    }

    lastRowColumn = getLastRowAndLastColumn(sheet);
    lastRow = lastRowColumn.getFirst();
    lastColumn = lastRowColumn.getSecond();
    LOG.debug("Transposing done. {} now has {} rows and {} columns.", new Object[] {tSheet.getSheetName(), 1+lastRow, lastColumn});

    if (replaceOriginalSheet) {
        int pos = wb.getSheetIndex(sheet);
        wb.removeSheetAt(pos);
        wb.setSheetOrder(tSheet.getSheetName(), pos);
    }

}

private static Pair<Integer, Integer> getLastRowAndLastColumn(Sheet sheet) {
    int lastRow = sheet.getLastRowNum();
    int lastColumn = 0;
    for (Row row : sheet) {
        if (lastColumn < row.getLastCellNum()) {
            lastColumn = row.getLastCellNum();
        }
    }
    return new Pair<Integer, Integer>(lastRow, lastColumn);
}

, где CellModel - это оболочка, которая содержит данные, содержащиеся в ячейке (вы можете добавитьбольше атрибутов, если вам нравится, например, комментарии, ...):

static class CellModel {
    private int rowNum = -1;
    private int colNum = -1;
    private CellStyle cellStyle;
    private int cellType = -1;
    private Object cellValue;

    public CellModel(Cell cell) {
        if (cell != null) {
            this.rowNum = cell.getRowIndex();
            this.colNum = cell.getColumnIndex();
            this.cellStyle = cell.getCellStyle();
            this.cellType = cell.getCellType();
            switch (this.cellType) {
                case Cell.CELL_TYPE_BLANK:
                    break;
                case Cell.CELL_TYPE_BOOLEAN:
                    cellValue = cell.getBooleanCellValue();
                    break;
                case Cell.CELL_TYPE_ERROR:
                    cellValue = cell.getErrorCellValue();
                    break;
                case Cell.CELL_TYPE_FORMULA:
                    cellValue = cell.getCellFormula();
                    break;
                case Cell.CELL_TYPE_NUMERIC:
                    cellValue = cell.getNumericCellValue();
                    break;
                case Cell.CELL_TYPE_STRING:
                    cellValue = cell.getRichStringCellValue();
                    break;
            }
        }
    }

    public boolean isBlank() {
        return this.cellType == -1 && this.rowNum == -1 && this.colNum == -1;
    }

    public void insertInto(Cell cell) {
        if (isBlank()) {
            return;
        }

        cell.setCellStyle(this.cellStyle);
        cell.setCellType(this.cellType);
        switch (this.cellType) {
            case Cell.CELL_TYPE_BLANK:
                break;
            case Cell.CELL_TYPE_BOOLEAN:
                cell.setCellValue((boolean) this.cellValue);
                break;
            case Cell.CELL_TYPE_ERROR:
                cell.setCellErrorValue((byte) this.cellValue);
                break;
            case Cell.CELL_TYPE_FORMULA:
                cell.setCellFormula((String) this.cellValue);
                break;
            case Cell.CELL_TYPE_NUMERIC:
                cell.setCellValue((double) this.cellValue);
                break;
            case Cell.CELL_TYPE_STRING:
                cell.setCellValue((RichTextString) this.cellValue);
                break;
        }
    }

    public CellStyle getCellStyle() {
        return cellStyle;
    }

    public int getCellType() {
        return cellType;
    }

    public Object getCellValue() {
        return cellValue;
    }

    public int getRowNum() {
        return rowNum;
    }

    public int getColNum() {
        return colNum;
    }

}
...