*/
@Internal
public void removeHyperlink(int row, int column) {
- // CTHyperlinks is regenerated from scratch when writing out the spreadsheet
- // so don't worry about maintaining hyperlinks and CTHyperlinks in parallel.
- // only maintain hyperlinks
- String ref = new CellReference(row, column).formatAsString();
- for (Iterator<XSSFHyperlink> it = hyperlinks.iterator(); it.hasNext();) {
- XSSFHyperlink hyperlink = it.next();
- if (hyperlink.getCellRef().equals(ref)) {
- it.remove();
- return;
+ XSSFHyperlink hyperlink = getHyperlink(row, column);
+ if (hyperlink != null) {
+ if (hyperlink.getFirstRow() == row && hyperlink.getLastRow() == row
+ && hyperlink.getFirstColumn() == column && hyperlink.getLastColumn() == column) {
+ removeHyperlink(hyperlink);
+ } else {
+ //we have a cellRef that spans multiple cells - we just want to remove the hyperlink from one cell
+ //we delete this hyperlink but add new hyperlinks to cover the other cells that were served
+ //by the old hyperlink
+ boolean leftCreated = false;
+ boolean rightCreated = false;
+ if (hyperlink.getFirstColumn() < column) {
+ XSSFHyperlink newLink = new XSSFHyperlink(hyperlink);
+ newLink.setFirstColumn(hyperlink.getFirstColumn());
+ newLink.setLastColumn(column - 1);
+ newLink.setFirstRow(hyperlink.getFirstRow());
+ newLink.setLastRow(hyperlink.getLastRow());
+ addHyperlink(newLink);
+ leftCreated = true;
+ }
+ if (hyperlink.getLastColumn() > column) {
+ XSSFHyperlink newLink = new XSSFHyperlink(hyperlink);
+ newLink.setFirstColumn(column + 1);
+ newLink.setLastColumn(hyperlink.getLastColumn());
+ newLink.setFirstRow(hyperlink.getFirstRow());
+ newLink.setLastRow(hyperlink.getLastRow());
+ addHyperlink(newLink);
+ rightCreated = true;
+ }
+ if (hyperlink.getFirstRow() < row) {
+ XSSFHyperlink newLink = new XSSFHyperlink(hyperlink);
+ int firstColumn = leftCreated ? row : hyperlink.getFirstColumn();
+ int lastColumn = rightCreated ? row : hyperlink.getLastColumn();
+ newLink.setFirstColumn(firstColumn);
+ newLink.setLastColumn(lastColumn);
+ newLink.setFirstRow(hyperlink.getFirstRow());
+ newLink.setLastRow(row - 1);
+ addHyperlink(newLink);
+ }
+ if (hyperlink.getLastRow() > row) {
+ XSSFHyperlink newLink = new XSSFHyperlink(hyperlink);
+ int firstColumn = leftCreated ? row : hyperlink.getFirstColumn();
+ int lastColumn = rightCreated ? row : hyperlink.getLastColumn();
+ newLink.setFirstColumn(firstColumn);
+ newLink.setLastColumn(lastColumn);
+ newLink.setFirstRow(row + 1);
+ newLink.setLastRow(hyperlink.getLastRow());
+ addHyperlink(newLink);
+ }
+ removeHyperlink(hyperlink);
}
}
}
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.openxml4j.opc.PackageRelationship;
import org.apache.poi.openxml4j.opc.PackageRelationshipCollection;
+import org.apache.poi.ss.SpreadsheetVersion;
import org.apache.poi.ss.usermodel.*;
+import org.apache.poi.ss.util.AreaReference;
import org.apache.poi.ss.util.CellAddress;
import org.apache.poi.ss.util.CellReference;
import org.apache.poi.xssf.XSSFITestDataProvider;
}
@Test
- void testChangeReference() throws IOException {
+ void testChangeReference() {
XSSFHyperlink hyperlink = new XSSFHyperlink(HyperlinkType.URL);
hyperlink.setCellReference("B2");
assertEquals(1, hyperlink.getFirstRow());
}
@Test
- void testChangeRowsAndColumns() throws IOException {
+ void testChangeRowsAndColumns() {
XSSFHyperlink hyperlink = new XSSFHyperlink(HyperlinkType.URL);
hyperlink.setCellReference("B2");
hyperlink.setLastRow(0);
assertEquals(1, hyperlink.getFirstColumn());
assertEquals(2, hyperlink.getLastColumn());
}
+
+ @Test
+ void testRemoveSharedHyperlinkFromOneCell() throws IOException {
+ testRemoveSharedHyperlinkFromOneCell("A1:E5", new CellAddress("C3"));
+ testRemoveSharedHyperlinkFromOneCell("A1:E5", new CellAddress("A1"));
+ testRemoveSharedHyperlinkFromOneCell("A1:E5", new CellAddress("E5"));
+ testRemoveSharedHyperlinkFromOneCell("A1:E5", new CellAddress("E1"));
+ testRemoveSharedHyperlinkFromOneCell("A1:E5", new CellAddress("A5"));
+ testRemoveSharedHyperlinkFromOneCell("D3:D5", new CellAddress("D3"));
+ testRemoveSharedHyperlinkFromOneCell("D3:D5", new CellAddress("D4"));
+ testRemoveSharedHyperlinkFromOneCell("D3:D5", new CellAddress("D5"));
+ }
+
+ private void testRemoveSharedHyperlinkFromOneCell(String area, CellAddress cellAddress) throws IOException {
+ try (XSSFWorkbook wb = new XSSFWorkbook()) {
+ XSSFSheet sheet = wb.createSheet();
+ XSSFHyperlink hyperlink = new XSSFHyperlink(HyperlinkType.URL);
+ hyperlink.setAddress("https://poi.apache.org");
+ hyperlink.setLocation("poi-location");
+ hyperlink.setLabel("poi-label");
+ hyperlink.setCellReference(area);
+ sheet.addHyperlink(hyperlink);
+ AreaReference areaRef = new AreaReference(hyperlink.getCellRef(), SpreadsheetVersion.EXCEL2007);
+ for (CellReference cellRef : areaRef.getAllReferencedCells()) {
+ XSSFHyperlink testHyperlink = sheet.getHyperlink(cellRef.getRow(), cellRef.getCol());
+ assertEquals(hyperlink, testHyperlink, "cell " + cellRef.formatAsString() + "has hyperlink?");
+ }
+ sheet.removeHyperlink(cellAddress.getRow(), cellAddress.getColumn());
+ assertNull(sheet.getHyperlink(cellAddress), "cell " + cellAddress.formatAsString() + "should no longer has a hyperlink");
+ for (CellReference cellRef : areaRef.getAllReferencedCells()) {
+ if (cellRef.formatAsString().equals(cellAddress.formatAsString())) {
+ //ignore
+ } else {
+ XSSFHyperlink testHyperlink = sheet.getHyperlink(cellRef.getRow(), cellRef.getCol());
+ assertEquals(hyperlink.getAddress(), testHyperlink.getAddress(), "cell " + cellRef.formatAsString() + "has hyperlink with right address?");
+ assertEquals(hyperlink.getLocation(), testHyperlink.getLocation(), "cell " + cellRef.formatAsString() + "has hyperlink with right location?");
+ assertEquals(hyperlink.getLabel(), testHyperlink.getLabel(), "cell " + cellRef.formatAsString() + "has hyperlink with right label?");
+ }
+ }
+ }
+ }
+
}