From 2ef6920d38ab77b998ab76ae06ba4a1f6159d6f4 Mon Sep 17 00:00:00 2001 From: TruongQuangSB <131350493+TruongQuangSB@users.noreply.github.com> Date: Fri, 4 Sep 2026 18:11:46 +0200 Subject: [PATCH 1/5] inital --- .../export/pdf/FopPdfExportBuilder.java | 27 -- .../export/xlsx/ExcelExportBuilder.java | 262 ++++++++++++++---- .../META-INF/MANIFEST.MF | 1 - .../org.eclipse.set.releng.target.target | 8 +- 4 files changed, 219 insertions(+), 79 deletions(-) diff --git a/java/bundles/org.eclipse.set.feature.export/src/org/eclipse/set/feature/export/pdf/FopPdfExportBuilder.java b/java/bundles/org.eclipse.set.feature.export/src/org/eclipse/set/feature/export/pdf/FopPdfExportBuilder.java index 054f5142e7..0b226a2c6e 100644 --- a/java/bundles/org.eclipse.set.feature.export/src/org/eclipse/set/feature/export/pdf/FopPdfExportBuilder.java +++ b/java/bundles/org.eclipse.set.feature.export/src/org/eclipse/set/feature/export/pdf/FopPdfExportBuilder.java @@ -144,33 +144,6 @@ protected static String getFilename(final String shortcut, return shortcut + "-fop." + extension; //$NON-NLS-1$ } - protected static Table getTableToBeExported( - final Map tables, final ExportType exportType) { - switch (exportType) { - case INVENTORY_RECORDS: - final Table invTable = tables.get(TableType.FINAL); - if (invTable != null) { - return invTable; - } - // if we do not have a final table we export the table of the - // single - // container of a state - return tables.get(TableType.SINGLE); - case PLANNING_RECORDS: { - final Table planTable = tables.get(TableType.DIFF); - if (planTable != null) { - return planTable; - } - // if we do not have a diff table we export the table of the - // single - // container of a state - return tables.get(TableType.SINGLE); - } - default: - throw new IllegalArgumentException(exportType.toString()); - } - } - protected EnumTranslationService enumTranslationService; protected FopService fopService; diff --git a/java/bundles/org.eclipse.set.feature.export/src/org/eclipse/set/feature/export/xlsx/ExcelExportBuilder.java b/java/bundles/org.eclipse.set.feature.export/src/org/eclipse/set/feature/export/xlsx/ExcelExportBuilder.java index 9368ad06e9..5fbbfc4fff 100644 --- a/java/bundles/org.eclipse.set.feature.export/src/org/eclipse/set/feature/export/xlsx/ExcelExportBuilder.java +++ b/java/bundles/org.eclipse.set.feature.export/src/org/eclipse/set/feature/export/xlsx/ExcelExportBuilder.java @@ -22,15 +22,19 @@ import java.util.Map; import java.util.Optional; import java.util.stream.Collectors; +import java.util.stream.Stream; import org.apache.commons.io.FileUtils; import org.apache.poi.ss.usermodel.BorderStyle; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellStyle; +import org.apache.poi.ss.usermodel.Font; +import org.apache.poi.ss.usermodel.IndexedColors; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.util.CellRangeAddress; +import org.apache.poi.xssf.usermodel.XSSFRichTextString; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.eclipse.core.runtime.Assert; import org.eclipse.set.basis.FreeFieldInfo; @@ -41,13 +45,18 @@ import org.eclipse.set.basis.constants.TableType; import org.eclipse.set.basis.exceptions.FileExportException; import org.eclipse.set.feature.export.pdf.TableToTableDocument; +import org.eclipse.set.model.tablemodel.CellContent; import org.eclipse.set.model.tablemodel.CompareFootnoteContainer; +import org.eclipse.set.model.tablemodel.CompareStateCellContent; import org.eclipse.set.model.tablemodel.CompareTableCellContent; import org.eclipse.set.model.tablemodel.CompareTableFootnoteContainer; import org.eclipse.set.model.tablemodel.Footnote; import org.eclipse.set.model.tablemodel.FootnoteContainer; +import org.eclipse.set.model.tablemodel.PlanCompareRow; import org.eclipse.set.model.tablemodel.SimpleFootnoteContainer; +import org.eclipse.set.model.tablemodel.StringCellContent; import org.eclipse.set.model.tablemodel.Table; +import org.eclipse.set.model.tablemodel.TableCell; import org.eclipse.set.model.tablemodel.TableRow; import org.eclipse.set.model.tablemodel.extensions.CellContentExtensions; import org.eclipse.set.model.tablemodel.extensions.TableCellExtensions; @@ -79,21 +88,19 @@ public class ExcelExportBuilder implements TableExport { private static final String TEMPLATE_DIR = "./data/export/excel"; //$NON-NLS-1$ private static final String FOOTNOTE_SHEET_NAME = "Bemerkungen"; //$NON-NLS-1$ + private static Font cellNewValueFont; + private static Font cellOldValueFont; + private static CellStyle compareTableRowStyle; + private static CellStyle compareTableCellStyle; + + private static CellStyle compareTableRowStyleFirstCell; + + private static CellStyle compareTableRowStyleLastCell; + private static int getFirstRowForContent(final Sheet sheet) { return getHeaderLastRowIndex(sheet) + 1; } - private static Table getTableToBeExported( - final Map tables) { - final Table invTable = tables.get(TableType.FINAL); - if (invTable != null) { - return invTable; - } - // if we do not have a final table we export the table of the single - // container of a state - return tables.get(TableType.SINGLE); - } - static String[] getColumnHeaders(final Sheet sheet) { final Row row = sheet.getRow(0); final int maxColIx = getHeaderLastColumnIndex(sheet); @@ -138,7 +145,7 @@ public void export(final Map tables, final TableType tableType, final Path outputPath, final OverwriteHandling overwriteHandling) throws FileExportException { - final Table table = getTableToBeExported(tables); + final Table table = tables.get(tableType); final boolean isInlineFootnote = TableExtensions .isInlineFootnote(table); // IMPROVE: this is only a temporary situation for the table @@ -160,6 +167,7 @@ public void export(final Map tables, final Sheet sheet = workbook.getSheetAt(0); workbook.setSheetName(0, shortcut.substring(0, 1).toUpperCase() + shortcut.substring(1)); + createCustomCellAndFont(workbook); // dummy-Header erzeugen für die Transformation final String[] headers = getColumnHeaders(sheet); final int columnCount = headers.length; @@ -246,11 +254,18 @@ private static void fillSheet(final Sheet sheet, final List rows, } final Row sheetRow = contentRowIndex == rowIndex ? sheet.getRow(contentRowIndex) - : createNewRow(sheet, contentRowIndex, columnCount); + : sheet.createRow(contentRowIndex); + if (contentRowIndex != rowIndex) { + final Cell firstCell = sheetRow.createCell(0); + firstCell.getCellStyle().setBorderBottom(BorderStyle.NONE); + firstCell.getCellStyle().setBorderTop(BorderStyle.NONE); + + } final FootnoteContainer footnotes = row.getFootnotes(); - final List contents = getCellContents(row); for (int i = 0; i < columnCount; i++) { - final String content = contents.get(i); + final TableCell tableCell = row.getCells().get(i); + final XSSFRichTextString richTextCell = createRichTextCell( + tableCell.getContent()); Cell cell = sheetRow.getCell(i + 1); if (cell == null) { @@ -260,20 +275,33 @@ private static void fillSheet(final Sheet sheet, final List rows, // If that is the case we take at least the font from the // definitely defined first cell from the header so that all // the cells are using the same font. - cell.getCellStyle() - .setFont(sheet.getWorkbook() - .getFontAt(sheet.getRow(0) - .getCell(1) - .getCellStyle() - .getFontIndex())); + if (tableCell.getContent() instanceof StringCellContent) { + cell.getCellStyle() + .setFont(getDefaultFont(sheet.getWorkbook())); + } + } if (TableToTableDocument .isRemarkColumn(row.getCells().get(i))) { - fillFootnoteCell(cell, content, allFootnotes, footnotes, - inlineFootnote); + fillFootnoteCell(cell, richTextCell, allFootnotes, + footnotes, inlineFootnote); continue; } - cell.setCellValue(content); + + if (tableCell.getContent() instanceof CompareTableCellContent) { + if (row instanceof PlanCompareRow) { + if (i == 0) { + cell.setCellStyle(compareTableRowStyleFirstCell); + } else if (i == columnCount) { + cell.setCellStyle(compareTableRowStyleLastCell); + } else { + cell.setCellStyle(compareTableRowStyle); + } + } else { + cell.setCellStyle(compareTableCellStyle); + } + } + cell.setCellValue(richTextCell); } // Auto adjust row height sheetRow.setHeight((short) -1); @@ -297,6 +325,46 @@ private static List getCellContents(final TableRow row) { }).toList(); } + private static XSSFRichTextString createRichTextCell( + final CellContent content) { + return switch (content) { + case final StringCellContent stringContent -> new XSSFRichTextString( + CellContentExtensions.getPlainStringValue(stringContent)); + case final CompareTableCellContent compareTableContent -> createRichTextCell( + compareTableContent.getMainPlanCellContent()); + case final CompareStateCellContent compareStateContent -> createRichTextCell( + compareStateContent); + default -> throw new IllegalArgumentException( + "Unexpected value: " + content); + }; + } + + private static XSSFRichTextString createRichTextCell( + final CompareStateCellContent compareStateContent) { + final Iterable newValues = CellContentExtensions + .getStringValueIterable(compareStateContent.getNewValue()); + final Iterable oldValues = CellContentExtensions + .getStringValueIterable(compareStateContent.getOldValue()); + final String newValuesStr = Streams.stream(newValues) + .collect(Collectors.joining(System.lineSeparator())); + final String oldValuesStr = Streams.stream(oldValues) + .collect(Collectors.joining(System.lineSeparator())); + final String textValue = Stream.of(newValuesStr, oldValuesStr) + .collect(Collectors.joining(System.lineSeparator())); + final XSSFRichTextString richtText = new XSSFRichTextString(textValue); + if (newValuesStr.isEmpty()) { + richtText.applyFont(0, textValue.length(), cellOldValueFont); + } else if (oldValuesStr.isEmpty()) { + richtText.applyFont(0, textValue.length(), cellNewValueFont); + } else { + richtText.applyFont(0, newValuesStr.length(), cellNewValueFont); + richtText.applyFont(newValuesStr.length() + 1, textValue.length(), + cellOldValueFont); + } + + return richtText; + } + private static List getFootnotes( final FootnoteContainer fnContainer) { if (fnContainer == null) { @@ -315,7 +383,8 @@ private static List getFootnotes( } private static void fillFootnoteCell(final Cell cell, - final String cellContent, final List allFootnotes, + final XSSFRichTextString richText, + final List allFootnotes, final FootnoteContainer fnContainer, final boolean inlineFootnote) { final List footnotes = getFootnotes(fnContainer); final List fnInfo = TableToTableDocument @@ -324,6 +393,7 @@ private static void fillFootnoteCell(final Cell cell, fn)) .toList()); final StringBuilder builder = new StringBuilder(); + final String cellContent = richText.getString(); if (!cellContent.isEmpty() && !cellContent.isBlank()) { builder.append(cellContent); builder.append(TableToTableDocument.FOOTNOTE_INLINE_TEXT_SEPARATOR); @@ -335,26 +405,8 @@ private static void fillFootnoteCell(final Cell cell, ? TableToTableDocument.FOOTNOTE_INLINE_TEXT_SEPARATOR : TableToTableDocument.FOOTNOTE_MARK_SEPRATOR)); builder.append(footnoteValue); - cell.setCellValue(builder.toString()); - } - - @SuppressWarnings("resource") - private static Row createNewRow(final Sheet sheet, final int rowIndex, - final int maxColIndex) { - final Row cloneRow = sheet.createRow(rowIndex); - final Workbook workbook = sheet.getWorkbook(); - for (int i = 0; i <= maxColIndex; i++) { - final Optional cellAt = getCellAt(sheet, rowIndex - 1, i); - final Cell newCell = cloneRow.createCell(i); - if (cellAt.isPresent()) { - final CellStyle cloneStyle = workbook.createCellStyle(); - cloneStyle.cloneStyleFrom(cellAt.get().getCellStyle()); - cloneStyle.setBorderTop(BorderStyle.NONE); - cloneStyle.setBorderBottom(BorderStyle.NONE); - newCell.setCellStyle(cloneStyle); - } - } - return cloneRow; + richText.setString(builder.toString()); + cell.setCellValue(richText); } private static void addTableSpans(final Sheet sheet, @@ -392,6 +444,122 @@ private static void addTableSpans(final Sheet sheet, } + private static void createCustomCellAndFont(final Workbook workbook) { + createCellNewValueFont(workbook); + createCellOldValueFont(workbook); + createCompareTableCellStyle(workbook); + createCompareTableRowStyle(workbook); + createCompareTableRowStyleFirstCell(workbook); + createCompareTableRowStyleLastCell(workbook); + } + + private static void createCellNewValueFont(final Workbook workbook) { + if (cellNewValueFont != null) { + return; + } + final Font defaultFont = getDefaultFont(workbook); + cellNewValueFont = workbook.createFont(); + + cellNewValueFont.setFontName(defaultFont.getFontName()); + cellNewValueFont + .setFontHeightInPoints(defaultFont.getFontHeightInPoints()); + cellNewValueFont.setColor(IndexedColors.RED.getIndex()); + } + + private static void createCellOldValueFont(final Workbook workbook) { + if (cellOldValueFont != null) { + return; + } + final Font defaultFont = getDefaultFont(workbook); + cellOldValueFont = workbook.createFont(); + cellOldValueFont.setFontName(defaultFont.getFontName()); + cellOldValueFont + .setFontHeightInPoints(defaultFont.getFontHeightInPoints()); + cellOldValueFont.setColor(IndexedColors.YELLOW.getIndex()); + cellOldValueFont.setStrikeout(true); + } + + private static Font getDefaultFont(final Workbook workbook) { + return workbook.getFontAt(workbook.getSheetAt(0) + .getRow(0) + .getCell(1) + .getCellStyle() + .getFontIndex()); + } + + private static void createCompareTableCellStyle(final Workbook workbook) { + if (compareTableCellStyle != null) { + return; + } + compareTableCellStyle = workbook.createCellStyle(); + compareTableCellStyle.setBorderBottom(BorderStyle.MEDIUM); + compareTableCellStyle + .setBottomBorderColor(IndexedColors.BLUE.getIndex()); + + compareTableCellStyle.setBorderTop(BorderStyle.MEDIUM); + compareTableCellStyle.setTopBorderColor(IndexedColors.BLUE.getIndex()); + + compareTableCellStyle.setBorderLeft(BorderStyle.MEDIUM); + compareTableCellStyle.setLeftBorderColor(IndexedColors.BLUE.getIndex()); + + compareTableCellStyle.setBorderRight(BorderStyle.MEDIUM); + compareTableCellStyle + .setRightBorderColor(IndexedColors.BLUE.getIndex()); + } + + private static void createCompareTableRowStyle(final Workbook workbook) { + if (compareTableRowStyle != null) { + return; + } + compareTableRowStyle = workbook.createCellStyle(); + compareTableRowStyle.setBorderBottom(BorderStyle.MEDIUM); + compareTableRowStyle + .setBottomBorderColor(IndexedColors.BLUE.getIndex()); + + compareTableRowStyle.setBorderTop(BorderStyle.MEDIUM); + compareTableRowStyle.setTopBorderColor(IndexedColors.BLUE.getIndex()); + } + + private static void createCompareTableRowStyleFirstCell( + final Workbook workbook) { + if (compareTableRowStyleFirstCell != null) { + return; + } + compareTableRowStyleFirstCell = workbook.createCellStyle(); + + compareTableRowStyleFirstCell.setBorderBottom(BorderStyle.MEDIUM); + compareTableRowStyleFirstCell + .setBottomBorderColor(IndexedColors.BLUE.getIndex()); + + compareTableRowStyleFirstCell.setBorderTop(BorderStyle.MEDIUM); + compareTableRowStyleFirstCell + .setTopBorderColor(IndexedColors.BLUE.getIndex()); + + compareTableRowStyleFirstCell.setBorderLeft(BorderStyle.MEDIUM); + compareTableRowStyleFirstCell + .setLeftBorderColor(IndexedColors.BLUE.getIndex()); + } + + private static void createCompareTableRowStyleLastCell( + final Workbook workbook) { + if (compareTableRowStyleLastCell != null) { + return; + } + compareTableRowStyleLastCell = workbook.createCellStyle(); + + compareTableRowStyleLastCell.setBorderBottom(BorderStyle.MEDIUM); + compareTableRowStyleLastCell + .setBottomBorderColor(IndexedColors.BLUE.getIndex()); + + compareTableRowStyleLastCell.setBorderTop(BorderStyle.MEDIUM); + compareTableRowStyleLastCell + .setTopBorderColor(IndexedColors.BLUE.getIndex()); + + compareTableRowStyleLastCell.setBorderRight(BorderStyle.MEDIUM); + compareTableRowStyleLastCell + .setRightBorderColor(IndexedColors.BLUE.getIndex()); + } + @Override public void exportTitleboxImage(final Titlebox titlebox, final Path path, final OverwriteHandling overwriteHandling) { @@ -420,7 +588,7 @@ public void exportSiteplanPdf(final List imagesData, final double ppm, final String outputDir, final ToolboxPaths toolboxPaths, final TableType tableType, final OverwriteHandling overwriteHandling) { - // do nothing - + // donothing } + } diff --git a/java/bundles/org.eclipse.set.feature.table.pt1/META-INF/MANIFEST.MF b/java/bundles/org.eclipse.set.feature.table.pt1/META-INF/MANIFEST.MF index 10de8cf61c..7edcd8d868 100644 --- a/java/bundles/org.eclipse.set.feature.table.pt1/META-INF/MANIFEST.MF +++ b/java/bundles/org.eclipse.set.feature.table.pt1/META-INF/MANIFEST.MF @@ -29,7 +29,6 @@ Import-Package: com.google.common.base, org.apache.commons.lang3.math;version="[3.17.0,4.0.0)", org.apache.poi.ss.usermodel, org.apache.poi.xssf.usermodel, - org.apache.xmlbeans, org.eclipse.e4.core.contexts, org.eclipse.e4.core.di, org.eclipse.e4.core.services.events, diff --git a/java/bundles/org.eclipse.set.releng.target/org.eclipse.set.releng.target.target b/java/bundles/org.eclipse.set.releng.target/org.eclipse.set.releng.target.target index e16393549f..8df0ffe699 100644 --- a/java/bundles/org.eclipse.set.releng.target/org.eclipse.set.releng.target.target +++ b/java/bundles/org.eclipse.set.releng.target/org.eclipse.set.releng.target.target @@ -307,25 +307,25 @@ DynamicImport-Package: * org.apache.poi poi-ooxml-lite - 5.0.0 + 5.5.1 jar org.apache.poi poi-ooxml - 5.0.0 + 5.5.1 jar org.apache.poi poi - 5.0.0 + 5.5.1 jar org.apache.xmlbeans xmlbeans - 5.1.1 + 5.4.0 jar From c9a2c9058e073ea787777e0d4d8646b751483850 Mon Sep 17 00:00:00 2001 From: Quang Truong Date: Wed, 9 Sep 2026 16:43:07 +0200 Subject: [PATCH 2/5] Set excel export style --- .../META-INF/MANIFEST.MF | 5 + .../export/xlsx/ExcelExportBuilder.java | 487 ++++++++++-------- 2 files changed, 284 insertions(+), 208 deletions(-) diff --git a/java/bundles/org.eclipse.set.feature.export/META-INF/MANIFEST.MF b/java/bundles/org.eclipse.set.feature.export/META-INF/MANIFEST.MF index fea9b13309..03ecf944cf 100644 --- a/java/bundles/org.eclipse.set.feature.export/META-INF/MANIFEST.MF +++ b/java/bundles/org.eclipse.set.feature.export/META-INF/MANIFEST.MF @@ -31,7 +31,11 @@ Import-Package: com.fasterxml.jackson.core, org.apache.poi, org.apache.poi.ss.usermodel, org.apache.poi.ss.util, + org.apache.poi.xssf.model;version="[5.0.0,6.0.0)", org.apache.poi.xssf.usermodel, + org.apache.poi.xssf.usermodel.extensions;version="[5.0.0,6.0.0)", + org.apache.xmlbeans;version="[5.1.0,6.0.0)", + org.apache.xmlbeans.impl.schema;version="[5.4.0,6.0.0)", org.apache.xmlgraphics.image.loader.spi;version="2.4.0", org.apache.xmlgraphics.io;version="2.4.0", org.eclipse.core.runtime;version="3.5.0", @@ -84,6 +88,7 @@ Import-Package: com.fasterxml.jackson.core, org.eclipse.set.utils.export.xsl.siteplan, org.eclipse.set.utils.table, org.eclipse.set.utils.viewgroups, + org.openxmlformats.schemas.spreadsheetml.x2006.main;version="[5.0.0,6.0.0)", org.osgi.service.component.annotations;version="1.2.0", org.osgi.service.event;version="[1.4.0,2.0.0)", org.slf4j;version="1.7.2" diff --git a/java/bundles/org.eclipse.set.feature.export/src/org/eclipse/set/feature/export/xlsx/ExcelExportBuilder.java b/java/bundles/org.eclipse.set.feature.export/src/org/eclipse/set/feature/export/xlsx/ExcelExportBuilder.java index 5fbbfc4fff..152991e6fc 100644 --- a/java/bundles/org.eclipse.set.feature.export/src/org/eclipse/set/feature/export/xlsx/ExcelExportBuilder.java +++ b/java/bundles/org.eclipse.set.feature.export/src/org/eclipse/set/feature/export/xlsx/ExcelExportBuilder.java @@ -17,10 +17,12 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; -import java.util.Collections; +import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.function.IntFunction; +import java.util.function.ToIntFunction; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -34,8 +36,18 @@ import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.util.CellRangeAddress; +import org.apache.poi.xssf.model.StylesTable; +import org.apache.poi.xssf.usermodel.XSSFCell; +import org.apache.poi.xssf.usermodel.XSSFCellStyle; +import org.apache.poi.xssf.usermodel.XSSFColor; +import org.apache.poi.xssf.usermodel.XSSFFont; import org.apache.poi.xssf.usermodel.XSSFRichTextString; +import org.apache.poi.xssf.usermodel.XSSFRow; +import org.apache.poi.xssf.usermodel.XSSFSheet; import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import org.apache.poi.xssf.usermodel.extensions.XSSFCellBorder; +import org.apache.xmlbeans.XmlException; +import org.apache.xmlbeans.XmlObject; import org.eclipse.core.runtime.Assert; import org.eclipse.set.basis.FreeFieldInfo; import org.eclipse.set.basis.OverwriteHandling; @@ -50,9 +62,9 @@ import org.eclipse.set.model.tablemodel.CompareStateCellContent; import org.eclipse.set.model.tablemodel.CompareTableCellContent; import org.eclipse.set.model.tablemodel.CompareTableFootnoteContainer; -import org.eclipse.set.model.tablemodel.Footnote; import org.eclipse.set.model.tablemodel.FootnoteContainer; import org.eclipse.set.model.tablemodel.PlanCompareRow; +import org.eclipse.set.model.tablemodel.PlanCompareRowType; import org.eclipse.set.model.tablemodel.SimpleFootnoteContainer; import org.eclipse.set.model.tablemodel.StringCellContent; import org.eclipse.set.model.tablemodel.Table; @@ -62,10 +74,14 @@ import org.eclipse.set.model.tablemodel.extensions.TableCellExtensions; import org.eclipse.set.model.tablemodel.extensions.TableExtensions; import org.eclipse.set.model.tablemodel.extensions.TableExtensions.FootnoteInfo; -import org.eclipse.set.model.tablemodel.extensions.TableRowExtensions; import org.eclipse.set.model.titlebox.Titlebox; import org.eclipse.set.services.export.TableExport; import org.eclipse.set.utils.table.TableSpanUtils; +import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTBorder; +import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTBorderPr; +import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTColor; +import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTXf; +import org.openxmlformats.schemas.spreadsheetml.x2006.main.STBorderStyle; import org.osgi.service.component.annotations.Component; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -87,15 +103,9 @@ public class ExcelExportBuilder implements TableExport { private static final String TEMPLATE_DIR = "./data/export/excel"; //$NON-NLS-1$ private static final String FOOTNOTE_SHEET_NAME = "Bemerkungen"; //$NON-NLS-1$ - - private static Font cellNewValueFont; - private static Font cellOldValueFont; - private static CellStyle compareTableRowStyle; - private static CellStyle compareTableCellStyle; - - private static CellStyle compareTableRowStyleFirstCell; - - private static CellStyle compareTableRowStyleLastCell; + private static List defaultCellStyleByColumn; + private static XSSFFont cellNewValueFont; + private static XSSFFont cellOldValueFont; private static int getFirstRowForContent(final Sheet sheet) { return getHeaderLastRowIndex(sheet) + 1; @@ -156,18 +166,18 @@ public void export(final Map tables, tableShortcut + "_vorlage.xlsx"); //$NON-NLS-1$ try (final FileInputStream inputStream = new FileInputStream( templatePath.toFile()); - final Workbook workbook = new XSSFWorkbook(inputStream)) { - + final XSSFWorkbook workbook = new XSSFWorkbook(inputStream)) { // check overwrite if (!overwriteHandling.test(outputPath)) { return; } - + createCellNewValueFont(workbook); + createCellOldValueFont(workbook); // es gibt nur einen - final Sheet sheet = workbook.getSheetAt(0); + final XSSFSheet sheet = workbook.getSheetAt(0); workbook.setSheetName(0, shortcut.substring(0, 1).toUpperCase() + shortcut.substring(1)); - createCustomCellAndFont(workbook); + defaultCellStyleByColumn = getDefaultCellStyles(workbook, sheet); // dummy-Header erzeugen für die Transformation final String[] headers = getColumnHeaders(sheet); final int columnCount = headers.length; @@ -178,10 +188,11 @@ public void export(final Map tables, final List rows = TableExtensions.getTableRows(table); // Fill sheet - fillSheet(sheet, rows, rowIndex, columnCount, isInlineFootnote); + fillSheet(workbook, sheet, rows, rowIndex, columnCount, + isInlineFootnote); if (!isInlineFootnote) { - final Sheet footnoteSheet = workbook + final XSSFSheet footnoteSheet = workbook .createSheet(FOOTNOTE_SHEET_NAME); fillFootnoteSheet(footnoteSheet, table); } @@ -198,7 +209,6 @@ public void export(final Map tables, Assert.isNotNull(outputDirPath); FileUtils.forceMkdir(outputDirPath.toFile()); - // ...und im Zielverzeichnis schreiben try (final FileOutputStream fileOut = new FileOutputStream( outputPath.toString())) { @@ -209,8 +219,28 @@ public void export(final Map tables, } } + private static List getDefaultCellStyles( + final XSSFWorkbook workbook, final XSSFSheet sheet) { + final int headerLastRowIndex = getHeaderLastRowIndex(sheet); + final XSSFRow dataRow = sheet.getRow(headerLastRowIndex + 1); + final List result = new LinkedList<>(); + for (int i = 0; i <= getHeaderLastColumnIndex(sheet); i++) { + if (dataRow.getCell(i) == null) { + final XSSFCell cell = dataRow.createCell(i); + cell.getCellStyle().setFont(getDefaultFont(workbook)); + cell.getCellStyle().setBorderBottom(BorderStyle.NONE); + cell.getCellStyle().setBorderTop(BorderStyle.NONE); + cell.getCellStyle().setBorderRight(BorderStyle.NONE); + cell.getCellStyle().setBorderLeft(BorderStyle.NONE); + } + result.add(dataRow.getCell(i).getCellStyle()); + + } + return result; + } + @SuppressWarnings("boxing") - private static void fillFootnoteSheet(final Sheet footnoteSheet, + private static void fillFootnoteSheet(final XSSFSheet footnoteSheet, final Table table) { final List allFootnotes = new ArrayList<>( Streams.stream(TableExtensions.getAllFootnotes(table)) @@ -235,72 +265,34 @@ private static void fillFootnoteSheet(final Sheet footnoteSheet, } } - @SuppressWarnings("resource") - private static void fillSheet(final Sheet sheet, final List rows, + private static void fillSheet(final XSSFWorkbook workbook, + final XSSFSheet sheet, final List rows, final int rowIndex, final int columnCount, final boolean inlineFootnote) { - if (rows.isEmpty()) { - return; - } - final Table table = TableRowExtensions.getTable(rows.getFirst()); - final List allFootnotes = Streams - .stream(TableExtensions.getAllFootnotes(table)) - .toList(); int contentRowIndex = rowIndex; - for (final TableRow row : rows) { - if (isRowEmpty(row)) { + if (isRowEmpty(row) && !(row instanceof PlanCompareRow)) { continue; } - final Row sheetRow = contentRowIndex == rowIndex + final XSSFRow sheetRow = contentRowIndex == rowIndex ? sheet.getRow(contentRowIndex) - : sheet.createRow(contentRowIndex); - if (contentRowIndex != rowIndex) { - final Cell firstCell = sheetRow.createCell(0); - firstCell.getCellStyle().setBorderBottom(BorderStyle.NONE); - firstCell.getCellStyle().setBorderTop(BorderStyle.NONE); - - } - final FootnoteContainer footnotes = row.getFootnotes(); + : createNewRow(sheet, contentRowIndex, columnCount); + final FootnoteContainer footnoteContainer = row.getFootnotes(); for (int i = 0; i < columnCount; i++) { final TableCell tableCell = row.getCells().get(i); final XSSFRichTextString richTextCell = createRichTextCell( tableCell.getContent()); - Cell cell = sheetRow.getCell(i + 1); - - if (cell == null) { - cell = sheetRow.createCell(i + 1); - // in the excel template it might be the case that a certain - // cell is was never defined/styled. - // If that is the case we take at least the font from the - // definitely defined first cell from the header so that all - // the cells are using the same font. - if (tableCell.getContent() instanceof StringCellContent) { - cell.getCellStyle() - .setFont(getDefaultFont(sheet.getWorkbook())); - } - + final XSSFCell cell = sheetRow.getCell(i + 1); + if (tableCell.getContent() instanceof CompareTableCellContent) { + setCompareTableCellStyle(workbook, columnCount, row, i, + cell); } - if (TableToTableDocument - .isRemarkColumn(row.getCells().get(i))) { - fillFootnoteCell(cell, richTextCell, allFootnotes, - footnotes, inlineFootnote); - continue; + if (TableToTableDocument.isRemarkColumn(row.getCells().get(i)) + && footnoteContainer != null) { + fillFootnoteCell(richTextCell, footnoteContainer, + inlineFootnote); } - if (tableCell.getContent() instanceof CompareTableCellContent) { - if (row instanceof PlanCompareRow) { - if (i == 0) { - cell.setCellStyle(compareTableRowStyleFirstCell); - } else if (i == columnCount) { - cell.setCellStyle(compareTableRowStyleLastCell); - } else { - cell.setCellStyle(compareTableRowStyle); - } - } else { - cell.setCellStyle(compareTableCellStyle); - } - } cell.setCellValue(richTextCell); } // Auto adjust row height @@ -309,6 +301,24 @@ private static void fillSheet(final Sheet sheet, final List rows, } } + private static void setCompareTableCellStyle(final XSSFWorkbook workbook, + final int columnCount, final TableRow row, final int i, + final XSSFCell cell) { + final CTBorder cellBorder = switch (row) { + case final PlanCompareRow compareRow -> createCompareTableCellBorderStyle( + workbook, true, true, i == columnCount - 1, i == 0, + compareRow + .getRowType() == PlanCompareRowType.CHANGED_GUID_ROW + ? STBorderStyle.MEDIUM_DASHED + : STBorderStyle.MEDIUM); + default -> createCompareTableCellBorderStyle(workbook, true, true, + true, true, STBorderStyle.MEDIUM); + }; + final XSSFCellStyle compareTableCellStyle = getCompareTableCellStyle( + workbook, cell, cellBorder); + cell.setCellStyle(compareTableCellStyle); + } + private static boolean isRowEmpty(final TableRow row) { return getCellContents(row).stream() .allMatch(s -> s == null || s.trim().isEmpty()); @@ -325,8 +335,12 @@ private static List getCellContents(final TableRow row) { }).toList(); } + @SuppressWarnings("nls") private static XSSFRichTextString createRichTextCell( final CellContent content) { + if (content == null) { + return new XSSFRichTextString(""); + } return switch (content) { case final StringCellContent stringContent -> new XSSFRichTextString( CellContentExtensions.getPlainStringValue(stringContent)); @@ -349,14 +363,18 @@ private static XSSFRichTextString createRichTextCell( .collect(Collectors.joining(System.lineSeparator())); final String oldValuesStr = Streams.stream(oldValues) .collect(Collectors.joining(System.lineSeparator())); - final String textValue = Stream.of(newValuesStr, oldValuesStr) - .collect(Collectors.joining(System.lineSeparator())); - final XSSFRichTextString richtText = new XSSFRichTextString(textValue); + + final XSSFRichTextString richtText = new XSSFRichTextString(); if (newValuesStr.isEmpty()) { - richtText.applyFont(0, textValue.length(), cellOldValueFont); + richtText.setString(oldValuesStr); + richtText.applyFont(0, oldValuesStr.length(), cellOldValueFont); } else if (oldValuesStr.isEmpty()) { - richtText.applyFont(0, textValue.length(), cellNewValueFont); + richtText.setString(newValuesStr); + richtText.applyFont(0, newValuesStr.length(), cellNewValueFont); } else { + final String textValue = Stream.of(newValuesStr, oldValuesStr) + .collect(Collectors.joining(System.lineSeparator())); + richtText.setString(textValue); richtText.applyFont(0, newValuesStr.length(), cellNewValueFont); richtText.applyFont(newValuesStr.length() + 1, textValue.length(), cellOldValueFont); @@ -365,48 +383,173 @@ private static XSSFRichTextString createRichTextCell( return richtText; } - private static List getFootnotes( - final FootnoteContainer fnContainer) { - if (fnContainer == null) { - return Collections.emptyList(); + private static XSSFCellStyle getCompareTableCellStyle( + final XSSFWorkbook workbook, final XSSFCell currentCell, + final CTBorder ctBorder) { + try { + final StylesTable stylesSource = workbook.getStylesSource(); + final CTXf clone = cloneCellCTXf(workbook, currentCell); + // Create blue border for compare cell + // When the border already added to workbook, then get the index in + // styles source, else added to styles source + final int compareTableCellBorderIdx = getStyleSourceObjectIndex( + ctBorder, // + index -> stylesSource.getBorderAt(index).getCTBorder(), + newObj -> stylesSource.putBorder( + new XSSFCellBorder(newObj, workbook.getTheme(), + stylesSource.getIndexedColors()))); + clone.setBorderId(compareTableCellBorderIdx); + clone.setApplyBorder(true); + + // When the styles source exist the cell style like this, then give + // the index of back, else added + final int compareTableCellStyleIdx = getStyleSourceObjectIndex( + clone, // + stylesSource::getCellXfAt, // + newObj -> stylesSource.putCellXf(newObj) - 1); + return new XSSFCellStyle(compareTableCellStyleIdx, -1, stylesSource, + workbook.getTheme()); + } catch (final Exception e) { + throw new RuntimeException(e); } - return switch (fnContainer) { - case final SimpleFootnoteContainer simpleContainer -> simpleContainer - .getFootnotes(); - case final CompareFootnoteContainer compareContainer -> compareContainer - .getUnchangedFootnotes() - .getFootnotes(); - case final CompareTableFootnoteContainer compareContainer -> getFootnotes( - compareContainer.getMainPlanFootnoteContainer()); - default -> Collections.emptyList(); - }; } - private static void fillFootnoteCell(final Cell cell, - final XSSFRichTextString richText, - final List allFootnotes, + private static CTXf cloneCellCTXf(final XSSFWorkbook workbook, + final XSSFCell currentCell) throws XmlException { + final StylesTable stylesSource = workbook.getStylesSource(); + // Get storage style index + final int currentStyleIdx = stylesSource + .putStyle(currentCell.getCellStyle()); + // Get raw source of the style + final CTXf currentCellCTXf = stylesSource.getCellXfAt(currentStyleIdx); + + return CTXf.Factory.parse(currentCellCTXf.xmlText()); + } + + private static CTBorder createCompareTableCellBorderStyle( + final XSSFWorkbook workbook, final boolean setTop, + final boolean setBottom, final boolean setRight, + final boolean setLeft, final STBorderStyle.Enum borderStyle) { + final CTBorder ctborder = CTBorder.Factory.newInstance(); + final XSSFColor clr = XSSFColor.from(CTColor.Factory.newInstance(), + workbook.getStylesSource().getIndexedColors()); + clr.setIndexed(IndexedColors.BLUE.getIndex()); + if (setBottom) { + final CTBorderPr bottom = ctborder.isSetBottom() + ? ctborder.getBottom() + : ctborder.addNewBottom(); + bottom.setStyle(borderStyle); + bottom.setColor(clr.getCTColor()); + } + + if (setTop) { + final CTBorderPr top = ctborder.isSetTop() ? ctborder.getTop() + : ctborder.addNewTop(); + top.setStyle(borderStyle); + top.setColor(clr.getCTColor()); + } + + if (setRight) { + final CTBorderPr right = ctborder.isSetRight() ? ctborder.getRight() + : ctborder.addNewRight(); + right.setStyle(STBorderStyle.MEDIUM); + right.setColor(clr.getCTColor()); + + } + + if (setLeft) { + final CTBorderPr left = ctborder.isSetLeft() ? ctborder.getLeft() + : ctborder.addNewLeft(); + left.setStyle(STBorderStyle.MEDIUM); + left.setColor(clr.getCTColor()); + } + + return ctborder; + } + + private static int getStyleSourceObjectIndex( + final T obj, final IntFunction getAddedObjFunc, + final ToIntFunction addNewObjFunc) { + try { + int i = 0; + while (true) { + final T addedObj = getAddedObjFunc.apply(i); + if (addedObj.xmlText().equals(obj.xmlText())) { + return i; + } + i++; + } + } catch (final IndexOutOfBoundsException e) { + return addNewObjFunc.applyAsInt(obj); + } catch (final Exception e) { + throw new RuntimeException(e); + } + + } + + private static void fillFootnoteCell(final XSSFRichTextString richText, final FootnoteContainer fnContainer, final boolean inlineFootnote) { - final List footnotes = getFootnotes(fnContainer); - final List fnInfo = TableToTableDocument - .processFootnotes(footnotes.stream() - .map(fn -> TableExtensions.getFootnoteInfo(allFootnotes, - fn)) - .toList()); - final StringBuilder builder = new StringBuilder(); - final String cellContent = richText.getString(); - if (!cellContent.isEmpty() && !cellContent.isBlank()) { - builder.append(cellContent); - builder.append(TableToTableDocument.FOOTNOTE_INLINE_TEXT_SEPARATOR); + switch (fnContainer) { + case final SimpleFootnoteContainer simpleContainer -> { + final Iterable fnsInfo = TableExtensions + .getFootnoteInfos(simpleContainer); + final String fnStr = getFootnoteString(fnsInfo, inlineFootnote); + richText.append(System.lineSeparator() + fnStr); + + } + case final CompareFootnoteContainer compareContainer -> { + final Iterable commonFnInfos = TableExtensions + .getFootnoteInfos( + compareContainer.getUnchangedFootnotes()); + final String commonFnStr = getFootnoteString(commonFnInfos, + inlineFootnote); + richText.append(System.lineSeparator() + commonFnStr); + + final Iterable newFnInfos = TableExtensions + .getFootnoteInfos(compareContainer.getNewFootnotes()); + final String newFnStr = getFootnoteString(newFnInfos, + inlineFootnote); + richText.append(System.lineSeparator() + newFnStr, + cellNewValueFont); + + final Iterable oldFnInfos = TableExtensions + .getFootnoteInfos(compareContainer.getOldFootnotes()); + final String oldFnStr = getFootnoteString(oldFnInfos, + inlineFootnote); + richText.append(System.lineSeparator() + oldFnStr, + cellNewValueFont); + + } + case final CompareTableFootnoteContainer compareTableContainer -> fillFootnoteCell( + richText, + compareTableContainer.getMainPlanFootnoteContainer(), + inlineFootnote); + default -> throw new IllegalArgumentException( + fnContainer.getClass().getName()); } - final String footnoteValue = fnInfo.stream() + } + + private static String getFootnoteString( + final Iterable footnotesInfo, + final boolean inlineFootnote) { + return Streams.stream(footnotesInfo) .map(inlineFootnote ? FootnoteInfo::toText : FootnoteInfo::toShorthand) - .collect(Collectors.joining(inlineFootnote - ? TableToTableDocument.FOOTNOTE_INLINE_TEXT_SEPARATOR - : TableToTableDocument.FOOTNOTE_MARK_SEPRATOR)); - builder.append(footnoteValue); - richText.setString(builder.toString()); - cell.setCellValue(richText); + .collect(Collectors + .joining(inlineFootnote ? System.lineSeparator() + : TableToTableDocument.FOOTNOTE_MARK_SEPRATOR)); + + } + + private static XSSFRow createNewRow(final XSSFSheet sheet, + final int rowIndex, final int maxColIndex) { + final XSSFRow cloneRow = sheet.createRow(rowIndex); + for (int i = 0; i <= maxColIndex; i++) { + final Cell newCell = cloneRow.createCell(i); + // Default style is style from first data cell of this column + newCell.setCellStyle(defaultCellStyleByColumn.get(i)); + } + return cloneRow; } private static void addTableSpans(final Sheet sheet, @@ -423,7 +566,6 @@ private static void addTableSpans(final Sheet sheet, final int spanUp = spanUtils.getRowSpanUp(column, row); final int spanDown = spanUtils.getRowSpanDown(column, row); - // If spanUp > 0, we have already merged this span // in a previous iteration if (spanUp > 0) { @@ -434,42 +576,44 @@ private static void addTableSpans(final Sheet sheet, if (spanDown == 0) { continue; } - - sheet.addMergedRegion(new CellRangeAddress(sheetRowIndex, - sheetRowIndex + spanDown, sheetColumn, sheetColumn)); + final CellRangeAddress mergeRegion = new CellRangeAddress( + sheetRowIndex, sheetRowIndex + spanDown, sheetColumn, + sheetColumn); + sheet.addMergedRegion(mergeRegion); + setStyleForMergeRegion(sheet, mergeRegion); } sheetRowIndex++; } - } - private static void createCustomCellAndFont(final Workbook workbook) { - createCellNewValueFont(workbook); - createCellOldValueFont(workbook); - createCompareTableCellStyle(workbook); - createCompareTableRowStyle(workbook); - createCompareTableRowStyleFirstCell(workbook); - createCompareTableRowStyleLastCell(workbook); + private static void setStyleForMergeRegion(final Sheet sheet, + final CellRangeAddress mergeRegion) { + if (mergeRegion.getFirstColumn() != mergeRegion.getLastColumn()) { + throw new IllegalArgumentException("Shoundn't merge vertical cell"); //$NON-NLS-1$ + } + final Cell firstCell = sheet.getRow(mergeRegion.getFirstRow()) + .getCell(mergeRegion.getFirstColumn()); + final CellStyle firstCellStyle = firstCell.getCellStyle(); + for (int i = mergeRegion.getFirstRow(); i <= mergeRegion + .getLastRow(); i++) { + final Cell cell = sheet.getRow(i) + .getCell(mergeRegion.getFirstColumn()); + cell.setCellStyle(firstCellStyle); + } + } - private static void createCellNewValueFont(final Workbook workbook) { - if (cellNewValueFont != null) { - return; - } + private static void createCellNewValueFont(final XSSFWorkbook workbook) { final Font defaultFont = getDefaultFont(workbook); cellNewValueFont = workbook.createFont(); - cellNewValueFont.setFontName(defaultFont.getFontName()); cellNewValueFont .setFontHeightInPoints(defaultFont.getFontHeightInPoints()); cellNewValueFont.setColor(IndexedColors.RED.getIndex()); } - private static void createCellOldValueFont(final Workbook workbook) { - if (cellOldValueFont != null) { - return; - } + private static void createCellOldValueFont(final XSSFWorkbook workbook) { final Font defaultFont = getDefaultFont(workbook); cellOldValueFont = workbook.createFont(); cellOldValueFont.setFontName(defaultFont.getFontName()); @@ -487,79 +631,6 @@ private static Font getDefaultFont(final Workbook workbook) { .getFontIndex()); } - private static void createCompareTableCellStyle(final Workbook workbook) { - if (compareTableCellStyle != null) { - return; - } - compareTableCellStyle = workbook.createCellStyle(); - compareTableCellStyle.setBorderBottom(BorderStyle.MEDIUM); - compareTableCellStyle - .setBottomBorderColor(IndexedColors.BLUE.getIndex()); - - compareTableCellStyle.setBorderTop(BorderStyle.MEDIUM); - compareTableCellStyle.setTopBorderColor(IndexedColors.BLUE.getIndex()); - - compareTableCellStyle.setBorderLeft(BorderStyle.MEDIUM); - compareTableCellStyle.setLeftBorderColor(IndexedColors.BLUE.getIndex()); - - compareTableCellStyle.setBorderRight(BorderStyle.MEDIUM); - compareTableCellStyle - .setRightBorderColor(IndexedColors.BLUE.getIndex()); - } - - private static void createCompareTableRowStyle(final Workbook workbook) { - if (compareTableRowStyle != null) { - return; - } - compareTableRowStyle = workbook.createCellStyle(); - compareTableRowStyle.setBorderBottom(BorderStyle.MEDIUM); - compareTableRowStyle - .setBottomBorderColor(IndexedColors.BLUE.getIndex()); - - compareTableRowStyle.setBorderTop(BorderStyle.MEDIUM); - compareTableRowStyle.setTopBorderColor(IndexedColors.BLUE.getIndex()); - } - - private static void createCompareTableRowStyleFirstCell( - final Workbook workbook) { - if (compareTableRowStyleFirstCell != null) { - return; - } - compareTableRowStyleFirstCell = workbook.createCellStyle(); - - compareTableRowStyleFirstCell.setBorderBottom(BorderStyle.MEDIUM); - compareTableRowStyleFirstCell - .setBottomBorderColor(IndexedColors.BLUE.getIndex()); - - compareTableRowStyleFirstCell.setBorderTop(BorderStyle.MEDIUM); - compareTableRowStyleFirstCell - .setTopBorderColor(IndexedColors.BLUE.getIndex()); - - compareTableRowStyleFirstCell.setBorderLeft(BorderStyle.MEDIUM); - compareTableRowStyleFirstCell - .setLeftBorderColor(IndexedColors.BLUE.getIndex()); - } - - private static void createCompareTableRowStyleLastCell( - final Workbook workbook) { - if (compareTableRowStyleLastCell != null) { - return; - } - compareTableRowStyleLastCell = workbook.createCellStyle(); - - compareTableRowStyleLastCell.setBorderBottom(BorderStyle.MEDIUM); - compareTableRowStyleLastCell - .setBottomBorderColor(IndexedColors.BLUE.getIndex()); - - compareTableRowStyleLastCell.setBorderTop(BorderStyle.MEDIUM); - compareTableRowStyleLastCell - .setTopBorderColor(IndexedColors.BLUE.getIndex()); - - compareTableRowStyleLastCell.setBorderRight(BorderStyle.MEDIUM); - compareTableRowStyleLastCell - .setRightBorderColor(IndexedColors.BLUE.getIndex()); - } - @Override public void exportTitleboxImage(final Titlebox titlebox, final Path path, final OverwriteHandling overwriteHandling) { @@ -588,7 +659,7 @@ public void exportSiteplanPdf(final List imagesData, final double ppm, final String outputDir, final ToolboxPaths toolboxPaths, final TableType tableType, final OverwriteHandling overwriteHandling) { - // donothing + // do nothing } } From 9ab4d83335bf65aa56c9d42e8b9c92416bd78391 Mon Sep 17 00:00:00 2001 From: Quang Truong Date: Fri, 11 Sep 2026 17:05:29 +0200 Subject: [PATCH 3/5] downgrade apache poi --- .../META-INF/MANIFEST.MF | 10 +++++----- .../org.eclipse.set.releng.target.target | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/java/bundles/org.eclipse.set.feature.export/META-INF/MANIFEST.MF b/java/bundles/org.eclipse.set.feature.export/META-INF/MANIFEST.MF index 03ecf944cf..910a483ce8 100644 --- a/java/bundles/org.eclipse.set.feature.export/META-INF/MANIFEST.MF +++ b/java/bundles/org.eclipse.set.feature.export/META-INF/MANIFEST.MF @@ -31,11 +31,11 @@ Import-Package: com.fasterxml.jackson.core, org.apache.poi, org.apache.poi.ss.usermodel, org.apache.poi.ss.util, - org.apache.poi.xssf.model;version="[5.0.0,6.0.0)", + org.apache.poi.xssf.model, org.apache.poi.xssf.usermodel, - org.apache.poi.xssf.usermodel.extensions;version="[5.0.0,6.0.0)", - org.apache.xmlbeans;version="[5.1.0,6.0.0)", - org.apache.xmlbeans.impl.schema;version="[5.4.0,6.0.0)", + org.apache.poi.xssf.usermodel.extensions, + org.apache.xmlbeans, + org.apache.xmlbeans.impl.schema, org.apache.xmlgraphics.image.loader.spi;version="2.4.0", org.apache.xmlgraphics.io;version="2.4.0", org.eclipse.core.runtime;version="3.5.0", @@ -88,7 +88,7 @@ Import-Package: com.fasterxml.jackson.core, org.eclipse.set.utils.export.xsl.siteplan, org.eclipse.set.utils.table, org.eclipse.set.utils.viewgroups, - org.openxmlformats.schemas.spreadsheetml.x2006.main;version="[5.0.0,6.0.0)", + org.openxmlformats.schemas.spreadsheetml.x2006.main, org.osgi.service.component.annotations;version="1.2.0", org.osgi.service.event;version="[1.4.0,2.0.0)", org.slf4j;version="1.7.2" diff --git a/java/bundles/org.eclipse.set.releng.target/org.eclipse.set.releng.target.target b/java/bundles/org.eclipse.set.releng.target/org.eclipse.set.releng.target.target index 8df0ffe699..e16393549f 100644 --- a/java/bundles/org.eclipse.set.releng.target/org.eclipse.set.releng.target.target +++ b/java/bundles/org.eclipse.set.releng.target/org.eclipse.set.releng.target.target @@ -307,25 +307,25 @@ DynamicImport-Package: * org.apache.poi poi-ooxml-lite - 5.5.1 + 5.0.0 jar org.apache.poi poi-ooxml - 5.5.1 + 5.0.0 jar org.apache.poi poi - 5.5.1 + 5.0.0 jar org.apache.xmlbeans xmlbeans - 5.4.0 + 5.1.1 jar From d4da581389aa5f17f960cc16a4c7316508965a1b Mon Sep 17 00:00:00 2001 From: TruongQuangSB <131350493+TruongQuangSB@users.noreply.github.com> Date: Fri, 11 Sep 2026 17:50:34 +0200 Subject: [PATCH 4/5] update --- .../META-INF/MANIFEST.MF | 12 +- .../export/xlsx/ExcelExportBuilder.java | 11 ++ .../feature/export/xlsx/ExcelWaterMark.java | 150 ++++++++++++++++++ 3 files changed, 168 insertions(+), 5 deletions(-) create mode 100644 java/bundles/org.eclipse.set.feature.export/src/org/eclipse/set/feature/export/xlsx/ExcelWaterMark.java diff --git a/java/bundles/org.eclipse.set.feature.export/META-INF/MANIFEST.MF b/java/bundles/org.eclipse.set.feature.export/META-INF/MANIFEST.MF index 03ecf944cf..a5c974131c 100644 --- a/java/bundles/org.eclipse.set.feature.export/META-INF/MANIFEST.MF +++ b/java/bundles/org.eclipse.set.feature.export/META-INF/MANIFEST.MF @@ -31,11 +31,11 @@ Import-Package: com.fasterxml.jackson.core, org.apache.poi, org.apache.poi.ss.usermodel, org.apache.poi.ss.util, - org.apache.poi.xssf.model;version="[5.0.0,6.0.0)", + org.apache.poi.xssf.model, org.apache.poi.xssf.usermodel, - org.apache.poi.xssf.usermodel.extensions;version="[5.0.0,6.0.0)", - org.apache.xmlbeans;version="[5.1.0,6.0.0)", - org.apache.xmlbeans.impl.schema;version="[5.4.0,6.0.0)", + org.apache.poi.xssf.usermodel.extensions, + org.apache.xmlbeans, + org.apache.xmlbeans.impl.schema, org.apache.xmlgraphics.image.loader.spi;version="2.4.0", org.apache.xmlgraphics.io;version="2.4.0", org.eclipse.core.runtime;version="3.5.0", @@ -88,7 +88,9 @@ Import-Package: com.fasterxml.jackson.core, org.eclipse.set.utils.export.xsl.siteplan, org.eclipse.set.utils.table, org.eclipse.set.utils.viewgroups, - org.openxmlformats.schemas.spreadsheetml.x2006.main;version="[5.0.0,6.0.0)", + org.openxmlformats.schemas.drawingml.x2006.main;version="[5.5.0,6.0.0)", + org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing;version="[5.5.0,6.0.0)", + org.openxmlformats.schemas.spreadsheetml.x2006.main, org.osgi.service.component.annotations;version="1.2.0", org.osgi.service.event;version="[1.4.0,2.0.0)", org.slf4j;version="1.7.2" diff --git a/java/bundles/org.eclipse.set.feature.export/src/org/eclipse/set/feature/export/xlsx/ExcelExportBuilder.java b/java/bundles/org.eclipse.set.feature.export/src/org/eclipse/set/feature/export/xlsx/ExcelExportBuilder.java index 152991e6fc..d9ca58e6df 100644 --- a/java/bundles/org.eclipse.set.feature.export/src/org/eclipse/set/feature/export/xlsx/ExcelExportBuilder.java +++ b/java/bundles/org.eclipse.set.feature.export/src/org/eclipse/set/feature/export/xlsx/ExcelExportBuilder.java @@ -56,6 +56,7 @@ import org.eclipse.set.basis.constants.ExportType; import org.eclipse.set.basis.constants.TableType; import org.eclipse.set.basis.exceptions.FileExportException; +import org.eclipse.set.core.services.enumtranslation.EnumTranslationService; import org.eclipse.set.feature.export.pdf.TableToTableDocument; import org.eclipse.set.model.tablemodel.CellContent; import org.eclipse.set.model.tablemodel.CompareFootnoteContainer; @@ -83,6 +84,7 @@ import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTXf; import org.openxmlformats.schemas.spreadsheetml.x2006.main.STBorderStyle; import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Reference; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -107,6 +109,9 @@ public class ExcelExportBuilder implements TableExport { private static XSSFFont cellNewValueFont; private static XSSFFont cellOldValueFont; + @Reference + EnumTranslationService enumTranslationService; + private static int getFirstRowForContent(final Sheet sheet) { return getHeaderLastRowIndex(sheet) + 1; } @@ -178,6 +183,12 @@ public void export(final Map tables, workbook.setSheetName(0, shortcut.substring(0, 1).toUpperCase() + shortcut.substring(1)); defaultCellStyleByColumn = getDefaultCellStyles(workbook, sheet); + if (tableType != TableType.DIFF + && exportType != ExportType.INVENTORY_RECORDS) { + ExcelWaterMark.createWaterMark(sheet, + enumTranslationService.translate(tableType) + .getPresentation()); + } // dummy-Header erzeugen für die Transformation final String[] headers = getColumnHeaders(sheet); final int columnCount = headers.length; diff --git a/java/bundles/org.eclipse.set.feature.export/src/org/eclipse/set/feature/export/xlsx/ExcelWaterMark.java b/java/bundles/org.eclipse.set.feature.export/src/org/eclipse/set/feature/export/xlsx/ExcelWaterMark.java new file mode 100644 index 0000000000..fb1a787d2f --- /dev/null +++ b/java/bundles/org.eclipse.set.feature.export/src/org/eclipse/set/feature/export/xlsx/ExcelWaterMark.java @@ -0,0 +1,150 @@ +/** + * Copyright (c) 2026 DB InfraGO AG and others + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v2.0 which is available at + * https://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + * + */ +package org.eclipse.set.feature.export.xlsx; + +import org.apache.poi.ss.usermodel.ClientAnchor.AnchorType; +import org.apache.poi.xssf.usermodel.XSSFClientAnchor; +import org.apache.poi.xssf.usermodel.XSSFDrawing; +import org.apache.poi.xssf.usermodel.XSSFSheet; +import org.apache.poi.xssf.usermodel.XSSFSimpleShape; +import org.apache.xmlbeans.XmlException; +import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D; +import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTMarker; +import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTShape; + +/** + * The water mark was manually created in Excel using WordArt. This class only + * recreates that WordArt through XML code. + * + * @author truong + */ +@SuppressWarnings("nls") +public class ExcelWaterMark { + + private class CustomXSSFSimpleShape extends XSSFSimpleShape { + public CustomXSSFSimpleShape(final XSSFDrawing drawing, + final CTShape ctShape, final XSSFClientAnchor anchor) { + super(drawing, ctShape); + this.anchor = anchor; + } + + } + + String markText; + XSSFSheet sheet; + + public ExcelWaterMark(final XSSFSheet sheet, final String markText) { + this.sheet = sheet; + this.markText = markText; + } + + private XSSFSimpleShape createSimleShape() throws XmlException { + final XSSFDrawing drawing = sheet.createDrawingPatriarch(); + final CTMarker marker = getMarker(); + + final XSSFClientAnchor xssfClientAnchor = new XSSFClientAnchor( + Integer.parseInt(marker.getColOff().toString()), + Integer.parseInt(marker.getRowOff().toString()), 0, 0, + marker.getCol(), marker.getRow(), 0, 0); + xssfClientAnchor.setAnchorType(AnchorType.DONT_MOVE_AND_RESIZE); + xssfClientAnchor.setSize(getPositiveSize()); + final XSSFSimpleShape simpleShape = new CustomXSSFSimpleShape(drawing, + getCTShape(), xssfClientAnchor); + + simpleShape.setText(markText); + return simpleShape; + } + + private static CTMarker getMarker() throws XmlException { + return CTMarker.Factory + .parse(""" + + 0 + 166688 + 25 + 60050 + + """); + } + + private static CTPositiveSize2D getPositiveSize() throws XmlException { + return CTPositiveSize2D.Factory.parse( + ""); + } + + private static CTShape getCTShape() throws XmlException { + return CTShape.Factory + .parse(""" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + """); + } + + /** + * @param targetSheet + * @param markText + */ + public static void createWaterMark(final XSSFSheet targetSheet, + final String markText) { + try { + final ExcelWaterMark waterMark = new ExcelWaterMark(targetSheet, + markText); + waterMark.createSimleShape(); + } catch (final Exception e) { + throw new RuntimeException(e.getMessage()); + } + + } +} From 6137a090d2cf17460433b5e8e33edae69ced149c Mon Sep 17 00:00:00 2001 From: Quang Truong Date: Tue, 15 Sep 2026 10:34:40 +0200 Subject: [PATCH 5/5] Update test reference --- .../set/feature/export/xlsx/ExcelExportBuilder.java | 2 +- .../res/xsl/ssko-fop.xsl | 2 +- .../res/xsl/sskp-fop.xsl | 2 +- .../res/xsl/sskp_dm-fop.xsl | 2 +- .../res/xsl/sskt-fop.xsl | 2 +- .../res/xsl/sskx-fop.xsl | 2 +- .../res/xsl/ssld-fop.xsl | 2 +- .../org.eclipse.set.releng.target.target | 8 ++++---- 8 files changed, 11 insertions(+), 11 deletions(-) diff --git a/java/bundles/org.eclipse.set.feature.export/src/org/eclipse/set/feature/export/xlsx/ExcelExportBuilder.java b/java/bundles/org.eclipse.set.feature.export/src/org/eclipse/set/feature/export/xlsx/ExcelExportBuilder.java index d9ca58e6df..c64ac7dbff 100644 --- a/java/bundles/org.eclipse.set.feature.export/src/org/eclipse/set/feature/export/xlsx/ExcelExportBuilder.java +++ b/java/bundles/org.eclipse.set.feature.export/src/org/eclipse/set/feature/export/xlsx/ExcelExportBuilder.java @@ -630,7 +630,7 @@ private static void createCellOldValueFont(final XSSFWorkbook workbook) { cellOldValueFont.setFontName(defaultFont.getFontName()); cellOldValueFont .setFontHeightInPoints(defaultFont.getFontHeightInPoints()); - cellOldValueFont.setColor(IndexedColors.YELLOW.getIndex()); + cellOldValueFont.setColor(IndexedColors.ORANGE.getIndex()); cellOldValueFont.setStrikeout(true); } diff --git a/java/bundles/org.eclipse.set.feature.table.pt1.test/res/xsl/ssko-fop.xsl b/java/bundles/org.eclipse.set.feature.table.pt1.test/res/xsl/ssko-fop.xsl index e8ed41a1f4..82d83f3ab0 100644 --- a/java/bundles/org.eclipse.set.feature.table.pt1.test/res/xsl/ssko-fop.xsl +++ b/java/bundles/org.eclipse.set.feature.table.pt1.test/res/xsl/ssko-fop.xsl @@ -99,4 +99,4 @@ http://www.eclipse.org/legal/epl-v20.html ABCDEFGHIJKLMNOPQRSTUVGrundsatzangabenSchlüsselFahrwegWeiche/Gleissperre/BÜSchlosskombination/SchlüsselsperreSonderanlageSchlüssel bei Technisch BerechtigtemBemerkungBezeichnung SchlossSchloss anIn Grundstellung eingeschlossenBezeichnungBartformGruppeBezeichnungVerschlossenes ElementSchlossartBezeichnungHaupt- -schlossUnterbringungZugRangierBezeichnungLageAnbaulageOrtArtOrtStreckekm.Die Tabelle ist leer +schlossUnterbringungZugRangierBezeichnungLageAnbaulageOrtArtOrtStreckekm.Die Tabelle ist leer diff --git a/java/bundles/org.eclipse.set.feature.table.pt1.test/res/xsl/sskp-fop.xsl b/java/bundles/org.eclipse.set.feature.table.pt1.test/res/xsl/sskp-fop.xsl index 886910a7ce..6713f3e3ef 100644 --- a/java/bundles/org.eclipse.set.feature.table.pt1.test/res/xsl/sskp-fop.xsl +++ b/java/bundles/org.eclipse.set.feature.table.pt1.test/res/xsl/sskp-fop.xsl @@ -125,4 +125,4 @@ streckeBauformggf. Montage- ort des SchaltkastensEnergie- -versorgungSollIstAnfangEndeHzkm/hmmmmmmmmmkm/hs%mDie Tabelle ist leer +versorgungSollIstAnfangEndeHzkm/hmmmmmmmmmkm/hs%mDie Tabelle ist leer diff --git a/java/bundles/org.eclipse.set.feature.table.pt1.test/res/xsl/sskp_dm-fop.xsl b/java/bundles/org.eclipse.set.feature.table.pt1.test/res/xsl/sskp_dm-fop.xsl index e6009c0d18..6713f3e3ef 100644 --- a/java/bundles/org.eclipse.set.feature.table.pt1.test/res/xsl/sskp_dm-fop.xsl +++ b/java/bundles/org.eclipse.set.feature.table.pt1.test/res/xsl/sskp_dm-fop.xsl @@ -125,4 +125,4 @@ streckeBauformggf. Montage- ort des SchaltkastensEnergie- -versorgungSollIstAnfangEndeHzkm/hmmmmmmmmmkm/hs%mDie Tabelle ist leer +versorgungSollIstAnfangEndeHzkm/hmmmmmmmmmkm/hs%mDie Tabelle ist leer diff --git a/java/bundles/org.eclipse.set.feature.table.pt1.test/res/xsl/sskt-fop.xsl b/java/bundles/org.eclipse.set.feature.table.pt1.test/res/xsl/sskt-fop.xsl index 271963500e..61ca55bf98 100644 --- a/java/bundles/org.eclipse.set.feature.table.pt1.test/res/xsl/sskt-fop.xsl +++ b/java/bundles/org.eclipse.set.feature.table.pt1.test/res/xsl/sskt-fop.xsl @@ -98,4 +98,4 @@ http://www.eclipse.org/legal/epl-v20.html ABCDEFGHIJKLMNOPGrundsatzangabenIP-AdressangabenBemerkungBezeichnung TSO/BSOArtBSOUnterbringungRegional- -bereichBlauGrauTeilsystemArtOrtStreckekmIPv4IPv6IPv4IPv6ArtBlauGrau.Die Tabelle ist leer +bereichBlauGrauTeilsystemArtOrtStreckekmIPv4IPv6IPv4IPv6ArtBlauGrau.Die Tabelle ist leer diff --git a/java/bundles/org.eclipse.set.feature.table.pt1.test/res/xsl/sskx-fop.xsl b/java/bundles/org.eclipse.set.feature.table.pt1.test/res/xsl/sskx-fop.xsl index 0b3dbc836e..27ba41e509 100644 --- a/java/bundles/org.eclipse.set.feature.table.pt1.test/res/xsl/sskx-fop.xsl +++ b/java/bundles/org.eclipse.set.feature.table.pt1.test/res/xsl/sskx-fop.xsl @@ -104,4 +104,4 @@ Mastmitte - Gleismitte Nr. (Bild)StreckekmGleisLinksRechtsBefestigungRegelzeichnung Nr. (Bild)Art/ Rz. Nr. (Bild)Höhe -u. SOmmmmmmmmDie Tabelle ist leer +u. SOmmmmmmmmDie Tabelle ist leer diff --git a/java/bundles/org.eclipse.set.feature.table.pt1.test/res/xsl/ssld-fop.xsl b/java/bundles/org.eclipse.set.feature.table.pt1.test/res/xsl/ssld-fop.xsl index 840e3fac9e..95f4b8d422 100644 --- a/java/bundles/org.eclipse.set.feature.table.pt1.test/res/xsl/ssld-fop.xsl +++ b/java/bundles/org.eclipse.set.feature.table.pt1.test/res/xsl/ssld-fop.xsl @@ -108,4 +108,4 @@ Aufwertung VerzichtErlaubnis- abhängigManuellAuflöseabschnitt (im Zielgleis)Auflöseverzögerung bzw. Kennlicht- verzögerungszeitSollIstFrei- -gemeldetmit Verschlussohne VerschlussBezeichnungBemessungslängekm/hmmmmsDie Tabelle ist leer +gemeldetmit Verschlussohne VerschlussBezeichnungBemessungslängekm/hmmmmsDie Tabelle ist leer diff --git a/java/bundles/org.eclipse.set.releng.target/org.eclipse.set.releng.target.target b/java/bundles/org.eclipse.set.releng.target/org.eclipse.set.releng.target.target index e16393549f..8df0ffe699 100644 --- a/java/bundles/org.eclipse.set.releng.target/org.eclipse.set.releng.target.target +++ b/java/bundles/org.eclipse.set.releng.target/org.eclipse.set.releng.target.target @@ -307,25 +307,25 @@ DynamicImport-Package: * org.apache.poi poi-ooxml-lite - 5.0.0 + 5.5.1 jar org.apache.poi poi-ooxml - 5.0.0 + 5.5.1 jar org.apache.poi poi - 5.0.0 + 5.5.1 jar org.apache.xmlbeans xmlbeans - 5.1.1 + 5.4.0 jar