シートの行を文字列列の1つで並べ替えたいのですが。 Sheet.shiftRowsメソッドを使用してそれを達成しようとしましたが、それでは管理できません。私のメソッドでは行の位置が切り替わりません。私のコードの何が問題になっていますか?または、Excelの任意の文字列列で行を並べ替えるより良い方法がありますか?
/**
* Sorts (A-Z) rows by String column
* @param sheet - sheet to sort
* @param column - String column to sort by
* @param rowStart - sorting from this row down
*/
private void sortSheet(Sheet sheet, int column, int rowStart) {
boolean sorting = true;
int lastRow = sheet.getLastRowNum();
while (sorting == true) {
sorting = false;
for (Row row : sheet) {
// skip if this row is before first to sort
if (row.getRowNum()<rowStart) continue;
// end if this is last row
if (lastRow==row.getRowNum()) break;
Row row2 = sheet.getRow(row.getRowNum()+1);
if (row2 == null) continue;
String firstValue = (row.getCell(column) != null) ? row.getCell(column).getStringCellValue() : "";
String secondValue = (row2.getCell(column) != null) ? row2.getCell(column).getStringCellValue() : "";
//compare cell from current row and next row - and switch if secondValue should be before first
if (secondValue.compareToIgnoreCase(firstValue)<0) {
sheet.shiftRows(row2.getRowNum(), row2.getRowNum(), -1);
sheet.shiftRows(row.getRowNum(), row.getRowNum(), 1);
sorting = true;
}
}
}
}
シートの行の並べ替えを管理する方法はありますか?
[〜#〜] update [〜#〜]上記の方法は、Apache-POI3.9バージョン以降で機能します。
編集:不足しているブラケット-helvioを追加しました
今、私は今それが機能していない理由です。 shiftRowsメソッドにバグがあります。 3番目の引数(シフトする行数)が負の場合、問題が発生します。
これはここで説明されています: https://issues.Apache.org/bugzilla/show_bug.cgi?id=53798
[〜#〜] update [〜#〜]このバグはバージョン3.9から修正されています
Poiにはソートメカニズムが組み込まれていませんが、もちろん、その必要性を備えた最初のメカニズムからはほど遠いです。
繰り返している行を移動しているため、問題が発生していると思います。上記のコードを実行しましたが、コードの実行が終了するまでに行がシートから消えているようです。
質問は、読み込みシートをインプレースで変更しようとします。 2枚目の出力シートを作成する方が適切だと思います。
したがって、基本的なアプローチはシートを読み取り、他の並べ替えの問題を処理するのと同じようにJavaで並べ替え、出力シートに書き込みます。に固有の行番号のマップを作成した場合関心のある列の文字列値を値で並べ替えることができます。この種のアプローチは、単一の列で並べ替える必要があると予測した場合にのみ機能します。いずれにしても、選択するほど簡単ではありません。 Excel内からのソートメニューオプション。
行を並べ替えるには、次のことを行う必要があります。
コード:
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));
}
}