JAVA实现多个excel合并为一个excel表格,解决科学计数法问题

在合并excel表格到新的excel表格时遇到某些列的数据都变成了科学计数法,这里使用正则表达式来解决该问题,废话不多说,直接上代码

public class ExcelMerger {

    private static final Logger logger = LoggerFactory.getLogger(ExcelMerger.class);

    public static void main(String[] args) {
        // 主文件夹路径
        String folderPath = "D:/xxx/xxx/xxx/xxx";

        try {
            //循环合并大文件夹下的子文件夹
            mergeFolderFile(folderPath);
        } catch (IOException e) {
            logger.error("合并文件时出错:" + e.getMessage());
            e.printStackTrace();
        }
    }

    private static void mergeFolderFile(String folderPath) throws IOException {
        File folderFile = new File(folderPath);
        //获取该父文件夹下的所有子文件夹(只处理文件夹)
        File[] listFiles = folderFile.listFiles(File::isDirectory);
        if (listFiles != null) {
            for (File listFile : listFiles) {
                mergeExcelFiles(listFile);
            }
        }
    }

    // 合并文件夹下的所有Excel文件,排除指定的文件
    public static void mergeExcelFiles(File folder) throws IOException {
        // 创建一个新的工作簿用于保存合并后的数据
        Workbook mergedWorkbook = new XSSFWorkbook();
        Sheet mergedSheet = mergedWorkbook.createSheet("合并结果");
        int rowIndex = 0;

        // 记录每个文件的表头,只取第一个Excel文件的表头
        boolean isFirstFile = true;

        // 遍历文件夹中的所有Excel文件
        for (File file : folder.listFiles()) {
            // 排除文件名为 "xxx.xlsx" 的文件
            if (file.isFile() && (file.getName().endsWith(".xlsx") || file.getName().endsWith(".xls")) && !file.getName().equals("xxx.xlsx")) {
                FileInputStream fis = new FileInputStream(file);
                // 使用XSSFWorkbook处理.xlsx格式文件
                Workbook workbook = new XSSFWorkbook(fis);
                // 假设每个Excel文件只有一个sheet,读取第一个sheet
                Sheet sheet = workbook.getSheetAt(0);

                // 获取文件名
                String fileName = file.getName().replace(".xlsx", "");

                // 如果是第一个文件,设置表头,只插入一次"xxx"列
                if (isFirstFile) {
                    Row headerRow = mergedSheet.createRow(rowIndex++);
                    // 设置"xxx"为第一列
                    headerRow.createCell(0).setCellValue("xxx");
                    // 复制第一个文件的表头到合并后的表头
                    Row firstFileHeaderRow = sheet.getRow(0);
                    if (firstFileHeaderRow != null) {
                        for (int j = 0; j < firstFileHeaderRow.getPhysicalNumberOfCells(); j++) {
                            // 将表头从第2列开始
                            Cell cell = headerRow.createCell(j + 1);  
                            cell.setCellValue(getCellValue(firstFileHeaderRow.getCell(j)));
                        }
                    }
                    // 设置标志,之后不再添加表头
                    isFirstFile = false;
                }

                // 读取Excel文件的每一行,并插入到合并结果中
                for (int i = 1; i <= sheet.getLastRowNum(); i++) {
                    // 从第二行开始(跳过表头)
                    Row row = sheet.getRow(i);
                    if (row == null) continue;

                    // 创建新行,将“xxx”插入到第一列
                    Row newRow = mergedSheet.createRow(rowIndex++);
                    // 设置“xxx”列为文件名
                    newRow.createCell(0).setCellValue(fileName);

                    // 将其他数据从第二列开始插入
                    for (int j = 0; j < row.getPhysicalNumberOfCells(); j++) {
                        // 获取单元格的值
                        String cellValue = getCellValue(row.getCell(j));
                        //处理科学计数法
                        String realCellValue = translateToPlainStr(cellValue);
                        // 将处理后的值放入新单元格
                        // 从第二列开始
                        Cell cell = newRow.createCell(j + 1);
                        cell.setCellValue(realCellValue);
                    }
                }

                workbook.close();
                fis.close();
            }
        }

        // 保存合并后的工作簿
        FileOutputStream fos = new FileOutputStream(folder.getPath() + "/合并结果.xlsx");
        mergedWorkbook.write(fos);
        fos.close();
        logger.info("所有文件已合并,保存为 '合并结果.xlsx'");
    }

    // 根据单元格类型读取值
    public static String getCellValue(Cell cell) {
        String cellValue = "";
        if (cell == null) {
            return cellValue;
        }

        // 根据单元格类型获取值
        switch (cell.getCellType()) {
            case STRING:
                cellValue = cell.getStringCellValue();
                break;
            case NUMERIC:
                if (DateUtil.isCellDateFormatted(cell)) {
                    // 如果是日期类型,转换为字符串
                    cellValue = cell.getDateCellValue().toString();
                } else {
                    // 如果是普通数值,转换为字符串
                    cellValue = String.valueOf(cell.getNumericCellValue());
                }
                break;
            case BOOLEAN:
                cellValue = String.valueOf(cell.getBooleanCellValue());
                break;
            case FORMULA:
                // 如果是公式,获取公式的结果
                cellValue = cell.getCellFormula();
                break;
            default:
                cellValue = "";
        }

        return cellValue;
    }

    //处理科学计数法
    public static String translateToPlainStr(String cellValue) {
        if (cellValue == null || cellValue.isEmpty()) {
            return "";
        }
        String regEx = "^([+-]?\\d+(?:\\.\\d+)?)[eE]([+-]?\\d+)$";
        Pattern pattern = Pattern.compile(regEx);
        Matcher matcher = pattern.matcher(cellValue);
        if (matcher.matches()) {
            BigDecimal realCellValue = new BigDecimal(cellValue);
            return realCellValue.stripTrailingZeros().toPlainString();
        }
        //去掉纯数字末尾多余的0
        if (cellValue.matches("[0-9]+(\\.\\d+)?")) {
            BigDecimal reCellValue = new BigDecimal(cellValue);
            cellValue = reCellValue.stripTrailingZeros().toPlainString();
        }
        return cellValue;
    }
}

亦菲彦祖们点个赞吧!希望对大家有所帮助~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值