Java后端实现并合并多个excel页签

Java后端实现合并多个excel页签

多个标签页合并

utils层
public static XSSFWorkbook mergeMultiExcel2MultiSheet(String sourceFilePath, String outputPath, String outputFileName) throws Exception {
    long beginTime = System.currentTimeMillis();
    // 将所有类型的尽调excel文件合并成一个excel文件
    // 源文件
    File file = new File(sourceFilePath);
    File[] tempList = file.listFiles();
    //根据文件名排序
    Arrays.sort(tempList, (f1, f2) -> f1.getName().compareTo(f2.getName()));
    String fileNameList[] = new String[tempList.length];
    LOGGER.info("该目录下对象个数:{}", tempList.length);
    for (int i = 0; i < tempList.length; i++) {
        if (tempList[i].isFile()) {
            fileNameList[i] = tempList[i].toString();
        }
    }
    XSSFWorkbook newExcelCreat = new XSSFWorkbook();
    // 遍历每个excel源文件,fileNameList为源文件的名称集合
    for (String fromExcelName : fileNameList) {
        InputStream in = new FileInputStream(fromExcelName);
        XSSFWorkbook fromExcel = new XSSFWorkbook(in);
        int length = fromExcel.getNumberOfSheets();
        //长度为1时
        if (length <= 1) {
            XSSFSheet oldSheet = fromExcel.getSheetAt(0);
            XSSFSheet newSheet = newExcelCreat.createSheet(oldSheet.getSheetName());
            copySheet(newExcelCreat, oldSheet, newSheet);
        } else {
            // 遍历每个sheet
            for (int i = 0; i < length; i++) {
                XSSFSheet oldSheet = fromExcel.getSheetAt(i);
                XSSFSheet newSheet = newExcelCreat.createSheet(oldSheet.getSheetName());
                copySheet(newExcelCreat, oldSheet, newSheet);
            }
        }
        in.close();
    }
    //定义新生成的xlx表格文件
    //生成目录
    String filePath = outputPath + System.getProperty("file.separator") + outputFileName;
    FileOutputStream fileOut = new FileOutputStream(filePath);
    newExcelCreat.write(fileOut);
    fileOut.flush();
    fileOut.close();


    // 删除各个源文件
    // 遍历每个源excel文件
    for (String fromExcelName : fileNameList) {
        File Existfile = new File(fromExcelName);
        if (Existfile.exists()) {
           Existfile.delete();
        }
    }
    long endTime = System.currentTimeMillis();
    LOGGER.info("合并文件执行时长:{} 毫秒.", (endTime - beginTime));
    return newExcelCreat;
}

该Java函数的主要功能是合并指定目录下的多个Excel文件,将其中的所有工作表(Sheet)整合到一个新的Excel文件中,并且在完成后可以选择性地删除原文件。以下是详细步骤:

  • 获取源文件列表:根据sourceFilePath参数定位到的目录路径,使用File.listFiles()方法获取所有子文件,并将其存储在一个File数组tempList中。
  • 排序文件名:对tempList中的文件按照文件名进行升序排序,确保合并顺序一致。
  • 提取文件名集合:遍历文件列表,只保留文件对象并将其对应的文件路径存入到字符串数组fileNameList中。
  • 创建新Excel工作簿:通过new XSSFWorkbook()创建一个空的工作簿对象newExcelCreat,用于存放合并后的内容。
  • 遍历并合并每个源Excel文件:
    • 对于fileNameList中的每个Excel文件,打开输入流读取内容并创建对应的工作簿对象fromExcel。
    • 获取fromExcel中的工作表数量,如果只有一个工作表,则直接复制该工作表到新工作簿中;如果有多个工作表,则逐个复制每个工作表。
    • 使用copySheet方法将每个旧工作表的内容复制到新工作簿的新工作表中,保持原工作表名称不变。
  • 保存合并后的Excel文件:
    • 根据outputPath和outputFileName参数构建输出文件的完整路径filePath。
    • 创建FileOutputStream对象指向目标文件路径,并调用newExcelCreat.write(fileOut)将合并后的工作簿写入到新的Excel文件中。
    • 关闭输出流,确保数据已完全写入磁盘。
  • 删除源Excel文件:再次遍历fileNameList,对于每一个源Excel文件,检查其是否存在,若存在则删除。
  • 记录执行时间和返回合并后的工作簿:计算函数执行时间并记录日志,最后返回合并后的新Excel工作簿对象newExcelCreat。

其中copySheet方法具体如下:

