Saltar al contenido

Apache-POI ordenando filas en Excel

Solución:

Poi no tiene un mecanismo de clasificación incorporado, aunque, por supuesto, estás lejos de ser el primero con esa necesidad.

Creo que se está metiendo en problemas porque está moviendo filas sobre las que está iterando. He ejecutado el código anterior y parece que lo que está sucediendo es que las filas desaparecen de la hoja al final de la ejecución del código.

La pregunta intenta hacer una modificación en el lugar de una hoja de lectura. Creo que sería más apropiado crear una segunda hoja de salida.

Entonces, el enfoque básico sería leer la hoja, ordenar en Java tal como trataría cualquier otro problema de ordenación, escribir en la hoja de salida. Si hizo un mapa del número de fila que es exclusivo del valor de cadena de la columna que le interesa, puede ordenar el mapa por valor. Este tipo de enfoque funcionaría si solo previera la necesidad de ordenar en una sola columna. En cualquier caso, no es tan simple como elegir la opción de menú de clasificación desde Excel.

Ahora sé por qué no funciona. Hay un error en el método shiftRows. Cuando el tercer argumento (número de filas para cambiar) es negativo, causa problemas.

Esto se describe aquí: https://issues.apache.org/bugzilla/show_bug.cgi?id=53798

ACTUALIZAR
Este error se ha corregido a partir de la versión 3.9.

Para ordenar las filas necesita:

  • copiar todas las filas a la temperatura
  • ordenar filas en la temperatura
  • eliminar todas las filas de la hoja
  • crear nuevas filas con valores de filas ordenadas de temp

Código:

import org.apache.commons.compress.utils.Lists;
import org.apache.poi.hssf.usermodel.HSSFOptimiser;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellRangeAddress;

import java.util.List;

public static void sortSheet(Workbook workbook, Sheet sheet) {
        //copy all rows to temp
        List<Row> rows = Lists.newArrayList(sheet.rowIterator());
        //sort rows in the temp
        rows.sort(Comparator.comparing(cells -> cells.getCell(0).getStringCellValue()));
        //remove all rows from sheet
        removeAllRows(sheet);
        //create new rows with values of sorted rows from temp
        for (int i = 0; i < rows.size(); i++) {
            Row newRow = sheet.createRow(i);
            Row sourceRow = rows.get(i);
            // Loop through source columns to add to new row
            for (int j = 0; j < sourceRow.getLastCellNum(); j++) {
                // Grab a copy of the old/new cell
                Cell oldCell = sourceRow.getCell(j);
                Cell newCell = newRow.createCell(j);

                // If the old cell is null jump to next cell
                if (oldCell == null) {
                    newCell = null;
                    continue;
                }

                // Copy style from old cell and apply to new cell
                CellStyle newCellStyle = workbook.createCellStyle();
                newCellStyle.cloneStyleFrom(oldCell.getCellStyle());
                newCell.setCellStyle(newCellStyle);

                // If there is a cell comment, copy
                if (oldCell.getCellComment() != null) {
                    newCell.setCellComment(oldCell.getCellComment());
                }

                // If there is a cell hyperlink, copy
                if (oldCell.getHyperlink() != null) {
                    newCell.setHyperlink(oldCell.getHyperlink());
                }

                // Set the cell data type
                newCell.setCellType(oldCell.getCellType());

                // Set the cell data value
                switch (oldCell.getCellType()) {
                    case BLANK:
                        newCell.setCellValue(oldCell.getStringCellValue());
                        break;
                    case BOOLEAN:
                        newCell.setCellValue(oldCell.getBooleanCellValue());
                        break;
                    case ERROR:
                        newCell.setCellErrorValue(oldCell.getErrorCellValue());
                        break;
                    case FORMULA:
                        newCell.setCellFormula(oldCell.getCellFormula());
                        break;
                    case NUMERIC:
                        newCell.setCellValue(oldCell.getNumericCellValue());
                        break;
                    case STRING:
                        newCell.setCellValue(oldCell.getRichStringCellValue());
                        break;
                }
            }

            // If there are are any merged regions in the source row, copy to new row
            for (int j = 0; j < sheet.getNumMergedRegions(); j++) {
                CellRangeAddress cellRangeAddress = sheet.getMergedRegion(j);
                if (cellRangeAddress.getFirstRow() == sourceRow.getRowNum()) {
                    CellRangeAddress newCellRangeAddress = new CellRangeAddress(newRow.getRowNum(),
                            (newRow.getRowNum() +
                                    (cellRangeAddress.getLastRow() - cellRangeAddress.getFirstRow()
                                    )),
                            cellRangeAddress.getFirstColumn(),
                            cellRangeAddress.getLastColumn());
                    sheet.addMergedRegion(newCellRangeAddress);
                }
            }
        }

    }

    private static void removeAllRows(Sheet sheet) {
            for (int i = 0; i < sheet.getLastRowNum(); i++) {
                sheet.removeRow(sheet.getRow(i));
            }
        }
¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *