6

我正在使用 POI XSSF API,我想转置一张纸。

我怎样才能做到这一点?

谢谢。

4

2 回答 2

4

转置,如将 A2 与 B1 交换,将 A3 与 C1 交换(因此列变为行)?

如果是这样,则没有内置任何内容,因此您需要自己编写一些代码。您可能想要获取一对单元格,保存其中一个单元格的内容(值和样式),将第二个单元格复制到第一个单元格,然后覆盖第二个单元格。

如果您不确定所有读/写部分,请参阅快速指南。

于 2011-05-03T23:17:51.540 回答
2

我一直在寻找相同的答案,不得不自己编写代码。我附上了我的非常简单的解决方案:

  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 是一个包装器,它保存 Cell 包含的数据(如果您喜欢,可以添加更多属性,例如,评论,...):

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;
    }

}
于 2015-02-19T12:38:14.813 回答