public static void copySheet(XSSFWorkbook wb, XSSFSheet fromSheet, XSSFSheet toSheet) {
    mergeSheetAllRegion(fromSheet, toSheet);
    // 设置列宽
    int length = fromSheet.getRow(fromSheet.getFirstRowNum()).getLastCellNum();
    for (int i = 0; i <= length; i++) {
        toSheet.setColumnWidth(i, fromSheet.getColumnWidth(i));
    }
    for (Iterator rowIt = fromSheet.rowIterator(); rowIt.hasNext(); ) {
        XSSFRow oldRow = (XSSFRow) rowIt.next();
        XSSFRow newRow = toSheet.createRow(oldRow.getRowNum());
        copyRow(wb, oldRow, newRow);
    }
}

主要功能是实现从一个Excel工作表(XSSFSheet类型,名为fromSheet)到另一个同类型工作表(名为toSheet)的完整内容复制,包括单元格数据、样式以及列宽等信息。下面是详细步骤:

  • 合并区域:首先调用自定义方法mergeSheetAllRegion(fromSheet, toSheet),是将fromSheet中的所有合并单元格区域复制并应用到toSheet。
  • 设置列宽:
    • 获取fromSheet的第一行的所有单元格数量,以此得到工作表的列数。
    • 遍历0到列数(包含列数),使用getColumnWidth(i)获取fromSheet的第i列的宽度,并通过setColumnWidth(i, width)方法将相同宽度设置给toSheet的对应列,确保列宽保持一致。
  • 复制行内容:
    • 使用迭代器遍历fromSheet的所有行。
    • 对于每行,将其转换为XSSFRow对象(即oldRow),并根据其在原表中的行号,在toSheet中创建一个新的对应行(即newRow)。
    • 调用copyRow(wb, oldRow, newRow)方法来逐个复制和粘贴行内单元格的内容及样式。这里需要传入整个Excel工作簿(XSSFWorkbook类型,名为wb)作为参数,因为可能涉及到引用其他表格或样式时需要用到工作簿上下文。

这个函数实现了两个Excel工作表之间的深度复制,不仅复制了单元格的值,还复制了列宽以及可能涉及的行内样式和其他相关信息。

其中mergeSheetAllRegion方法具体如下:

public static void mergeSheetAllRegion(XSSFSheet fromSheet, XSSFSheet toSheet) {
    int num = fromSheet.getNumMergedRegions();
    CellRangeAddress cellR = null;
    for (int i = 0; i < num; i++) {
        cellR = fromSheet.getMergedRegion(i);
        toSheet.addMergedRegion(cellR);
    }
}

该方法其主要功能是从一个Apache POI库处理的Excel工作表(XSSFSheet)中复制所有合并区域的信息,并将其添加到另一个XSSFSheet中。具体实现步骤如下:
首先,通过调用fromSheet.getNumMergedRegions()方法获取源工作表(fromSheet)中的合并单元格区域总数。
使用一个for循环遍历所有的合并区域。循环变量i从0开始,小于num(即合并区域的数量)为止。
在每次循环迭代中,通过调用fromSheet.getMergedRegion(i)方法获取指定索引i处的合并单元格区域信息,并将其存储在CellRangeAddress类型的变量cellR中。CellRangeAddress对象包含了合并区域的起始行、结束行、起始列和结束列等信息。
最后,在目标工作表(toSheet)中使用toSheet.addMergedRegion(cellR)方法将从源工作表获取的合并单元格区域信息添加进去,实现了合并区域信息的复制。
总之,此函数用于在两个Excel工作表之间复制合并单元格设置,保持目标工作表的合并单元格布局与源工作表一致。

copyRow方法具体如下:

public static void copyRow(XSSFWorkbook wb, XSSFRow oldRow, XSSFRow toRow) {
    toRow.setHeight(oldRow.getHeight());
    for (Iterator cellIt = oldRow.cellIterator(); cellIt.hasNext(); ) {
        XSSFCell tmpCell = (XSSFCell) cellIt.next();
        XSSFCell newCell = toRow.createCell(tmpCell.getColumnIndex());
        copyCell(wb, tmpCell, newCell);
    }
}

该方法用于将一个Apache POI库中定义的XSSF类型的Excel行(oldRow)的内容完整复制到另一个同样为XSSF类型的Excel行(toRow)中。具体实现过程如下:

  • 设置目标行的高度:首先,函数通过调用toRow.setHeight(oldRow.getHeight())来设置目标行(toRow)的高度与源行(oldRow)相同,确保在样式和布局上保持一致。
  • 遍历源行单元格:接着,使用迭代器遍历源行的所有单元格。这里调用oldRow.cellIterator()获取一个迭代器,并在循环中逐个取出每个单元格(类型为XSSFCell)。
  • 创建并初始化新单元格:对于源行中的每一个单元格(tmpCell),在目标行中创建一个新的单元格(newCell),通过调用toRow.createCell(tmpCell.getColumnIndex())实现,其中tmpCell.getColumnIndex()用于获取当前单元格在原行中的列索引,确保新单元格在目标行中的位置与原单元格对应。
  • 复制单元格内容及样式:然后,调用名为copyCell(wb, tmpCell, newCell)的辅助函数,这个函数未在此代码段中显示具体内容,但根据函数名推测其功能是将tmpCell的内容(包括但不限于数值、字符串、公式等)以及样式信息(如字体、颜色、填充、边框等)复制到新创建的newCell中。
  • 重复上述过程直至完成所有单元格的复制:循环继续执行,直到遍历完源行的所有单元格,从而完成整个行数据的复制操作。

