如何使用POI SS / XSSF转置工作表?

时间:2011-05-03 22:07:07

标签: excel apache-poi transpose xssf

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

我该怎么做?

感谢。

2 个答案:

答案 0 :(得分:4)

转置,如交换A2中的B1和A3与C1(因此列成为行)?

如果是这样,那里面没有任何东西,所以你需要自己编写一些代码。你可能想要抓住一对单元格,保存一个单元格(值和样式),将第二个单元格复制到第一个单元格,然后覆盖第二个单元格。

如果您不确定所有读/写部件,请参阅quick guide

答案 1 :(得分:2)

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

  1. 确定行数
  2. 确定使用的最大列数
  3. 每行和每列的迭代器
  4. 将该行/列中的单元格保存为“CellModel”类型的简单列表
  5. 完成后,迭代所有CellModels
  6. 切换列和行索引并将CellModel保存到工作表中
  7. 我使用的代码是:

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