JAVA删除excel指定列

news/2024/7/21 4:20:33 标签: java, excel, 开发语言

首先POI没有提供删除列的API,所以就需要用其他的方式实现。

在 java - Apache POI xls column Remove - Stack Overflow 这里找到了实现方式:

先将该列所有值都清空,然后将该列之后的所有列往前移动。

下面的工具类中 

deleteColumns(InputStream excelStream, List<String> delColumnTitleList)方法实现了批量删除列的逻辑。

java">import lombok.SneakyThrows;
import org.apache.poi.ss.usermodel.Cell;
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.xssf.usermodel.XSSFWorkbook;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

/**
 * @Description
 * @ClassName ExcelUtil
 * @Date 2022/12/23 11:38
 */
public class ExcelUtil {

    /**
     * 获取sheet表头
     * @param sheet
     * @return
     */
    public static List<String> getTitle(Sheet sheet) {
        List<String> titleList = new ArrayList<>();
        if (sheet.getPhysicalNumberOfRows() > 0) {
            Row headerRow = sheet.getRow(0); // 获取第一行(表头行)

            for (int i = 0; i < headerRow.getPhysicalNumberOfCells(); i++) {
                Cell cell = headerRow.getCell(i);
                if (cell != null) {
                    String headerText = cell.getStringCellValue();
                    titleList.add(headerText);
                }
            }
        }
        return titleList;
    }

    /**
     * 删除excel指定列
     * @param excelStream excel流
     * @param delColumnTitleList 需要删除的列的表头
     * @return
     */
    @SneakyThrows
    public static ByteArrayOutputStream deleteColumns(InputStream excelStream, List<String> delColumnTitleList) {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

        Workbook workbook = new XSSFWorkbook(excelStream);
        // 获取第一个sheet
        Sheet sheet = workbook.getSheetAt(0);
        deleteColumns(sheet, delColumnTitleList);
        workbook.write(outputStream);
        workbook.close();
        outputStream.close();
        return outputStream;
    }

    /**
     * 删除sheet指定的列
     * @param sheet
     * @param delColumnTitleList
     */
    public static void deleteColumns(Sheet sheet, List<String> delColumnTitleList) {
        List<String> titleList = getTitle(sheet);
        for (String delTitle : delColumnTitleList) {
            int i = titleList.indexOf(delTitle);
            if (i >= 0) {
                deleteColumn(sheet, i);
            }
            //由于是循环删除,删除后,列所在位置索引会变化,所以titleList相应也移除删除的列
            titleList.remove(delTitle);
        }
    }

    /**
     * 删除指定列
     * poi没有提供删除指定列的api,所以先将该列清空,然后将后续的列往前移动,这样达到删除列的效果
     * @param sheet
     * @param columnToDelete
     */
    public static void deleteColumn(Sheet sheet, int columnToDelete) {
        int maxColumn = 0;
        for (int r = 0; r < sheet.getLastRowNum() + 1; r++) {
            Row row = sheet.getRow(r);

            // if no row exists here; then nothing to do; next!
            if (row == null) {
                continue;
            }

            // if the row doesn't have this many columns then we are good; next!
            int lastColumn = row.getLastCellNum();
            if (lastColumn > maxColumn) {
                maxColumn = lastColumn;
            }

            if (lastColumn < columnToDelete) {
                continue;
            }

            for (int x = columnToDelete + 1; x < lastColumn + 1; x++) {
                Cell oldCell = row.getCell(x - 1);
                if (oldCell != null) {
                    row.removeCell(oldCell);
                }

                Cell nextCell = row.getCell(x);
                if (nextCell != null) {
                    Cell newCell = row.createCell(x - 1, nextCell.getCellType());
                    cloneCell(newCell, nextCell);
                }
            }
        }

        // Adjust the column widths
        for (int c = 0; c < maxColumn; c++) {
            sheet.setColumnWidth(c, sheet.getColumnWidth(c + 1));
        }
    }

