在合并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;
}
}
亦菲彦祖们点个赞吧!希望对大家有所帮助~