专业做网站开发,最新舆情信息网,桂林欣梦网络,国内主要的o2o电商平台背景
在日常工作中#xff0c;我们经常需要将多个Excel文件合并成一个#xff0c;同时保留原有的样式和格式。Apache POI是一个流行的Java库#xff0c;用于读取和写入Microsoft Office格式的文件#xff0c;包括Excel。然而#xff0c;仅仅使用Apache POI的基本功能进行…背景
在日常工作中我们经常需要将多个Excel文件合并成一个同时保留原有的样式和格式。Apache POI是一个流行的Java库用于读取和写入Microsoft Office格式的文件包括Excel。然而仅仅使用Apache POI的基本功能进行合并操作往往会导致样式的丢失这对于需要保留格式信息的场景来说是不够的。常见的应用场景如钉钉的打卡数据只能一个一个的表格导出接下来的文章就恰好可以运用到这样的场景中。
本文将探讨如何在合并Excel文件时保留原表格的样式并提供一个改进的代码示例以便更好地处理这个问题。
问题描述
在合并多个Excel文件时常见的挑战之一是保留每个文件中的单元格样式。这些样式可能包括字体、颜色、边框、填充等。使用Apache POI的基本方法复制单元格时只会复制内容而不会保留这些样式。
解决方案
要解决这个问题我们需要使用Apache POI的更高级功能来复制单元格样式。这涉及到创建样式映射以便在合并过程中跟踪和复制每个单元格的样式。
以下是实现这一功能的关键步骤 创建样式映射使用一个映射结构如HashMap来存储从原始工作簿的CellStyle到合并工作簿的XSSFCellStyle的映射。这可以确保我们不会为相同的样式重复创建新的XSSFCellStyle对象。 遍历工作簿和工作表对于要合并的每个Excel文件遍历其中的每个工作簿和工作表。 复制行和单元格对于每个工作表中的行和单元格创建新的行和单元格并复制内容。 复制样式在复制单元格时检查样式映射是否已经包含了该单元格的样式。如果没有从原始工作簿中克隆样式并将其添加到映射中。然后将新克隆的样式应用到新创建的单元格上。 写入合并后的工作簿最后将合并后的工作簿写入输出文件。 代码示例
下面是一个示例代码展示了如何实现上述解决方案
dependency groupIdorg.apache.poi/groupId artifactIdpoi/artifactId version5.2.0/version
/dependency
dependency groupIdorg.apache.poi/groupId artifactIdpoi-ooxml/artifactId version5.2.0/version
/dependency案例一多个excel合成一个表格
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;import java.io.*;
import java.util.ArrayList;
import java.util.List;public class ExcelMerger {public static void main(String[] args) {ListString fileNames new ArrayList();fileNames.add(H:\\time\\_打卡时间表1.xlsx);fileNames.add(H:\\time\\_打卡时间表2.xlsx);fileNames.add(H:\\time\\_打卡时间表3.xlsx);// 添加更多文件路径...String outputFileName H:\\time\\merged_excel_file.xlsx;try{InputStream inputStream;Workbook workbook;OutputStream outputStream new FileOutputStream(outputFileName);XSSFWorkbook mergedWorkbook new XSSFWorkbook();int j 0;for (String fileName : fileNames) {inputStream new FileInputStream(fileName);workbook WorkbookFactory.create(inputStream);j ;for (int i 0; i workbook.getNumberOfSheets(); i) {Sheet sheet workbook.getSheetAt(i);try {mergedWorkbook.createSheet(sheet.getSheetName() i j);}catch (Exception e){System.out.println(1);}copySheet(mergedWorkbook.getSheet(sheet.getSheetName() i j), sheet);}}mergedWorkbook.write(outputStream);} catch (IOException e) {e.printStackTrace();}}private static void copySheet(Sheet newSheet, Sheet sheet) {int rowCount sheet.getLastRowNum() - sheet.getFirstRowNum();for (int i 0; i rowCount; i) {Row newRow newSheet.createRow(i);Row currentRow sheet.getRow(i);copyRow(newRow, currentRow);}}private static void copyRow(Row newRow, Row currentRow) {if (currentRow null) {return;}int cellCount currentRow.getLastCellNum();for (int i 0; i cellCount; i) {Cell currentCell currentRow.getCell(i);if (currentCell null) {continue;}Cell newCell newRow.createCell(i);copyCell(newCell, currentCell);}}private static void copyCell(Cell newCell, Cell currentCell) {newCell.setCellType(currentCell.getCellType());switch (currentCell.getCellType()) {case STRING:newCell.setCellValue(currentCell.getStringCellValue());break;case BOOLEAN:newCell.setCellValue(currentCell.getBooleanCellValue());break;case NUMERIC:newCell.setCellValue(currentCell.getNumericCellValue());break;case FORMULA:newCell.setCellFormula(currentCell.getCellFormula());break;default:break;}}
}案例二多个表格合成一个sheet
//初始化一个XSSFWorkbook实例作为合并后的工作簿并创建一个名为Merged Sheet的新sheet。
//遍历每个要合并的Excel文件并对每个文件中的每个sheet进行迭代。
//对于每个sheet中的每一行都创建一个新的行并复制到合并后的sheet中。
//在复制行时同时复制每个单元格的内容包括字符串、布尔值、数字和公式。
//最后将合并后的工作簿写入输出文件。
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook; import java.io.*;
import java.util.ArrayList;
import java.util.List; public class ExcelMerger {public static void main(String[] args) { ListString fileNames new ArrayList();fileNames.add(H:\\time\\_打卡时间表1.xlsx);fileNames.add(H:\\time\\_打卡时间表2.xlsx);fileNames.add(H:\\time\\_打卡时间表3.xlsx);// 添加更多文件路径...String outputFileName H:\\time\\merged_excel_file.xlsx;try {InputStream inputStream; Workbook workbook;FileOutputStream outputStream new FileOutputStream(outputFileName);XSSFWorkbook mergedWorkbook new XSSFWorkbook(); Sheet mergedSheet mergedWorkbook.createSheet(Merged Sheet); int rowNum 0; // 用于新sheet中的行号 for (String fileName : fileNames) { inputStream new FileInputStream(fileName); workbook WorkbookFactory.create(inputStream); for (int i 0; i workbook.getNumberOfSheets(); i) { Sheet sheet workbook.getSheetAt(i); for (Row row : sheet) { Row newRow mergedSheet.createRow(rowNum); copyRow(newRow, row); } } } mergedWorkbook.write(outputStream); } catch (IOException e) { e.printStackTrace(); } } private static void copyRow(Row newRow, Row currentRow) { if (currentRow null) { return; } for (Cell cell : currentRow) { Cell newCell newRow.createCell(cell.getColumnIndex(), cell.getCellType()); switch (cell.getCellType()) { case STRING: newCell.setCellValue(cell.getStringCellValue()); break; case BOOLEAN: newCell.setCellValue(cell.getBooleanCellValue()); break; case NUMERIC: newCell.setCellValue(cell.getNumericCellValue()); break; case FORMULA: newCell.setCellFormula(cell.getCellFormula()); break; case BLANK: // Handle blank cells as needed break; default: break; } } }
}案例三多个表格合成一个sheet并保留样式
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFWorkbook; import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;public class ExcelMergerWithStyles { public static void main(String[] args) { ListString fileNames new ArrayList();fileNames.add(H:\\time\\_打卡时间表1.xlsx);fileNames.add(H:\\time\\_打卡时间表2.xlsx);fileNames.add(H:\\time\\_打卡时间表3.xlsx);// 添加更多文件路径...String outputFileName H:\\time\\merged_excel_file.xlsx;try {InputStream inputStream;Workbook workbook;FileOutputStream outputStream new FileOutputStream(outputFileName);XSSFWorkbook mergedWorkbook new XSSFWorkbook(); Sheet mergedSheet mergedWorkbook.createSheet(Merged Sheet); int rowNum 0; // 用于新sheet中的行号 // 用于存储已创建样式的映射以避免重复创建相同的样式 MapCellStyle, XSSFCellStyle styleMap new HashMap();for (String fileName : fileNames) { inputStream new FileInputStream(fileName); workbook WorkbookFactory.create(inputStream); for (int i 0; i workbook.getNumberOfSheets(); i) { Sheet sheet workbook.getSheetAt(i); for (Row row : sheet) { Row newRow mergedSheet.createRow(rowNum); copyRowWithStyles(newRow, row, mergedWorkbook, styleMap); } } } mergedWorkbook.write(outputStream); } catch (IOException e) { e.printStackTrace(); } } private static void copyRowWithStyles(Row newRow, Row currentRow, XSSFWorkbook mergedWorkbook, MapCellStyle, XSSFCellStyle styleMap) { if (currentRow null) { return; } for (Cell cell : currentRow) { Cell newCell newRow.createCell(cell.getColumnIndex(), cell.getCellType()); copyCellContent(cell, newCell); // 复制样式 CellStyle cellStyle cell.getCellStyle(); XSSFCellStyle newCellStyle styleMap.get(cellStyle); if (newCellStyle null) { newCellStyle mergedWorkbook.createCellStyle(); newCellStyle.cloneStyleFrom(cellStyle); styleMap.put(cellStyle, newCellStyle); } newCell.setCellStyle(newCellStyle); } } private static void copyCellContent(Cell source, Cell target) { switch (source.getCellType()) { case STRING: target.setCellValue(source.getStringCellValue()); break; case BOOLEAN: target.setCellValue(source.getBooleanCellValue()); break; case NUMERIC: target.setCellValue(source.getNumericCellValue()); break; case FORMULA: target.setCellFormula(source.getCellFormula()); break; case BLANK: // Handle blank cells as needed break; default: break; } }
}总结
通过扩展Apache POI库的基本功能我们可以实现在合并Excel文件时保留原表格样式的能力。这涉及到创建样式映射遍历工作簿和工作表复制行、单元格和样式并最终写入合并后的工作簿。虽然这个过程可能比简单的合并更为复杂但它提供了更大的灵活性允许我们根据需要定制合并后的Excel文件的样式和格式。
对于需要处理大量Excel文件或具有复杂样式的场景这种方法可能需要进行进一步的优化和错误处理。但无论如何它提供了一个很好的起点用于在Java中实现具有样式保留功能的Excel合并操作。