java poi拆分excel文件,每个文件保留标题行

简介: java poi拆分excel文件,每个文件保留标题行

一、背景

在工作中,经常需要处理excel文件,将提供的excel文件导入数据库,有时候文件太大我们就需要做拆分了,下面实现将xlsx文件和xls文件按行数拆分,每个文件都保留标题行。这篇文件接着拆分csv大文件进行说明。

二、后端代码

1、我们需要引入poi的依赖

        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>4.0.1</version>
        </dependency>
        <!-- 07版本以后的格式 -->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>4.0.1</version>
        </dependency>

2、拆分xls类型的文件方法


(1)参数inputStream为要拆分的文件流


(2)参数fileName为拆分文件名


(3)参数splitSize为拆分后每个文件的最大行数


(4)思路:根据前端传的excel文件流转换为一个Workbook文件,创建Workbook文件目的就是能够更好的操作excel,然后获取总行数,根据传到splitSize计算出需要创建几个excel文件,然后创建需要的若干个空excel放入list集合中,遍历原始excel,遍历时有行,单元格的概念,这个poi都能够操作,原始文件第一行的所有单元格都遍历到每个拆分文件的第一行,其余行随机往拆分文件里面一行一行的写,写到最后,将拆分文件集合中的Workbook文件写入存放拆分文件的目录中,关流。

   /**
     * 拆分xls文件并返回文件夹路径
     * @param inputStream
     * @param fileName
     * @param splitSize
     * @return
     */
    public static String getXlsZipPath(InputStream inputStream, String fileName, int splitSize) {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        Workbook workBook = null;
        try {
            workBook = WorkbookFactory.create(inputStream);
        } catch (Exception e) {
            logger.error("Load excel file error!", e);
            return null;
        }
        try {
            Sheet sheet = workBook.getSheetAt(0);
            Iterator<Row> rowIterator = sheet.rowIterator();
            int totalRows = sheet.getPhysicalNumberOfRows();
            int splitNumber = (int) ((totalRows % splitSize == 0) ? (totalRows / splitSize) : (totalRows / splitSize + 1));
            logger.info("xls文件总行数: {}行  拆分文件个数:{}个", totalRows, splitNumber);
            List<HSSFWorkbook> hssfWorkbooks = new ArrayList<>();
            //创建存放拆分文件的目录,文件夹存在,可能里面有内容,删除所有内容
            File dir = new File(defaultDir + fileName);
            if (dir.exists()) {
                delAllFile(dir.getAbsolutePath());
            }
            dir.mkdirs();
            //创建的拆分文件写入流并放入集合中
            for (int count = 0; count < splitNumber; count++) {
                HSSFWorkbook hssfWorkbook = new HSSFWorkbook();
                hssfWorkbook.createSheet().createRow(0);
                hssfWorkbooks.add(hssfWorkbook);
            }
            int oldRow = 0;
            while (rowIterator.hasNext()) {
                Row row = rowIterator.next();
                if (row.getRowNum() == 0) {
                    oldRow++;
                    Iterator<Cell> cellIterator = row.cellIterator();
                    int index = 0;
                    while (cellIterator.hasNext()) {
                        Cell next = cellIterator.next();
//                        解决获取excel数据的方法与实际类型不符
                        next.setCellType(CellType.STRING);
                        String value = next.getStringCellValue();
                        for (int count = 0; count < splitNumber; count++) {
                            HSSFRow row1 = hssfWorkbooks.get(count).getSheetAt(0).getRow(0);
                            row1.createCell(index).setCellValue(value);
                        }
                        index++;
                    }
                }
                if (row.getRowNum() != 0) {
                    Iterator<Cell> cellIterator = row.cellIterator();
                    HSSFWorkbook hssfWorkbook = hssfWorkbooks.get(oldRow % splitNumber);
                    HSSFSheet sheet1 = hssfWorkbook.getSheetAt(0);
                    int index = 0;
                    HSSFRow row1 = sheet1.createRow(sheet1.getLastRowNum() + 1);
                    while (cellIterator.hasNext()) {
                        Cell next = cellIterator.next();
                        next.setCellType(CellType.STRING);
                        String value = next.getStringCellValue();
                        row1.createCell(index++).setCellValue(value);
                    }
                    oldRow++;
                }
            }
            //创建拆分文件并关流
            for (int i = 0; i < hssfWorkbooks.size(); i++) {
                String splitFilePath = defaultDir + fileName + File.separator + fileName + i + ".xlsx";
                File file = new File(splitFilePath);
                file.createNewFile();
                FileOutputStream outputStream = new FileOutputStream(file);
                hssfWorkbooks.get(i).write(outputStream);
                hssfWorkbooks.get(i).close();
            }
        } catch (IOException e) {
            logger.error("拆分xls文件失败  :" + e);
        }
        stopWatch.stop();
        logger.info("xls文件拆分共花费:  " + stopWatch.getTotalTimeMillis() + " ms");
        return defaultDir + fileName + File.separator;
    }

