From f06e90fedf5e808b65c2a4ced7b4692adcba51b6 Mon Sep 17 00:00:00 2001 From: Kai Reinhard Date: Thu, 6 Feb 2020 18:27:14 +0100 Subject: [PATCH] Bugfix in copyAndInsert. copyCellsFrom(srcRow) supports now merged regions (inside the current row). --- examples/Excel/Workbook-Test.xlsx | Bin 15038 -> 15113 bytes .../de/micromata/merlin/excel/ExcelRow.kt | 12 +++++++++++- .../merlin/excel/ExcelRowActionsTest.kt | 5 +++++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/examples/Excel/Workbook-Test.xlsx b/examples/Excel/Workbook-Test.xlsx index f6a5b6bcf557217d024b601951a9ad950475f1bc..eca655e5989ffe108367bd903fcb5d78a7dc5e9d 100644 GIT binary patch delta 5127 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 + srcRow.sheet.poiSheet.mergedRegions?.forEach { address -> + // Only merge region in this single row are supported. + if (address.firstRow == srcRow.rowNum && address.lastRow == srcRow.rowNum) { + numMergedRegions.add(address) + } + } for (colNum in 0..srcRow.lastCellNum) { val srcCell = srcRow.row.getCell(colNum) if (srcCell != null) { val destCell = row.getCell(colNum) ?: row.createCell(colNum) ExcelCell.copyCell(srcCell, destCell) + numMergedRegions.filter { it.firstColumn == srcCell.columnIndex }.forEach { + sheet.addMergeRegion(CellRangeAddress(this.rowNum, this.rowNum, it.firstColumn, it.lastColumn)) + } } } } diff --git a/merlin-core/src/test/kotlin/de/micromata/merlin/excel/ExcelRowActionsTest.kt b/merlin-core/src/test/kotlin/de/micromata/merlin/excel/ExcelRowActionsTest.kt index e9dd3385..795a7caa 100644 --- a/merlin-core/src/test/kotlin/de/micromata/merlin/excel/ExcelRowActionsTest.kt +++ b/merlin-core/src/test/kotlin/de/micromata/merlin/excel/ExcelRowActionsTest.kt @@ -19,6 +19,8 @@ internal class ExcelRowActionsTest { sheet1.getRow(3)!!.copyAndInsert(actionsSheet, 1) Assertions.assertEquals("k.reinhard@acme.com", actionsSheet.getRow(0)!!.getCell(1)!!.stringCellValue) Assertions.assertEquals("b.muster@acme.com", actionsSheet.getRow(1)!!.getCell(1)!!.stringCellValue) + val copiedRow = actionsSheet.getRow(1)!! + Assertions.assertTrue(actionsSheet.poiSheet.mergedRegions?.any { it.firstRow == copiedRow.rowNum && it.lastRow == copiedRow.rowNum && it.firstColumn == 5 && it.lastColumn == 7 } == true) Assertions.assertEquals(0.0, actionsSheet.getRow(2)!!.getCell(0)!!.numericCellValue) Assertions.assertEquals(1.0, actionsSheet.getRow(3)!!.getCell(0)!!.numericCellValue) @@ -34,6 +36,9 @@ internal class ExcelRowActionsTest { Assertions.assertEquals(1.0, actionsSheet.getRow(5)!!.getCell(0)!!.numericCellValue) Assertions.assertEquals(1.5, actionsSheet.getRow(6)!!.getCell(0)!!.numericCellValue) Assertions.assertEquals(2.0, actionsSheet.getRow(7)!!.getCell(0)!!.numericCellValue) + Assertions.assertTrue(actionsSheet.poiSheet.mergedRegions?.any { it.firstRow == newRow.rowNum && it.lastRow == newRow.rowNum && it.firstColumn == 7 && it.lastColumn == 8 } == true) + + sheet1.getRow(3)!!.copyAndInsert(actionsSheet, 14) val file = File(Definitions.OUTPUT_DIR, "RowActionsTest.xlsx") log.info("Writing checksum Excel file: " + file.getAbsolutePath())