add support for reading hyperlinks that have cell refs that are area references (very limited update or write support as yet)

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1892141 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
PJ Fanning 2021-08-09 21:57:40 +00:00
parent 65d7486cc6
commit 7bcf6d5a6d
4 changed files with 106 additions and 33 deletions

View File

@ -22,7 +22,9 @@ import java.net.URISyntaxException;
import org.apache.poi.common.usermodel.HyperlinkType;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.PackageRelationship;
import org.apache.poi.ss.SpreadsheetVersion;
import org.apache.poi.ss.usermodel.Hyperlink;
import org.apache.poi.ss.util.AreaReference;
import org.apache.poi.ss.util.CellReference;
import org.apache.poi.util.Internal;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTHyperlink;
@ -264,20 +266,32 @@ public class XSSFHyperlink implements Hyperlink {
public void setCellReference(String ref) {
_ctHyperlink.setRef(ref);
}
@Internal
public void setCellReference(CellReference ref) {
setCellReference(ref.formatAsString());
}
private CellReference buildCellReference() {
private CellReference buildFirstCellReference() {
return buildCellReference(false);
}
private CellReference buildLastCellReference() {
return buildCellReference(true);
}
private CellReference buildCellReference(boolean lastCell) {
String ref = _ctHyperlink.getRef();
if (ref == null) {
ref = "A1";
}
if (ref.contains(":")) {
AreaReference area = new AreaReference(ref, SpreadsheetVersion.EXCEL2007);
return lastCell ? area.getLastCell() : area.getFirstCell();
}
return new CellReference(ref);
}
/**
* Return the column of the first cell that contains the hyperlink
*
@ -285,7 +299,7 @@ public class XSSFHyperlink implements Hyperlink {
*/
@Override
public int getFirstColumn() {
return buildCellReference().getCol();
return buildFirstCellReference().getCol();
}
@ -296,7 +310,7 @@ public class XSSFHyperlink implements Hyperlink {
*/
@Override
public int getLastColumn() {
return buildCellReference().getCol();
return buildLastCellReference().getCol();
}
/**
@ -306,7 +320,7 @@ public class XSSFHyperlink implements Hyperlink {
*/
@Override
public int getFirstRow() {
return buildCellReference().getRow();
return buildFirstCellReference().getRow();
}
@ -317,7 +331,7 @@ public class XSSFHyperlink implements Hyperlink {
*/
@Override
public int getLastRow() {
return buildCellReference().getRow();
return buildLastCellReference().getRow();
}
/**
@ -327,18 +341,19 @@ public class XSSFHyperlink implements Hyperlink {
*/
@Override
public void setFirstColumn(int col) {
setCellReference(new CellReference( getFirstRow(), col ));
String firstCellRef = CellReference.convertNumToColString(col) + (getFirstRow() + 1);
setCellRange(firstCellRef + ":" + buildLastCellReference().formatAsString());
}
/**
* Set the column of the last cell that contains the hyperlink.
* For XSSF, a Hyperlink may only reference one cell
*
* @param col the 0-based column of the last cell that contains the hyperlink
*/
@Override
public void setLastColumn(int col) {
setFirstColumn(col);
String lastCellRef = CellReference.convertNumToColString(col) + (getLastRow() + 1);
setCellRange(buildFirstCellReference().formatAsString() + ":" + lastCellRef);
}
/**
@ -348,18 +363,28 @@ public class XSSFHyperlink implements Hyperlink {
*/
@Override
public void setFirstRow(int row) {
setCellReference(new CellReference( row, getFirstColumn() ));
String firstCellRef = CellReference.convertNumToColString(getFirstColumn()) + (row + 1);
setCellRange(firstCellRef + ":" + buildLastCellReference().formatAsString());
}
/**
* Set the row of the last cell that contains the hyperlink.
* For XSSF, a Hyperlink may only reference one cell
*
* @param row the 0-based row of the last cell that contains the hyperlink
*/
@Override
public void setLastRow(int row) {
setFirstRow(row);
String lastCellRef = CellReference.convertNumToColString(getLastColumn()) + (row + 1);
setCellRange(buildFirstCellReference().formatAsString() + ":" + lastCellRef);
}
private void setCellRange(String range) {
AreaReference ref = new AreaReference(range, SpreadsheetVersion.EXCEL2007);
if(ref.isSingleCell()) {
setCellReference(ref.getFirstCell());
} else {
setCellReference(ref.formatAsString());
}
}
/**

View File

@ -55,23 +55,7 @@ import org.apache.poi.poifs.crypt.HashAlgorithm;
import org.apache.poi.ss.SpreadsheetVersion;
import org.apache.poi.ss.formula.FormulaShifter;
import org.apache.poi.ss.formula.SheetNameFormatter;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellCopyPolicy;
import org.apache.poi.ss.usermodel.CellRange;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.DataValidation;
import org.apache.poi.ss.usermodel.DataValidationHelper;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.Footer;
import org.apache.poi.ss.usermodel.FormulaEvaluator;
import org.apache.poi.ss.usermodel.Header;
import org.apache.poi.ss.usermodel.IgnoredErrorType;
import org.apache.poi.ss.usermodel.Name;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Table;
import org.apache.poi.ss.usermodel.Workbook;
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.CellRangeAddress;
@ -846,9 +830,9 @@ public class XSSFSheet extends POIXMLDocumentPart implements Sheet {
*/
@Override
public XSSFHyperlink getHyperlink(CellAddress addr) {
String ref = addr.formatAsString();
for(XSSFHyperlink hyperlink : hyperlinks) {
if(hyperlink.getCellRef().equals(ref)) {
for (XSSFHyperlink hyperlink : getHyperlinkList()) {
if (addr.getRow() >= hyperlink.getFirstRow() && addr.getRow() <= hyperlink.getLastRow()
&& addr.getColumn() >= hyperlink.getFirstColumn() && addr.getColumn() <= hyperlink.getLastColumn()) {
return hyperlink;
}
}

View File

@ -51,6 +51,27 @@ public final class TestXSSFHyperlink extends BaseTestHyperlink {
}
}
@Test
public void readSharedHyperlink() throws IOException {
try (XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("sharedhyperlink.xlsx")) {
XSSFSheet sheet = wb.getSheetAt(0);
XSSFHyperlink hyperlink3 = sheet.getHyperlink(new CellAddress("A3"));
XSSFHyperlink hyperlink4 = sheet.getHyperlink(new CellAddress("A4"));
XSSFHyperlink hyperlink5 = sheet.getHyperlink(new CellAddress("A5"));
assertNotNull(hyperlink3, "hyperlink found?");
assertEquals(hyperlink3, hyperlink4);
assertEquals(hyperlink3, hyperlink5);
assertEquals("A3:A5", hyperlink3.getCellRef());
assertEquals(0, hyperlink3.getFirstColumn());
assertEquals(0, hyperlink3.getLastColumn());
assertEquals(2, hyperlink3.getFirstRow());
assertEquals(4, hyperlink3.getLastRow());
}
}
@Test
void testCreate() throws Exception {
XSSFWorkbook workbook = new XSSFWorkbook();
@ -331,7 +352,7 @@ public final class TestXSSFHyperlink extends BaseTestHyperlink {
}
@Test
void test() throws IOException {
void testCellStyle() throws IOException {
XSSFWorkbook wb = new XSSFWorkbook();
CreationHelper createHelper = wb.getCreationHelper();
@ -372,4 +393,47 @@ public final class TestXSSFHyperlink extends BaseTestHyperlink {
wb.close();
wbBack.close();
}
@Test
void testChangeReference() throws IOException {
try (XSSFWorkbook wb = new XSSFWorkbook()) {
XSSFHyperlink hyperlink = new XSSFHyperlink(HyperlinkType.URL);
hyperlink.setCellReference("B2");
assertEquals(1, hyperlink.getFirstRow());
assertEquals(1, hyperlink.getLastRow());
assertEquals(1, hyperlink.getFirstColumn());
assertEquals(1, hyperlink.getLastColumn());
hyperlink.setFirstRow(0);
assertEquals("B1:B2", hyperlink.getCellRef());
assertEquals(0, hyperlink.getFirstRow());
assertEquals(1, hyperlink.getLastRow());
assertEquals(1, hyperlink.getFirstColumn());
assertEquals(1, hyperlink.getLastColumn());
hyperlink.setLastRow(2);
assertEquals("B1:B3", hyperlink.getCellRef());
assertEquals(0, hyperlink.getFirstRow());
assertEquals(2, hyperlink.getLastRow());
assertEquals(1, hyperlink.getFirstColumn());
assertEquals(1, hyperlink.getLastColumn());
hyperlink.setFirstColumn(0);
assertEquals("A1:B3", hyperlink.getCellRef());
assertEquals(0, hyperlink.getFirstRow());
assertEquals(2, hyperlink.getLastRow());
assertEquals(0, hyperlink.getFirstColumn());
assertEquals(1, hyperlink.getLastColumn());
hyperlink.setLastColumn(2);
assertEquals("A1:C3", hyperlink.getCellRef());
assertEquals(0, hyperlink.getFirstRow());
assertEquals(2, hyperlink.getLastRow());
assertEquals(0, hyperlink.getFirstColumn());
assertEquals(2, hyperlink.getLastColumn());
hyperlink.setFirstColumn(2);
hyperlink.setFirstRow(2);
assertEquals("C3", hyperlink.getCellRef());
assertEquals(2, hyperlink.getFirstRow());
assertEquals(2, hyperlink.getLastRow());
assertEquals(2, hyperlink.getFirstColumn());
assertEquals(2, hyperlink.getLastColumn());
}
}
}

Binary file not shown.