3、拆分xlsx类型的文件方法


(1)参数inputStream为要拆分的文件流


(2)参数fileName为拆分文件名


(3)参数splitSize为拆分后每个文件的最大行数


(4)思路:根据前端传的excel文件流转换为一个Workbook文件,创建Workbook文件目的就是能够更好的操作excel,然后获取总行数,根据传到splitSize计算出需要创建几个excel文件,然后创建需要的若干个空excel放入list集合中,遍历原始excel,遍历时有行,单元格的概念,这个poi都能够操作,原始文件第一行的所有单元格都遍历到每个拆分文件的第一行,其余行随机往拆分文件里面一行一行的写,写到最后,将拆分文件集合中的Workbook文件写入存放拆分文件的目录中,关流。

    /**
     * 拆分xlsx文件并返回文件夹路径
     *
     * @param inputStream
     * @param fileName
     * @param splitSize
     * @return
     */
    public static String getXlsxZipPath(InputStream inputStream, String fileName, int splitSize) {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        Workbook workBook = null;
        try {
            workBook = WorkbookFactory.create(inputStream);
        } catch (Exception e) {
            logger.error("Load excel file error!", e);
            return null;
        }
        try {
            Sheet sheet = workBook.getSheetAt(0);
            Iterator<Row> rowIterator = sheet.rowIterator();
            int totalRows = sheet.getPhysicalNumberOfRows();
            int splitNumber = (int) ((totalRows % splitSize == 0) ? (totalRows / splitSize) : (totalRows / splitSize + 1));
            logger.info("xlsx文件总行数: {}行  拆分文件个数:{}个", totalRows, splitNumber);
            List<XSSFWorkbook> xssfWorkbooks = new ArrayList<>();
            //创建存放拆分文件的目录,文件夹存在,可能里面有内容,删除所有内容
            File dir = new File(defaultDir + fileName);
            if (dir.exists()) {
                delAllFile(dir.getAbsolutePath());
            }
            dir.mkdirs();
            //创建的拆分文件写入流并放入集合中
            for (int count = 0; count < splitNumber; count++) {
                XSSFWorkbook xssfWorkbook = new XSSFWorkbook();
                xssfWorkbook.createSheet().createRow(0);
                xssfWorkbooks.add(xssfWorkbook);
            }
            int oldRow = 0;
            while (rowIterator.hasNext()) {
                Row row = rowIterator.next();
                if (row.getRowNum() == 0) {
                    oldRow++;
                    Iterator<Cell> cellIterator = row.cellIterator();
                    int index = 0;
                    while (cellIterator.hasNext()) {
                        Cell next = cellIterator.next();
                        next.setCellType(CellType.STRING);
                        String value = next.getStringCellValue();
                        for (int count = 0; count < splitNumber; count++) {
                            XSSFRow row1 = xssfWorkbooks.get(count).getSheetAt(0).getRow(0);
                            row1.createCell(index).setCellValue(value);
                        }
                        index++;
                    }
                }
                if (row.getRowNum() != 0) {
                    Iterator<Cell> cellIterator = row.cellIterator();
                    XSSFWorkbook xssfWorkbook = xssfWorkbooks.get(oldRow % splitNumber);
                    XSSFSheet sheet1 = xssfWorkbook.getSheetAt(0);
                    int index = 0;
                    XSSFRow row1 = sheet1.createRow(sheet1.getLastRowNum() + 1);
                    while (cellIterator.hasNext()) {
                        Cell next = cellIterator.next();
                        next.setCellType(CellType.STRING);
                        String value = next.getStringCellValue();
                        row1.createCell(index++).setCellValue(value);
                    }
                    oldRow++;
                }
            }
            //创建拆分文件并关流
            for (int i = 0; i < xssfWorkbooks.size(); i++) {
                String splitFilePath = defaultDir + fileName + File.separator + fileName + i + ".xlsx";
                File file = new File(splitFilePath);
                file.createNewFile();
                FileOutputStream outputStream = new FileOutputStream(file);
                xssfWorkbooks.get(i).write(outputStream);
                xssfWorkbooks.get(i).close();
            }
        } catch (IOException e) {
            logger.error("拆分xlsx文件失败  :" + e);
        }
        stopWatch.stop();
        logger.info("xlsx文件拆分共花费:  " + stopWatch.getTotalTimeMillis() + " ms");
        return defaultDir + fileName + File.separator;
    }

4、这两种方法具体用哪一个需要在使用之前判断传过来的文件类型。

