我正在使用java和Apache POI Library编写接口。我在删除空行时遇到问题。我的代码是:
public class ExcelDeleteRowsCols {
final short ROW_START = 0;
final short COL_START = 0;
public void deleteRows() {
try {
// Open file
FileInputStream inf = new FileInputStream("in.xls");
Workbook wb = WorkbookFactory.create(inf);
// Loop every sheets of workbook
for (Sheet sheet : wb){
// Loop every rows of this sheet
int lastIndex = sheet.getLastRowNum();
for (int i = ROW_START; i <= lastIndex; i++) {
if (sheet.getRow(i) == null || sheet.getRow(i).getCell(COL_START) == null || sheet.getRow(i).getCell(COL_START).toString().equals("")){
sheet.removeRow(sheet.getRow(i)); //sheet.shiftRows(i, lastIndex, 2);
}
}
}
// Save as in another file
FileOutputStream fileOut = new FileOutputStream("out.xls");
wb.write(fileOut);
fileOut.flush();
fileOut.close();
System.out.println("Finished!");
} catch (IOException ioe) {
System.out.println(ioe);
} catch (Exception e) {
System.out.println(e);
}
}
}
问题在于,在具有空单元格的行中显示异常消息java.lang.NullPointerException。我不明白。 Excel示例:
“空单元格” 2号线 3号线 4号线 5号线 “空单元” Line7 Line8 Line9 Line10 Line11 Line12 Line13
如果没有空单元格,代码工作正常......
请你能帮帮我吗?
提前致谢。
答案 0 :(得分:2)
当然你不能使用
sheet.removeRow(row)
当你的行为空时
正如我在您的代码中看到的那样,您只想在&#34; in.xls&#34;中保留非空行。将文件写入&#34; out.xls&#34; ,所以我建议你这样改变算法:
Workbook wbOut = new HSSFWorkbook(); // or whatever workbook you'd like to use
for (Sheet sheet : wb){
Sheet newSheet = wbOut.createSheet();
int newI = 0;
// Loop every rows of this sheet
int lastIndex = sheet.getLastRowNum();
for (int i = ROW_START; i <= lastIndex; i++) {
// the exact opposite condition
if (sheet.getRow(i) != null &&
sheet.getRow(i).getCell(COL_START) != null &&
!sheet.getRow(i).getCell(COL_START).toString().equals("")){
// row is not null so you can copy it to a new sheet
Row newRow = newSheet.createRow(newI++);
newRow = sheet.getRow(i);
}
}
}
// Save as in another file
FileOutputStream fileOut = new FileOutputStream("out.xls");
wbOut.write(fileOut);
fileOut.flush();
fileOut.close();
因此,您只将非空行复制到最终可以编写的新工作簿中。
答案 1 :(得分:0)
因此,您真的想要关闭电子表格中的空行,而不是删除行。也就是说,移动包含数据的行,以便中间没有空行。
我完全改变了这个答案,考虑到这一点。
FileInputStream inf = new FileInputStream("Row_Delete_Test.xlsx");
Workbook wb = WorkbookFactory.create(inf);
for (Sheet sh : wb) {
int previousIndex = sh.getFirstRowNum();
if (previousIndex > 0) {
sh.shiftRows(px, sh.getLastRowNum(), -px);
previousIndex = 0;
}
for (Row row : sh) {
boolean deleteRow = true;
for (Cell cell : row) {
if (!cell.toString().trim().equals("")) {
deleteRow = false;
break;
}
}
int currentIndex = row.getRowNum();
if (deleteRow) {
sh.removeRow(row);
} else {
if (currentIndex > previousIndex + 1) {
sh.shiftRows(row.getRowNum(), sh.getLastRowNum(), previousIndex - currentIndex + 1);
currentIndex = previousIndex + 1;
}
previousIndex = currentIndex;
}
}
}
FileOutputStream fileOut = new FileOutputStream("Row_Delete_Test.xlsx");
wb.write(fileOut);
wb.close();
fileOut.close();
这会产生&#34;删除&#34;电子表格中的行。
注意:Excel电子表格实际上只包含带有单元格的行,并且只包含带有数据的单元格。这些数据几乎可以是任何东西,包括空白,所以如果你也想要删除&#34;在唯一的单元格值为空的行中,则必须搜索该行。
以下是一些示例数据(请注意,这是来自sheet1.xml
文件中的Row_Delete_Test.xlsx
)
<sheetData>
<row r="2" spans="2:3" x14ac:dyDescent="0.25">
<c r="B2" t="s">
<v>0</v>
</c>
</row>
<row r="5" spans="2:3" x14ac:dyDescent="0.25">
<c r="B5" t="s">
<v>1</v>
</c>
</row>
<row r="6" spans="2:3" x14ac:dyDescent="0.25">
<c r="C6" t="s">
<v>4</v>
</c>
</row>
<row r="7" spans="2:3" x14ac:dyDescent="0.25">
<c r="B7" t="s">
<v>2</v>
</c>
</row>
<row r="8" spans="2:3" x14ac:dyDescent="0.25">
<c r="B8" t="s">
<v>3</v>
</c>
</row>
<row r="9" spans="2:3" x14ac:dyDescent="0.25">
<c r="C9" t="s">
<v>4</v>
</c>
</row>
</sheetData>
我将告诉你,因为除了查看共享字符串表之外你无法知道,<v>4</v>
指定的共享字符串4只是一个空白值。其他共享字符串值为<v>0</v>
=&#39;第1行&#39;,<v>1</v>
=&#39;第2行&#39;,<v>2</v>
=&#39;第3行& #39;和<v>3</v>
=&#39;第4行和第39行。因此,这里填充了行2和5到9,每行都有一个单元格,其中包含数据。第6行和第9行各自在C列中有一个空白值的单元格。
运行上面的代码后,sheetData看起来像这样
<sheetData>
<row r="1" spans="2:3" x14ac:dyDescent="0.25">
<c r="B1" t="s">
<v>0</v>
</c>
</row>
<row r="2" spans="2:3" x14ac:dyDescent="0.25">
<c r="B2" t="s">
<v>1</v>
</c>
</row>
<row r="3" spans="2:3" x14ac:dyDescent="0.25">
<c r="B3" t="s">
<v>2</v>
</c>
</row>
<row r="4" spans="2:3" x14ac:dyDescent="0.25">
<c r="B4" t="s">
<v>3</v>
</c>
</row>
</sheetData>
现在只有1-4行在电子表格中。第2行已移至第1行,第5行,第2行,第7行至第3行以及第8行至第4行。
答案 2 :(得分:0)
我有这个xls文件:
我的目标是删除每一个空行,对于这个问题,我认为最好的选择是Java中的OPI。代码是:
public class ExcelDeleteRowsCols {
final short ROW_START = 0;
final short COL_START = 0;
public void deleteRows() {
try {
// Open file
FileInputStream inf = new FileInputStream("in.xls");
Workbook wb = WorkbookFactory.create(inf);
// Loop every sheets of workbook
for (Sheet sheet : wb){
// Loop every rows of this sheet
int lastIndex = sheet.getLastRowNum();
for (int i = ROW_START; i <= lastIndex; i++) {
if (sheet.getRow(i) == null || sheet.getRow(i).getCell(COL_START) == null || sheet.getRow(i).getCell(COL_START).toString().equals("")){
sheet.removeRow(sheet.getRow(i));
}
}
}
// Save as in another file
FileOutputStream fileOut = new FileOutputStream("out.xls");
wb.write(fileOut);
fileOut.flush();
fileOut.close();
System.out.println("Finished!");
} catch (IOException ioe) {
System.out.println(ioe);
} catch (Exception e) {
System.out.println(e);
}
}
}
当行为空时,代码工作正常,但问题是当行为空时( sheet.getRow(i)== null )。例如,在xls第2行,第12行,第15行和第16行中,您的值为null,然后它不会被删除,因为命令 sheet.removeRow(sheet.getRow(i)); 通过NullPointer抛出和异常。
有没有办法删除值为null的行?