    /**
     * 右边列左移
     */
    private static void cloneCell(Cell cNew, Cell cOld) {
        cNew.setCellComment(cOld.getCellComment());
        cNew.setCellStyle(cOld.getCellStyle());

        switch (cNew.getCellTypeEnum()) {
            case BOOLEAN: {
                cNew.setCellValue(cOld.getBooleanCellValue());
                break;
            }
            case NUMERIC: {
                cNew.setCellValue(cOld.getNumericCellValue());
                break;
            }
            case STRING: {
                cNew.setCellValue(cOld.getStringCellValue());
                break;
            }
            case ERROR: {
                cNew.setCellValue(cOld.getErrorCellValue());
                break;
            }
            case FORMULA: {
                cNew.setCellFormula(cOld.getCellFormula());
                break;
            }
        }

    }

}


http://www.niftyadmin.cn/n/5121408.html

相关文章

MindShow邀请码

MindShow邀请码 Mindshow是一款强大的AI制作PPT演示工具。它能够帮助用户自动创建演示文稿&#xff0c;无需逐页输入文本、调整字体大小和位置。利用Mindshow&#xff0c;您只需要使用大纲&#xff0c;就可以轻松修改所有幻灯片的内容和样式。 邀请码&#xff1a;6918322 地址…

Android APP 隐藏系统软键盘的方法

1.场景描述&#xff1a; 1) APP项目中经常会开发自定义软键盘&#xff1b;同时在使用EditText时&#xff0c;也会常常遇到自动弹出系统自带的软键盘&#xff0c;与自定义的软键盘产生冲突的情况&#xff1b;此时需要禁止EditText自动弹出系统软键盘&#xff0c;从而使自定义的…

电厂数据可视化三维大屏展示平台加强企业安全防范

园区可视化大屏是一种新型的信息化手段&#xff0c;能够将园区内各项数据信息以图像的形式直观呈现在大屏幕上&#xff0c;便于管理员和员工进行实时监控、分析和决策。本文将从以下几个方面介绍园区可视化大屏的作用和应用。 VR数字孪生园区系统是通过将实际园区的各种数据和信…

从厨房间到股市:家庭主妇的华美转身

我一直是一个安于现状的家庭主妇。生活中&#xff0c;我热爱烹饪、园艺和照顾家人&#xff0c;但我也渴望能有更多的自我实现和价值感。在机缘巧合下&#xff0c;我接触到了卓扬网&#xff0c;一个专业的股票投资平台。从那刻起&#xff0c;我的人生发生了翻天覆地的变化。 初…

5083: 【递推】走方格

题目描述 在平面上有一些二维的点阵。 这些点的编号就像二维数组的编号一样&#xff0c;从上到下依次为第 1 至第 n 行&#xff0c;从左到右依次为第 1 至第 m 列&#xff0c;每一个点可以用行号和列号来表示。 现在有个人站在第 1 行第 1 列&#xff0c;要走到第 n 行第 m …

井盖异动传感器丨井盖状态监测仪助力排水管网系统装上“眼睛”

智慧排水技术作为现代城市管理的重要组成部分&#xff0c;正在以其高效、可持续和环保的特点在全球范围内得到广泛应用。 随着城市化进程的不断加速&#xff0c;城市面临着日益严重的排水管理挑战。国家政府也在《全国城市市政基础设施建设“十三五”规划》等明确要求建设城市…

从0到1配置TensorRT环境

根据博文&#xff1a;TensorFlow2.x模型转onnx、TensorRT给出的环境来配置。 以下是该博文中给出的版本信息 TensorFlow 2.4 CUDA 11.1 CUDNN 8 TensorRT 8.2.1.8 tf2onnx 1.13.0 onnx 1.12.0 下载地址 包下载地址TensorRT 8.2.1.8https://developer.nvidia.com/nvidia-tenso…

C++基础语法——智能指针

目录 1.智能指针存在的意义 2.内存泄漏 ①什么是内存泄漏&#xff0c;内存泄漏的危害 ②内存泄漏分类 ③如何检测内存泄漏 ④如何避免内存泄漏 3.智能指针的使用及其模拟实现 ①RAII ②智能指针的原理 ③std::auto_ptr 模拟实现 ④std::unique_ptr 模拟实现 ⑤st…