Java 如何使用ApachePOI删除行

Java 如何使用ApachePOI删除行,java,apache-poi,Java,Apache Poi,我试图移走第三排 这是我根据Tman、Leo和zibi的评论所做的编辑。多谢各位 public class MainTest { public static void main(String[] args) throws IOException { FileInputStream file = new FileInputStream(new File("test.xlsx") ); XSSFWorkbook wb = new XSSFWorkb

我试图移走第三排

这是我根据Tman、Leo和zibi的评论所做的编辑。多谢各位

public class MainTest {

    public static void main(String[] args) throws IOException {

        FileInputStream file  =   new FileInputStream(new  File("test.xlsx") );
        XSSFWorkbook wb = new XSSFWorkbook(file);
        XSSFSheet sheet = wb.getSheetAt(0);
        sheet.removeRow(sheet.getRow(3));
//      sheet.shiftRows(3, 3, -1);

        File outWB = new File("testResult.xlsx");
        OutputStream out = new FileOutputStream(outWB);
        wb.write(out);
        out.flush();
        out.close();


        System.exit(0);
    }

}

但这会删除一行中的值,但不会删除该行

如果您使用的是XLS文件(不是XLSX),则应使用HSSFWorkbook。我刚刚测试了下面的解决方案,一切正常:

    File file = new File(....);
    FileInputStream fis = new FileInputStream(file);
    HSSFWorkbook wb = new HSSFWorkbook(fis);
    HSSFSheet sheet = wb.getSheetAt(0);

    sheet.shiftRows(3, 3, -1);

    File outWB = new File(.....);
    OutputStream out = new FileOutputStream(outWB);
    wb.write(out);
    out.flush();
    out.close();
甚至最好使用工作簿工厂,它可以为您识别类型:

    Workbook wb = WorkbookFactory.create(file);
    Sheet sheet = wb.getSheetAt(0);
    sheet.shiftRows(3, 3, -1);
下面您可以找到一个执行行删除的函数,它可以在xls和xlsx中使用(已测试;)

Workbook wb=WorkbookFactory.create(文件);
Sheet Sheet=wb.getSheetAt(0);
拆卸工具(第2页);
File outhb=新文件(…);
OutputStream out=新文件OutputStream(outWB);
wb.写(出);
out.flush();
out.close();
公共静态无效清除程序(工作表,int行索引){
int lastRowNum=sheet.getLastRowNum();
如果(rowIndex>=0&&rowIndex
尝试更好的特殊功能


此外,XSSFWorkbook还可以使用.xlsx扩展名

请参见移位行的定义:

在开始行和结束行之间移动行数n行。如果使用负数,它会将行上移。代码确保行不会环绕。调用shiftRows(startRow、endRow、n、false、false)
另外移动在这些行中完全定义的合并区域(即在要移动的行上合并2个单元格)。


因此,为了删除第三行,需要使用
startRow=3
(零基索引,因此基本上是第四行),
endRow=sheet.getLastRowNum()
n=-1
将所选行从第4行向上移动到最后一行,向上移动1行。

当我使用以下方法而不是删除单个行时,我能够将200行从大约300行从4s快速删除到0,4s:

    for (Sheet currentSheet: workbook) {                
        RowDeleter rowDeleter = new RowDeleter(currentSheet);
       ...
        if (..) rowDeleter.removeRow(i);
       ...
       rowDeleter.execute();
    }

static class RowDeleter {
    private final Sheet sheet;
    private final boolean[] deleted;

    public RowDeleter(Sheet sheet) {
        this.sheet = sheet;
        deleted = new boolean[sheet.getLastRowNum()+1];
        Arrays.fill(deleted, false);
    }
    
    public void removeRow(int rowIndex) {
        deleted[rowIndex] = true;
    }
    
    public void execute() {
        int first = -1;
        int last = -1;
        for (int i = deleted.length-1; i>=0; i--) {
            if (deleted[i]) {
                first = i;
                if (last < 0) {
                    last = i;
                }
            } else if (first >= 0) {
                removeRows(first, last-first+1); 
                first = -1;
                last = -1;
            }
        }
        
    }
    void removeRows(int rowIndex, int count) {
        int lastRowNum = sheet.getLastRowNum();
        if (rowIndex >= 0 && rowIndex < lastRowNum) {
            sheet.shiftRows(rowIndex + count, lastRowNum, -count);
        }
        if (rowIndex == lastRowNum) {
            Row removingRow = sheet.getRow(rowIndex);
            if (removingRow != null) {
                sheet.removeRow(removingRow);
            }
        }
    }
}
用于(当前工作表:工作簿){
RowDeleter RowDeleter=新的RowDeleter(当前工作表);
...
如果(..)行删除器删除程序(i);
...
rowDeleter.execute();
}
静态类行删除器{
私人最后一页;
删除私有最终布尔[];
公共行删除器(第页){
this.sheet=sheet;
已删除=新布尔值[sheet.getLastRowNum()+1];
数组。填充(已删除,false);
}
公共无效删除行(整数行索引){
已删除[rowIndex]=真;
}
public void execute(){
int first=-1;
int last=-1;
对于(int i=deleted.length-1;i>=0;i--){
如果(删除[i]){
第一个=i;
如果(最后一次<0){
last=i;
}
}else if(第一个>=0){
移除器(第一,最后第一+1);
第一个=-1;
last=-1;
}
}
}
无效删除行(整数行索引,整数计数){
int lastRowNum=sheet.getLastRowNum();
如果(rowIndex>=0&&rowIndex
我希望excel不希望出现xlsx文件您将第3行下移1。用负数来转移。如果你帮助我,你可以考虑接受我的回答:+ 1谢谢。这真是太棒了。但是我使用的是
xlsx
。请将您的答案修改为
xlsx
谢谢。它会删除一行中的所有值,但不会删除该行。我已经发布了一个更新,Apache 4.0.1中的一个bug阻止了它的工作,这里也讨论了它
Specified by: shiftRows(...) in Sheet
Parameters:
    startRow the row to start shifting
    endRow the row to end shifting
    n the number of rows to shift
    for (Sheet currentSheet: workbook) {                
        RowDeleter rowDeleter = new RowDeleter(currentSheet);
       ...
        if (..) rowDeleter.removeRow(i);
       ...
       rowDeleter.execute();
    }

static class RowDeleter {
    private final Sheet sheet;
    private final boolean[] deleted;

    public RowDeleter(Sheet sheet) {
        this.sheet = sheet;
        deleted = new boolean[sheet.getLastRowNum()+1];
        Arrays.fill(deleted, false);
    }
    
    public void removeRow(int rowIndex) {
        deleted[rowIndex] = true;
    }
    
    public void execute() {
        int first = -1;
        int last = -1;
        for (int i = deleted.length-1; i>=0; i--) {
            if (deleted[i]) {
                first = i;
                if (last < 0) {
                    last = i;
                }
            } else if (first >= 0) {
                removeRows(first, last-first+1); 
                first = -1;
                last = -1;
            }
        }
        
    }
    void removeRows(int rowIndex, int count) {
        int lastRowNum = sheet.getLastRowNum();
        if (rowIndex >= 0 && rowIndex < lastRowNum) {
            sheet.shiftRows(rowIndex + count, lastRowNum, -count);
        }
        if (rowIndex == lastRowNum) {
            Row removingRow = sheet.getRow(rowIndex);
            if (removingRow != null) {
                sheet.removeRow(removingRow);
            }
        }
    }
}