Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 删除Apache Poi中的特定行_Java_Excel_Apache Poi - Fatal编程技术网

Java 删除Apache Poi中的特定行

Java 删除Apache Poi中的特定行,java,excel,apache-poi,Java,Excel,Apache Poi,我需要删除包含用户输入的单词的行。这是我的代码: try { System.out.println("Write material that need to be removed: "); Scanner in = new Scanner(System.in); String toFind = in.nextLine(); FileInputStream file

我需要删除包含用户输入的单词的行。这是我的代码:

        try {
            System.out.println("Write material that need to be removed: ");
            Scanner in = new Scanner(System.in);
            String toFind = in.nextLine();
            FileInputStream file = new FileInputStream(new File("solty.xls"));

            //Create Workbook instance holding reference to .xlsx file
            HSSFWorkbook workbook = new HSSFWorkbook(file);
            DataFormatter formatter = new DataFormatter();
            HSSFSheet sheet = workbook.getSheetAt(0);

            for (Row row : sheet) {
                for (Cell cell : row) {
                    Iterator<Row> rowIterator = sheet.iterator();

                    while (rowIterator.hasNext()) {
                        Row row3 = rowIterator.next();
                        CellReference cellRef = new CellReference(row3.getRowNum(), cell.getColumnIndex());
                        
                        String text = formatter.formatCellValue(cell);

                        // is it an exact match?
                        if (toFind.equals(text)) {
                            System.out.println("Text finded at " + cellRef.formatAsString());
                            System.out.println(cellRef.getRow());
                            int rowIndex = cellRef.getRow();
                            System.out.println(row.getCell(rowIndex));
                            HSSFRow row1 = sheet.getRow(rowIndex);
                            sheet.removeRow(row1);
                            file.close();
                            FileOutputStream outFile = new FileOutputStream(new File("solty.xls"));
                            workbook.write(outFile);
                            outFile.flush();
                            outFile.close();

                        }
                        // is it a partial match?
                        else if (text.contains(toFind)) {
                            System.out.println("Index is  " + cellRef.formatAsString());


                        }


                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
试试看{
System.out.println(“写入需要删除的材料:”);
扫描仪输入=新扫描仪(系统输入);
字符串toFind=in.nextLine();
FileInputStream文件=新的FileInputStream(新文件(“solty.xls”);
//创建包含对.xlsx文件引用的工作簿实例
HSSF工作簿=新的HSSF工作簿(文件);
DataFormatter formatter=新的DataFormatter();
HSSFSheet sheet=工作簿。getSheetAt(0);
用于(行:页){
用于(单元格:行){
迭代器rowIterator=sheet.Iterator();
while(roweiterator.hasNext()){
行row3=行迭代器.next();
CellReference cellRef=新的CellReference(row3.getRowNum(),cell.getColumnIndex());
字符串文本=格式化程序。formatCellValue(单元格);
//这是一模一样的吗?
if(toFind.equals(文本)){
System.out.println(“在“+cellRef.formatAsString()处查找的文本”);
System.out.println(cellRef.getRow());
int rowIndex=cellRef.getRow();
System.out.println(row.getCell(rowIndex));
HSSFRow row1=sheet.getRow(rowIndex);
第1行(第1行);
file.close();
FileOutputStream outFile=新的FileOutputStream(新文件(“solty.xls”));
工作簿。写入(输出文件);
outFile.flush();
outFile.close();
}
//这是部分匹配吗?
else if(text.contains(toFind)){
System.out.println(“索引为”+cellRef.formatAsString());
}
}
}
}
}捕获(IOE异常){
e、 printStackTrace();
}
}
}

但问题是它会一致地删除行,而不是包含用户单词的行。即使它工作,它也有例外:ConcurrentModificationException

抛出
ConcurrentModificationException
,因为
Sheet.removeRow
迭代器迭代该工作表的行时尝试更改行。这是不可能的

因此,您需要以另一种方式获取行,而不是使用
迭代器。例如,使用
For
循环,使用
int r
sheet.getRow(r)
获取行

但是
Sheet.removeow
有一个误导性的名字。它并不真正删除行,而是只从图纸的存储中删除行,而不向上移动下面的行。所以事实上,它只是完全清空了这一行。如果确实要删除该行,则需要使用
Sheet.shiftRows
Sheet.shiftRows
在以前版本的ApachePOI
中有很多bug。因此,它只能在使用当前的ApachePOI5.0.0时正常工作

但是使用
Sheet.shiftRows
每次移动都会影响行号。因此,使用
int r
sheet.getRow(r)
for
循环需要从下到上向后循环,否则它将尝试获取已经删除的行号

下面的代码应该使用当前的
ApachePOI5.0.0
并删除包含
字符串toFind
作为内容的单元格的所有行

import java.io.FileOutputStream;
import java.io.FileInputStream;

import org.apache.poi.ss.usermodel.*;

class RemoveSpecificRows {

 public static void main(String[] args) throws Exception {
     
  System.out.println("Write material that need to be removed: ");
  java.util.Scanner in = new java.util.Scanner(System.in);
  String toFind = in.nextLine();

  try (Workbook workbook = WorkbookFactory.create(new FileInputStream("ExcelSource.xls")); 
       FileOutputStream fileout = new FileOutputStream("ExcelResult.xls") ) {

   DataFormatter formatter = new DataFormatter();
   
   Sheet sheet = workbook.getSheetAt(0);
   
   for (int r = sheet.getLastRowNum(); r >=0;  r--) {
    Row row = sheet.getRow(r);
    if (row != null) {
     for (int c = 0; c < row.getLastCellNum(); c++) {
      Cell cell = row.getCell(c);
      String value = formatter.formatCellValue(cell);
      if (toFind.equals(value)) {
       System.out.println("Text " + toFind + " found at " + cell.getAddress()); 
       //sheet.removeRow(row); //this only empties the row
       sheet.shiftRows(r + 1, sheet.getLastRowNum() + 2, -1); //shift row below up to last row once up
       break;
      }
     }
    }      
   }

   workbook.write(fileout);

  }

 }
}
import java.io.FileOutputStream;
导入java.io.FileInputStream;
导入org.apache.poi.ss.usermodel.*;
类RemoveSpecifics{
公共静态void main(字符串[]args)引发异常{
System.out.println(“写入需要删除的材料:”);
java.util.Scanner in=new java.util.Scanner(System.in);
字符串toFind=in.nextLine();
尝试(工作簿=WorkbookFactory.create(新文件输入流(“ExcelSource.xls”));
FileOutputStream fileout=新的FileOutputStream(“ExcelResult.xls”)){
DataFormatter formatter=新的DataFormatter();
工作表=工作簿。getSheetAt(0);
对于(int r=sheet.getLastRowNum();r>=0;r--){
Row Row=sheet.getRow(r);
如果(行!=null){
对于(int c=0;c
兄弟,你真的救了我的命。非常感谢你。我一个星期内解决不了这个问题!还有一个问题。如何将删除的行插入另一个Excel文档?请在此提供帮助?@senseiton:否。首先,这必须作为StackOverflow中的另一个问题来提问。其次,在我看来,将军是不可能的。行和单元格在许多方面与其工作表和工作簿相关。所以从一张纸上得到一行,然后把那一行放到另一张纸上是不可能的。如果该附加工作表位于不同的工作簿中,则通常是不可能的。所以我又问了一个问题