总之,此函数的主要目的是在两个Excel行之间进行深度复制,不仅复制单元格的内容,还包括单元格的高度以及可能存在的样式信息。

copyCell方法具体如下:

public static void copyCell(XSSFWorkbook wb, XSSFCell fromCell, XSSFCell toCell) {
  XSSFCellStyle newstyle = wb.createCellStyle();
   copyCellStyle(fromCell.getCellStyle(), newstyle);
   // 样式
   toCell.setCellStyle(newstyle);
   if (fromCell.getCellComment() != null) {
       toCell.setCellComment(fromCell.getCellComment());
   }
   // 不同数据类型处理
   CellType fromCellType = fromCell.getCellTypeEnum();
   if (fromCellType == CellType.NUMERIC) {
       if (DateUtil.isCellDateFormatted(fromCell)) {
           toCell.setCellValue(fromCell.getDateCellValue());
       } else {
           toCell.setCellValue(fromCell.getNumericCellValue());
       }
	   } else if (fromCellType == CellType.STRING) {
	       toCell.setCellValue(fromCell.getRichStringCellValue());
	   } else if (fromCellType == CellType.BLANK) {
	       // nothing21
	   } else if (fromCellType == CellType.BOOLEAN) {
	       toCell.setCellValue(fromCell.getBooleanCellValue());
	   } else if (fromCellType == CellType.ERROR) {
	       toCell.setCellErrorValue(fromCell.getErrorCellValue());
	   } else if (fromCellType == CellType.FORMULA) {
	       toCell.setCellFormula(fromCell.getCellFormula());
	   } else { // nothing29
   }

}

该函数 copyCell 是一个Java方法,用于将一个基于Apache POI库的XSSF类型(表示.xlsx格式的Excel工作簿)的单元格(fromCell)的内容和样式完全复制到另一个同样类型的单元格(toCell)中。具体实现步骤如下:
创建新样式:首先,使用传入的工作簿(wb)创建一个新的XSSFCellStyle对象(newstyle),这个新样式将会被用来复制源单元格(fromCell)的样式。
复制样式:调用 copyCellStyle 方法(未在给出的代码片段中详细定义),将fromCell的样式复制到新创建的newstyle中。这一步确保目标单元格(toCell)将具有与源单元格相同的字体、填充、边框、对齐方式等样式信息。
设置目标单元格样式:将newstyle应用到目标单元格(toCell)上,通过调用 setCellStyle 方法完成。
复制注释:如果源单元格(fromCell)包含注释(cellComment),则将其复制到目标单元格(toCell),通过调用 setCellComment 方法实现。
处理不同数据类型:
对于数值型单元格,首先判断是否为日期格式(通过DateUtil.isCellDateFormatted方法)。若是日期,则调用 getDateCellValue 获取并设置日期值;若不是,则调用 getNumericCellValue 获取并设置数值值。
字符串型单元格,调用 getRichStringCellValue 获取并设置字符串值。
空白型单元格不做任何操作。
布尔型单元格,调用 getBooleanCellValue 获取并设置布尔值。
错误型单元格,调用 getErrorCellValue 获取并设置错误值。
公式型单元格,调用 getCellFormula 获取并设置公式。
对于除上述已处理的所有其他未知或未列举的CellType类型,此函数不执行任何操作。
总之,这个函数主要用于精确地克隆Excel单元格的所有内容和属性,包括但不限于样式、注释以及各种类型的数据。

copyCellStyle方法具体如下:

 public static void copyCellStyle(XSSFCellStyle fromStyle, XSSFCellStyle toStyle) {
    toStyle.cloneStyleFrom(fromStyle);
}

该函数public static void copyCellStyle(XSSFCellStyle fromStyle, XSSFCellStyle toStyle)的功能是实现Excel样式单元格的样式复制。在Apache POI库中,XSSFCellStyle对象用于表示xlsx格式Excel文件中的单元格样式,包括但不限于字体、填充颜色、边框样式和颜色、对齐方式、数字格式等属性。
函数接受两个参数:
XSSFCellStyle fromStyle:源样式对象,包含了需要被复制的所有样式信息。
XSSFCellStyle toStyle:目标样式对象,将接收并应用从fromStyle复制过来的所有样式属性。

controller层调用
String outFileName = dwxh+"-"+nf+"年"+yf+"月.xlsx";
ExcelUtil.mergeMultiExcel2MultiSheet(ybOutPath,ybSynthesisPath,outFileName);
  • 11
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值