diff --git a/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFTable.java b/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFTable.java index dfe5a51e59..1cff2e5f9c 100644 --- a/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFTable.java +++ b/poi-ooxml/src/main/java/org/apache/poi/xssf/usermodel/XSSFTable.java @@ -29,6 +29,7 @@ import java.util.HashMap; import java.util.List; import java.util.Locale; +import org.apache.commons.collections4.map.CaseInsensitiveMap; import org.apache.poi.ooxml.POIXMLDocumentPart; import org.apache.poi.openxml4j.opc.PackagePart; import org.apache.poi.ss.SpreadsheetVersion; @@ -60,7 +61,7 @@ public class XSSFTable extends POIXMLDocumentPart implements Table { private CTTable ctTable; private transient List xmlColumnPrs; private transient List tableColumns; - private transient HashMap columnMap; + private transient CaseInsensitiveMap columnMap; private transient CellReference startCellReference; private transient CellReference endCellReference; private transient String commonXPath; @@ -836,9 +837,8 @@ public class XSSFTable extends POIXMLDocumentPart implements Table { public int findColumnIndex(String columnHeader) { if (columnHeader == null) return -1; if (columnMap == null) { - // FIXME: replace with org.apache.commons.collections.map.CaseInsensitiveMap final int count = getColumnCount(); - columnMap = new HashMap<>(count * 3 / 2); + columnMap = new CaseInsensitiveMap<>(count * 3 / 2); int i = 0; for (XSSFTableColumn column : getColumns()) { @@ -849,7 +849,10 @@ public class XSSFTable extends POIXMLDocumentPart implements Table { } // Table column names with special characters need a single quote escape // but the escape is not present in the column definition - Integer idx = columnMap.get(caseInsensitive(columnHeader.replace("'", ""))); + String unescapedString = columnHeader + .replace("''", "'") + .replace("'#", "#"); + Integer idx = columnMap.get(unescapedString); return idx == null ? -1 : idx; } diff --git a/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFTable.java b/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFTable.java index 166149959f..212747c2d9 100644 --- a/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFTable.java +++ b/poi-ooxml/src/test/java/org/apache/poi/xssf/usermodel/TestXSSFTable.java @@ -31,6 +31,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Locale; +import org.apache.commons.io.output.UnsynchronizedByteArrayOutputStream; import org.apache.poi.ss.SpreadsheetVersion; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.util.AreaReference; @@ -592,6 +593,49 @@ public final class TestXSSFTable { } } + @Test + void testBug65669() throws IOException { + String[] testValues = new String[] {"C'olumn", "Column"}; + for (String testValue : testValues) { + try (XSSFWorkbook wb = new XSSFWorkbook()) { + XSSFSheet sheet = wb.createSheet(); + + final String column = testValue; + + // Set the values for the table + XSSFRow row; + XSSFCell cell; + for (int i = 0; i < 3; i++) { + // Create row + row = sheet.createRow(i); + for (int j = 0; j < 3; j++) { + // Create cell + cell = row.createCell(j); + if (i == 0) { + final String columnName = column + (j + 1); + cell.setCellValue(columnName); + } else { + if (j != 2) { + cell.setCellValue((i + 1.0) * (j + 1.0)); + } + } + } + } + + // Create Table + AreaReference reference = wb.getCreationHelper().createAreaReference( + new CellReference(0, 0), new CellReference(2, 2)); + XSSFTable table = sheet.createTable(reference); + table.setName("Table1"); + table.setDisplayName("Table1"); + for (int i = 1; i < 3; i++) { + cell = sheet.getRow(i).getCell(2); + cell.setCellFormula("Table1[[#This Row],[" + column + "1]]"); + } + } + } + } + private static XSSFTable addTable(XSSFSheet sheet,int nRow, int nCol, int nNumRows, int nNumCols) { for (int i = 0; i < nNumRows; i++) { XSSFRow row = sheet.createRow(i + nRow);