5、上面需要用到的删除文件方法如下

  /***
     * 删除文件夹
     *
     */
    public static void delFolder(String folderPath) {
        try {
            delAllFile(folderPath); // 删除完里面所有内容
            String filePath = folderPath;
            filePath = filePath.toString();
            File myFilePath = new File(filePath);
            myFilePath.delete(); // 删除空文件夹
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /***
     * 删除指定文件夹下所有文件
     *
     * @param path 文件夹完整绝对路径
     * @return
     */
    public static boolean delAllFile(String path) {
        boolean flag = false;
        File file = new File(path);
        if (!file.exists()) {
            return flag;
        }
        if (!file.isDirectory()) {
            return flag;
        }
        String[] tempList = file.list();
        File temp = null;
        for (int i = 0; i < tempList.length; i++) {
            if (path.endsWith(File.separator)) {
                temp = new File(path + tempList[i]);
            } else {
                temp = new File(path + File.separator + tempList[i]);
            }
            if (temp.isFile()) {
                temp.delete();
            }
            if (temp.isDirectory()) {
                delAllFile(path + "/" + tempList[i]);// 先删除文件夹里面的文件
                delFolder(path + "/" + tempList[i]);// 再删除空文件夹
                flag = true;
            }
        }
        return flag;
    }
目录
相关文章
|
数据库
psc文件文件如何导入数据库
psc文件文件如何导入数据库
360 0
|
负载均衡 网络协议 安全
slb选择监听协议和端口
阿里云SLB中,监听协议(TCP、HTTP、HTTPS)与端口(80、443等)决定客户端请求的处理方式。TCP适用于纯TCP或自处理HTTP的场景,HTTP用于智能调度Web服务,HTTPS提供安全的HTTP传输。监听端口通常匹配应用标准,如80 for HTTP,443 for HTTPS。配置时,可考虑HTTPS重定向和传递`X-Forwarded-Proto`头以识别请求来源。选择应基于业务需求和安全考虑。
769 3
|
存储 easyexcel Java
阿里easyexcel解析百万级大数据量的Excel表格,看这一篇文章就够了
阿里easyexcel解析百万级大数据量的Excel表格,看这一篇文章就够了
阿里easyexcel解析百万级大数据量的Excel表格,看这一篇文章就够了
|
5月前
|
存储 JSON JavaScript
[go]byte类型, string 类型, json 类型
本文介绍了Go语言中byte类型的基本概念、特点及用法。byte是8位无符号整数,取值范围为0-255,常用于二进制数据操作,如网络通信和文件读写。文章还详细说明了byte与字符串的转换、遍历byte数据以及与其他类型间的转换。此外,探讨了Go中json.Marshal和json.Unmarshal函数实现[]byte与JSON间的转换,并对比了[]byte与JSON的区别,帮助开发者更好地理解其应用场景与差异。
193 2
|
数据采集 前端开发 JavaScript
查看Socket断开原因及加入心跳机制防止自动断开连接
一般情况下,前端页面连接WebSocket服务的时候都是通过Nginx等负载均衡,然后由Nginx去代理连接后端的socket服务。如果建立连接之后不做一些措施,那么可能会有各种各样的原因会导致socket断开。
2967 0
|
关系型数据库 MySQL Java
centos7安装mysql教程及Navicat平替软件
【8月更文挑战第17天】本教程详述CentOS 7上安装MySQL的过程。首先确保移除任何预装的MySQL组件,然后通过wget获取并安装MySQL的YUM源。可以选择安装特定版本如5.7或8.0。安装MySQL服务器后,启动服务并查找初始密码。登录MySQL后应立即更改密码,并可根据需要设置远程访问权限。此外,还推荐使用免费开源的DBeaver作为数据库管理工具,提供了安装步骤以方便管理和操作MySQL数据库。
421 3
|
10月前
|
存储 分布式计算 Hadoop
MPP 架构与 Hadoop 架构技术选型指南
MPP架构与Hadoop架构是处理海量数据的两大选择。MPP通过大规模并行处理实现快速查询响应,适用于企业级数据仓库和OLAP应用;Hadoop则以分布式存储和计算为核心,擅长处理非结构化数据和大数据分析。两者各有优劣,MPP适合结构化数据和高性能需求场景,而Hadoop在扩展性和容错性上表现更佳。选择时需综合考虑业务需求、预算和技术能力。
1037 14
|
11月前
|
JSON API 数据处理
如何运用获得京东商品详情API接口搬运商品到自己的电商平台?(一篇文章全搞定)
本文介绍如何利用京东商品详情API接口,将商品信息高效搬运至第三方电商平台。主要内容包括:前期准备(注册账号、申请权限、阅读文档、技术准备),API接口调用(构造请求URL、发送请求、解析返回数据、调用频率限制),数据处理与上架(清洗整理、分类设置、信息上传、商品审核),定时更新与维护(更新商品信息、信息维护、错误处理与日志记录),以及案例分析和优化建议。通过合理使用该接口,可提高运营效率,丰富商品种类,增强平台竞争力。
338 13
|
11月前
|
监控 测试技术
slb测试会话保持功能
slb测试会话保持功能
359 6
|
缓存 网络协议 测试技术
推荐一款简单易用线上引流测试工具:GoReplay
推荐一款简单易用线上引流测试工具:GoReplay
622 0
推荐一款简单易用线上引流测试工具:GoReplay