在Excel中查找合并单元格,拆分单元格并将它们写入新电子表格中?

我已经给了一个Assignment,我需要拆分电子表格的数据,并将其写入新的电子表格。 条件是,鉴于电子表格可能有多个合并单元格的数量,我需要find这些合并的单元格,并在新的电子表格中写入这些数据。 即一个合并单元格之间的数据或单元格直到另一个合并单元格必须写入另一个电子表格。

我的努力守则如下,

import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import org.apache.poi.hssf.usermodel.HSSFCell; import org.apache.poi.hssf.usermodel.HSSFRow; import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFWorkbook; public class CopyTest { public static void main(String[] args) throws IOException { CopyTest excel = new CopyTest(); excel.process("D:\\B3.xls"); } public void process(String fileName) throws IOException { BufferedInputStream bis = new BufferedInputStream(new FileInputStream(fileName)); HSSFWorkbook workbook = new HSSFWorkbook(bis); HSSFWorkbook myWorkBook = new HSSFWorkbook(); HSSFSheet sheet = null; HSSFRow row = null; HSSFCell cell = null; HSSFSheet mySheet = null; HSSFRow myRow = null; HSSFCell myCell = null; int sheets = workbook.getNumberOfSheets(); int fCell = 0; int lCell = 0; int fRow = 0; int lRow = 0; for (int iSheet = 0; iSheet < sheets; iSheet++) { sheet = workbook.getSheetAt(iSheet); if (sheet != null) { mySheet = myWorkBook.createSheet(sheet.getSheetName()); fRow = sheet.getFirstRowNum(); System.out.println("First Row at"+fRow); lRow = sheet.getLastRowNum(); for (int iRow = fRow; iRow <= lRow; iRow++) { row = sheet.getRow(iRow); myRow = mySheet.createRow(iRow); if (row != null) { fCell = row.getFirstCellNum(); lCell = row.getLastCellNum(); for (int iCell = fCell; iCell < lCell; iCell++) { //if (mySheet.getMergedRegionAt(index)!=null) System.out.println("Finding next merged Cells"); cell = row.getCell(iCell); myCell = myRow.createCell(iCell); if (cell != null) { myCell.setCellType(cell.getCellType()); switch (cell.getCellType()) { case HSSFCell.CELL_TYPE_BLANK: myCell.setCellValue(""); break; case HSSFCell.CELL_TYPE_BOOLEAN: myCell.setCellValue(cell.getBooleanCellValue()); break; case HSSFCell.CELL_TYPE_ERROR: myCell.setCellErrorValue(cell.getErrorCellValue()); break; case HSSFCell.CELL_TYPE_FORMULA: myCell.setCellFormula(cell.getCellFormula()); break; case HSSFCell.CELL_TYPE_NUMERIC: myCell.setCellValue(cell.getNumericCellValue()); break; case HSSFCell.CELL_TYPE_STRING: myCell.setCellValue(cell.getStringCellValue()); break; default: myCell.setCellFormula(cell.getCellFormula()); // System.out.println("Reading Cell value\t"+myCell); }System.out.println("Reading Cell value\t"+myCell); } } } } } } bis.close(); BufferedOutputStream bos = new BufferedOutputStream( new FileOutputStream("D:\\Result Excel1.xls", true)); myWorkBook.write(bos); bos.close(); }} 

通过此代码,我已经实现了将电子表格克隆到另一张新的工作表中。 在这里,我无法find合并的单元格,getMergedCellRegionAt()帮助我,并返回像A:4 D:12这样的合并单元格区域。 我如何继续这个。 请帮助我,你的小小的努力是值得赞赏的。 提前致谢。

根据HSSFSheet的Javadocs , getMergedCellRegionAt()在2008年被弃用,因为它返回的Region也被弃用了,有利于CellRangeAddress 。 它build议你应该使用getMergedRegion(int)来代替,它返回一个CellRangeAddress

合并的区域数据不直接与单元格本身一起存储,而是与Sheet对象一起存储。 所以你不需要遍历行和单元格来查找它们是否是合并区域的一部分; 你只需要遍历工作表中合并区域的列表,然后用addMergedRegion(CellRangeAddress)将合并区域添加到新工作表中。

 for (int i = 0; i < sheet.getNumMergedRegions(); i++) { CellRangeAddress mergedRegion = sheet.getMergedRegion(i); // Just add it to the sheet on the new workbook. mySheet.addMergedRegion(mergedRegion); } 

HSSFSheet上的这些方法在Sheet接口中,所以它们可以与Apache POI支持的任何Excel工作簿,.xls(HSSF)或.xlsx(XSSF)一起使用。

合并的单元格在第一个单元格中具有它们的值。

以下方法返回提供合并区域中第一个单元格的行和列的区域的值

 String getMergedRegionStringValue(HSSFSheet sheet, int firstRow, int firstColumn){ for(int i = 0; i < sheet.getNumMergedRegions(); i++) { CellRangeAddress region = sheet.getMergedRegion(i); int colIndex = region.getFirstColumn(); int rowNum = region.getFirstRow(); //check first cell of the region if(rowNum == firstRow && colIndex == firstColumn){ return sheet.getRow(rowNum).getCell(colIndex).getStringCellValue(); } } } 

rgettmans答案是完全正确的。

Java 8

我只想为streamjoinJava 8的解决scheme:

 Sheet oldSheet, newSheet; IntStream.range(0, oldSheet.getNumMergedRegions()) .mapToObj(oldSheet::getMergedRegion) .forEach(newSheet::addMergedRegion);