Apache-POI 행 정렬(Excel)
시트의 행을 문자열 열 중 하나로 정렬하고 싶습니다.Sheet.shift Rows 방법으로 해보았지만, 그것으로는 해결할 수 없습니다.제 방식에서는 행의 위치를 바꾸지 않습니다.내 코드에 무슨 문제가 있습니까?아니면 엑셀에서 문자열 열로 행을 정렬하는 더 좋은 방법이 있을까요?
/**
* 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;
}
}
}
}
시트에서 행 정렬을 관리하는 방법이 있습니까?
업데이트 위의 메서드는 Apache-POI 3.9 버전부터 작동합니다.
편집: 누락된 브래킷 추가 - helvio
Poi에는 정렬 메커니즘이 내장되어 있지 않지만, 물론 당신은 그러한 필요성이 있는 첫 번째 장치와는 거리가 멀기는 합니다.
반복해서 행을 옮기는 것 때문에 문제가 생기는 것 같습니다.위의 코드를 실행해보니 코드 실행이 끝날 때쯤 시트에서 행이 사라지고 있는 것 같습니다.
문제는 읽기 시트를 제자리 수정하려고 합니다.저는 두 번째 출력 시트를 만드는 것이 더 적합할 것으로 생각합니다.
그래서 기본적인 접근법은 시트를 읽고, 다른 종류의 문제를 다루는 것처럼 자바로 정렬하고, 출력 시트에 쓰는 것입니다.관심 있는 열의 문자열 값에 고유한 행 번호 맵을 수행한 경우 값별로 맵을 정렬할 수 있습니다.이러한 접근 방식은 단일 열에 정렬할 필요성을 예상한 경우에만 적용됩니다.어떤 경우든 엑셀 안에서 정렬 메뉴 옵션을 선택하는 것만큼 간단하지 않습니다.
이제 왜 안 되는지 알겠어요.shiftRows 메서드에 버그가 있습니다.세 번째 인수(이동할 행 수)가 음수이면 문제가 발생합니다.
이것은 여기에 설명되어 있습니다: https://issues.apache.org/bugzilla/show_bug.cgi?id=53798
업데이트 이 버그는 버전 3.9에서 수정되었습니다.
행을 정렬하려면 다음 작업을 수행해야 합니다.
- 모든 행을 임시로 복사
- 온도에 따라 줄을 정렬합니다.
- 시트에서 행을 모두 제거
- 온도에서 정렬된 행 값으로 새 행 만들기
코드:
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));
}
}
언급URL : https://stackoverflow.com/questions/13134490/apache-poi-sorting-rows-in-excel
'sourcecode' 카테고리의 다른 글
목록에서 범주 제외 - Wordpress (0) | 2023.09.25 |
---|---|
자바스크립트 날짜 + 7일 (0) | 2023.09.25 |
IPv6 호환 주소를 관계형 데이터베이스에 저장하는 방법 (0) | 2023.09.25 |
mariadb에서 상태 쿼리 오류 표시 (0) | 2023.09.25 |
각 2에서 $임의치는 무엇입니까? (0) | 2023.09.25 |