// 删除空行并将有数据的整行向上移动 int lastRowNum1 = sheet.getLastRowNum();//表格行数 for (int i = lastRowNum1; i >= 1; i--) {//从最后一行开始,到第二行结束,一步一步往上一行遍历寻找空行 Row row = sheet.getRow(i);//获取行对象 if (row == null || isRowEmpty(row)) {//如果此行对象是空的数据 //在开始行和结束行之间作为整体,向下移动行 n 行数。 * 如果使用负数,它将向上移动行 //sheet.shiftRows(i + 1, lastRowNum1 + 1, -1); sheet.shiftRows(i, i, lastRowNum1-i); lastRowNum1--; } }
时间: 2024-02-06 11:04:41 浏览: 187
这段代码是用来删除 Excel 表格中的空行,并将有数据的整行向上移动。它首先获取表格的行数,然后从最后一行开始遍历至第二行,逐行查找空行。如果当前行是空行,则使用 `sheet.shiftRows` 方法将该行下面的所有行上移一行,从而达到删除空行的效果,同时更新表格行数。函数 `isRowEmpty` 用于判断当前行是否为空行。
相关问题
优化这段代码 public static LinkedHashMap<String, String> excelToShopIdList(InputStream inputStream) { LinkedHashMap<String, String> res = new LinkedHashMap<>(); try { Workbook sheets = WorkbookFactory.create(inputStream); inputStream.close(); Sheet sheetAt = sheets.getSheetAt(0); // 获取设备编码 res.put("deviceCode", sheetAt.getSheetName()); int lastRowNum = sheetAt.getLastRowNum() + 1; // 标识 从该行开始解析 String[] ar = new String[]{"name", "base", "decimal", "description", "disable", "mult"}; int isTrueNum = 0; for (int i = 0; i < lastRowNum; i++) { Row row = sheetAt.getRow(i); // 空行直接跳过 if (ObjectUtils.isEmpty(row)) { isTrueNum = 0; continue; } // isTrueNum < 6 说明 和标识行没有完全匹配 if (isTrueNum < 6) { isTrueNum = 0; //和 标识行进行匹配 for (int j = 0; j < ar.length; j++) { if (ObjectUtils.isNotEmpty(row.getCell(j) ) && row.getCell(j).getCellType().equals(CellType.STRING) && ar[j].equals(row.getCell(j).getStringCellValue())) { isTrueNum++; continue; } } } else { Cell nameCell = row.getCell(0); Cell desCell = row.getCell(3); Cell typeCell = row.getCell(13); if (ObjectUtils.isEmpty(nameCell)) { continue; } if (CellType.STRING.equals(nameCell.getCellType()) && StringUtils.isEmpty(nameCell.getStringCellValue())) { continue; } // 结束标识行 if ("var_name".equals(nameCell.getStringCellValue())) { break; } res.put(nameCell.getStringCellValue(), desCell.getStringCellValue()); res.put(nameCell.getStringCellValue()+"_type#", typeCell.getStringCellValue()); } } } catch (IOException e) { e.printStackTrace(); } return res; }
这段代码可以进行如下优化:
1. 使用try-with-resources语句,自动关闭输入流。
2. 可以将Sheet对象的获取和解析逻辑单独抽出来作为一个方法,提高代码的可读性和可维护性。
3. 使用常量来代替魔法值,提高代码的可读性。
4. 使用StringUtils.isNotBlank()代替ObjectUtils.isNotEmpty()和StringUtils.isNotEmpty(),代码更简洁。
改进后的代码如下:
```
private static final String[] COLUMN_NAMES = {"name", "base", "decimal", "description", "disable", "mult"};
private static final String VAR_NAME_COLUMN_NAME = "var_name";
private static final int COLUMN_NAME_INDEX = 0;
private static final int DESCRIPTION_INDEX = 3;
private static final int TYPE_INDEX = 13;
public static LinkedHashMap<String, String> excelToShopIdList(InputStream inputStream) {
LinkedHashMap<String, String> res = new LinkedHashMap<>();
try (Workbook workbook = WorkbookFactory.create(inputStream)) {
Sheet sheet = workbook.getSheetAt(0);
String deviceCode = sheet.getSheetName();
res.put("deviceCode", deviceCode);
int lastRowIndex = sheet.getLastRowNum() + 1;
int matchedColumnCount = 0;
for (int i = 0; i < lastRowIndex; i++) {
Row row = sheet.getRow(i);
if (row == null) {
matchedColumnCount = 0;
continue;
}
if (matchedColumnCount < COLUMN_NAMES.length) {
matchedColumnCount = matchColumnNames(row);
} else {
Cell nameCell = row.getCell(COLUMN_NAME_INDEX);
if (nameCell == null || StringUtils.isBlank(nameCell.getStringCellValue())) {
continue;
}
if (VAR_NAME_COLUMN_NAME.equals(nameCell.getStringCellValue())) {
break;
}
Cell descriptionCell = row.getCell(DESCRIPTION_INDEX);
Cell typeCell = row.getCell(TYPE_INDEX);
res.put(nameCell.getStringCellValue(), descriptionCell.getStringCellValue());
res.put(nameCell.getStringCellValue() + "_type#", typeCell.getStringCellValue());
}
}
} catch (IOException e) {
e.printStackTrace();
}
return res;
}
private static int matchColumnNames(Row row) {
int matchedColumnCount = 0;
for (int j = 0; j < COLUMN_NAMES.length; j++) {
Cell cell = row.getCell(j);
if (cell != null && cell.getCellType() == CellType.STRING && COLUMN_NAMES[j].equals(cell.getStringCellValue())) {
matchedColumnCount++;
}
}
return matchedColumnCount;
}
```
删除空行后,有数据的行会位移吗
是的,在删除空行后,有数据的行会向上移动,填补空行的位置。这意味着,原来在第 N 行的数据,如果第 N 行是空行,那么它将会被移动到第 N-1 行的位置。如果你在处理表格数据时需要保持原有的行数不变,那么你可以在遍历表格时,将有数据的行复制到一个新的表格中,然后将新表格保存为一个新的 Excel 文件。以下是一个简单的示例代码:
```java
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
public class RemoveEmptyRows {
public static void main(String[] args) throws IOException {
// 读取 Excel 文件
FileInputStream input = new FileInputStream("input.xlsx");
Workbook workbook = new XSSFWorkbook(input);
Sheet sheet = workbook.getSheetAt(0);
// 创建新的 Excel 文件
Workbook newWorkbook = new XSSFWorkbook();
Sheet newSheet = newWorkbook.createSheet();
// 遍历所有行,将有数据的行复制到新表格中
int lastRow = sheet.getLastRowNum();
int newRow = 0;
for (int i = 0; i <= lastRow; i++) {
Row row = sheet.getRow(i);
if (row == null || row.getPhysicalNumberOfCells() == 0) {
// 如果是空行,则跳过
continue;
}
Row newRow = newSheet.createRow(newRow++);
for (int j = 0; j < row.getLastCellNum(); j++) {
Cell cell = row.getCell(j);
if (cell == null) {
// 如果是空单元格,则创建一个空单元格
newRow.createCell(j, CellType.BLANK);
} else {
// 如果是非空单元格,则复制单元格内容
Cell newCell = newRow.createCell(j, cell.getCellType());
switch (cell.getCellType()) {
case BOOLEAN:
newCell.setCellValue(cell.getBooleanCellValue());
break;
case NUMERIC:
newCell.setCellValue(cell.getNumericCellValue());
break;
case STRING:
newCell.setCellValue(cell.getStringCellValue());
break;
case FORMULA:
newCell.setCellFormula(cell.getCellFormula());
break;
case ERROR:
newCell.setCellErrorValue(cell.getErrorCellValue());
break;
case _NONE:
case BLANK:
break;
}
}
}
}
// 保存新的 Excel 文件
FileOutputStream output = new FileOutputStream("output.xlsx");
newWorkbook.write(output);
output.close();
newWorkbook.close();
workbook.close();
}
}
```
这段代码会读取名为“input.xlsx”的 Excel 文件,然后遍历所有行,将有数据的行复制到名为“output.xlsx”的新表格中。新表格的行数与原表格相同,但是已经去除了空行。你可以根据需要修改文件名和文件路径。
阅读全文