bug 58348: add hyperlink copying and merging to CellCopyPolicy

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1711926 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Javen O'Neal 2015-11-02 09:59:32 +00:00
parent 0eb6ec6717
commit f7fbfcd5ea
3 changed files with 209 additions and 18 deletions

View File

@ -21,23 +21,37 @@ import org.apache.poi.util.Beta;
@Beta
public class CellCopyPolicy implements Cloneable {
// cell-level policies
public static final boolean DEFAULT_COPY_CELL_VALUE_POLICY = true;
public static final boolean DEFAULT_COPY_CELL_STYLE_POLICY = true;
public static final boolean DEFAULT_COPY_CELL_FORMULA_POLICY = true;
public static final boolean DEFAULT_COPY_MERGED_REGIONS_POLICY = true;
public static final boolean DEFAULT_COPY_HYPERLINK_POLICY = true;
public static final boolean DEFAULT_MERGE_HYPERLINK_POLICY = false;
// row-level policies
public static final boolean DEFAULT_COPY_ROW_HEIGHT_POLICY = true;
public static final boolean DEFAULT_CONDENSE_ROWS_POLICY = false;
// sheet-level policies
public static final boolean DEFAULT_COPY_MERGED_REGIONS_POLICY = true;
// cell-level policies
private boolean copyCellValue = DEFAULT_COPY_CELL_VALUE_POLICY;
private boolean copyCellStyle = DEFAULT_COPY_CELL_STYLE_POLICY;
private boolean copyCellFormula = DEFAULT_COPY_CELL_FORMULA_POLICY;
private boolean copyMergedRegions = DEFAULT_COPY_MERGED_REGIONS_POLICY;
private boolean copyHyperlink = DEFAULT_COPY_HYPERLINK_POLICY;
private boolean mergeHyperlink = DEFAULT_MERGE_HYPERLINK_POLICY;
// row-level policies
private boolean copyRowHeight = DEFAULT_COPY_ROW_HEIGHT_POLICY;
private boolean condenseRows = DEFAULT_CONDENSE_ROWS_POLICY;
// sheet-level policies
private boolean copyMergedRegions = DEFAULT_COPY_MERGED_REGIONS_POLICY;
/**
* Default CellCopyPolicy, uses default policy
* For custom CellCopyPolicy, use {@link #Builder} class
* For custom CellCopyPolicy, use {@link Builder} class
*/
public CellCopyPolicy() { }
@ -48,25 +62,37 @@ public class CellCopyPolicy implements Cloneable {
copyCellValue = builder.copyCellValue;
copyCellStyle = builder.copyCellStyle;
copyCellFormula = builder.copyCellFormula;
copyMergedRegions = builder.copyMergedRegions;
copyHyperlink = builder.copyHyperlink;
mergeHyperlink = builder.mergeHyperlink;
copyRowHeight = builder.copyRowHeight;
condenseRows = builder.condenseRows;
copyMergedRegions = builder.copyMergedRegions;
}
public static class Builder {
// cell-level policies
private boolean copyCellValue = DEFAULT_COPY_CELL_VALUE_POLICY;
private boolean copyCellStyle = DEFAULT_COPY_CELL_STYLE_POLICY;
private boolean copyCellFormula = DEFAULT_COPY_CELL_FORMULA_POLICY;
private boolean copyMergedRegions = DEFAULT_COPY_MERGED_REGIONS_POLICY;
private boolean copyHyperlink = DEFAULT_COPY_HYPERLINK_POLICY;
private boolean mergeHyperlink = DEFAULT_MERGE_HYPERLINK_POLICY;
// row-level policies
private boolean copyRowHeight = DEFAULT_COPY_ROW_HEIGHT_POLICY;
private boolean condenseRows = DEFAULT_CONDENSE_ROWS_POLICY;
// sheet-level policies
private boolean copyMergedRegions = DEFAULT_COPY_MERGED_REGIONS_POLICY;
/**
* Builder class for CellCopyPolicy
*/
public Builder() {
}
// cell-level policies
public Builder cellValue(boolean copyCellValue) {
this.copyCellValue = copyCellValue;
return this;
@ -79,10 +105,16 @@ public class CellCopyPolicy implements Cloneable {
this.copyCellFormula = copyCellFormula;
return this;
}
public Builder mergedRegions(boolean copyMergedRegions) {
this.copyMergedRegions = copyMergedRegions;
public Builder copyHyperlink(boolean copyHyperlink) {
this.copyHyperlink = copyHyperlink;
return this;
}
public Builder mergeHyperlink(boolean mergeHyperlink) {
this.mergeHyperlink = mergeHyperlink;
return this;
}
// row-level policies
public Builder rowHeight(boolean copyRowHeight) {
this.copyRowHeight = copyRowHeight;
return this;
@ -91,6 +123,12 @@ public class CellCopyPolicy implements Cloneable {
this.condenseRows = condenseRows;
return this;
}
// sheet-level policies
public Builder mergedRegions(boolean copyMergedRegions) {
this.copyMergedRegions = copyMergedRegions;
return this;
}
public CellCopyPolicy build() {
return new CellCopyPolicy(this);
}
@ -101,9 +139,11 @@ public class CellCopyPolicy implements Cloneable {
.cellValue(copyCellValue)
.cellStyle(copyCellStyle)
.cellFormula(copyCellFormula)
.mergedRegions(copyMergedRegions)
.copyHyperlink(copyHyperlink)
.mergeHyperlink(mergeHyperlink)
.rowHeight(copyRowHeight)
.condenseRows(condenseRows);
.condenseRows(condenseRows)
.mergedRegions(copyMergedRegions);
return builder;
}
@ -112,6 +152,9 @@ public class CellCopyPolicy implements Cloneable {
return createBuilder().build();
}
/*
* Cell-level policies
*/
/**
* @return the copyCellValue
*/
@ -155,19 +198,36 @@ public class CellCopyPolicy implements Cloneable {
}
/**
* @return the copyMergedRegions
* @return the copyHyperlink
*/
public boolean isCopyMergedRegions() {
return copyMergedRegions;
public boolean isCopyHyperlink() {
return copyHyperlink;
}
/**
* @param copyMergedRegions the copyMergedRegions to set
* @param copyHyperlink the copyHyperlink to set
*/
public void setCopyMergedRegions(boolean copyMergedRegions) {
this.copyMergedRegions = copyMergedRegions;
public void setCopyHyperlink(boolean copyHyperlink) {
this.copyHyperlink = copyHyperlink;
}
/**
* @return the mergeHyperlink
*/
public boolean isMergeHyperlink() {
return mergeHyperlink;
}
/**
* @param mergeHyperlink the mergeHyperlink to set
*/
public void setMergeHyperlink(boolean mergeHyperlink) {
this.mergeHyperlink = mergeHyperlink;
}
/*
* Row-level policies
*/
/**
* @return the copyRowHeight
*/
@ -200,4 +260,22 @@ public class CellCopyPolicy implements Cloneable {
this.condenseRows = condenseRows;
}
/*
* Sheet-level policies
*/
/**
* @return the copyMergedRegions
*/
public boolean isCopyMergedRegions() {
return copyMergedRegions;
}
/**
* @param copyMergedRegions the copyMergedRegions to set
*/
public void setCopyMergedRegions(boolean copyMergedRegions) {
this.copyMergedRegions = copyMergedRegions;
}
}

View File

@ -180,6 +180,25 @@ public final class XSSFCell implements Cell {
setCellStyle(null);
}
}
if (policy.isMergeHyperlink()) {
// if srcCell doesn't have a hyperlink and destCell has a hyperlink, don't clear destCell's hyperlink
final Hyperlink srcHyperlink = srcCell.getHyperlink();
if (srcHyperlink != null) {
setHyperlink(srcHyperlink.clone());
}
}
else if (policy.isCopyHyperlink()) {
// overwrite the hyperlink at dest cell with srcCell's hyperlink
// if srcCell doesn't have a hyperlink, clear the hyperlink (if one exists) at destCell
final Hyperlink srcHyperlink = srcCell.getHyperlink();
if (srcHyperlink == null) {
setHyperlink(null);
}
else {
setHyperlink(srcHyperlink.clone());
}
}
}
/**

View File

@ -21,9 +21,11 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import java.io.IOException;
import java.util.List;
import org.apache.poi.hssf.HSSFITestDataProvider;
import org.apache.poi.ss.SpreadsheetVersion;
@ -31,7 +33,11 @@ import org.apache.poi.ss.usermodel.BaseTestXCell;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellCopyPolicy;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.CreationHelper;
import org.apache.poi.ss.usermodel.DataFormatter;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.Hyperlink;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.RichTextString;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
@ -521,7 +527,6 @@ public final class TestXSSFCell extends BaseTestXCell {
final CellCopyPolicy policy = new CellCopyPolicy.Builder().cellFormula(false).build();
destCell.copyCellFrom(srcCell, policy);
assertEquals(Cell.CELL_TYPE_NUMERIC, destCell.getCellType());
System.out.println("ERROR: fix formula evaluation");
}
@Test
@ -540,6 +545,95 @@ public final class TestXSSFCell extends BaseTestXCell {
assertEquals(true, destCell.getBooleanCellValue());
}
@Test
public final void testCopyCellFrom_CellCopyPolicy_copyHyperlink() throws IOException {
setUp_testCopyCellFrom_CellCopyPolicy();
final Workbook wb = srcCell.getSheet().getWorkbook();
final CreationHelper createHelper = wb.getCreationHelper();
srcCell.setCellValue("URL LINK");
Hyperlink link = createHelper.createHyperlink(Hyperlink.LINK_URL);
link.setAddress("http://poi.apache.org/");
srcCell.setHyperlink(link);
// Set link cell style (optional)
CellStyle hlinkStyle = wb.createCellStyle();
Font hlinkFont = wb.createFont();
hlinkFont.setUnderline(Font.U_SINGLE);
hlinkFont.setColor(IndexedColors.BLUE.getIndex());
hlinkStyle.setFont(hlinkFont);
srcCell.setCellStyle(hlinkStyle);
// Copy hyperlink
final CellCopyPolicy policy = new CellCopyPolicy.Builder().copyHyperlink(true).mergeHyperlink(false).build();
destCell.copyCellFrom(srcCell, policy);
assertNotNull(destCell.getHyperlink());
assertSame("unit test assumes srcCell and destCell are on the same sheet",
srcCell.getSheet(), destCell.getSheet());
final List<XSSFHyperlink> links = srcCell.getSheet().getHyperlinkList();
assertEquals("number of hyperlinks on sheet", 2, links.size());
assertEquals("source hyperlink",
new CellReference(srcCell).formatAsString(), links.get(0).getCellRef());
assertEquals("destination hyperlink",
new CellReference(destCell).formatAsString(), links.get(1).getCellRef());
wb.close();
}
@Test
public final void testCopyCellFrom_CellCopyPolicy_mergeHyperlink() throws IOException {
setUp_testCopyCellFrom_CellCopyPolicy();
final Workbook wb = srcCell.getSheet().getWorkbook();
final CreationHelper createHelper = wb.getCreationHelper();
srcCell.setCellValue("URL LINK");
Hyperlink link = createHelper.createHyperlink(Hyperlink.LINK_URL);
link.setAddress("http://poi.apache.org/");
destCell.setHyperlink(link);
// Set link cell style (optional)
CellStyle hlinkStyle = wb.createCellStyle();
Font hlinkFont = wb.createFont();
hlinkFont.setUnderline(Font.U_SINGLE);
hlinkFont.setColor(IndexedColors.BLUE.getIndex());
hlinkStyle.setFont(hlinkFont);
destCell.setCellStyle(hlinkStyle);
// Pre-condition assumptions. This test is broken if either of these fail.
assertSame("unit test assumes srcCell and destCell are on the same sheet",
srcCell.getSheet(), destCell.getSheet());
assertNull(srcCell.getHyperlink());
// Merge hyperlink - since srcCell doesn't have a hyperlink, destCell's hyperlink is not overwritten (cleared).
final CellCopyPolicy policy = new CellCopyPolicy.Builder().mergeHyperlink(true).copyHyperlink(false).build();
destCell.copyCellFrom(srcCell, policy);
assertNull(srcCell.getHyperlink());
assertNotNull(destCell.getHyperlink());
assertSame(link, destCell.getHyperlink());
List<XSSFHyperlink> links;
links = srcCell.getSheet().getHyperlinkList();
assertEquals("number of hyperlinks on sheet", 1, links.size());
assertEquals("source hyperlink",
new CellReference(destCell).formatAsString(), links.get(0).getCellRef());
// Merge destCell's hyperlink to srcCell. Since destCell does have a hyperlink, this should copy destCell's hyperlink to srcCell.
srcCell.copyCellFrom(destCell, policy);
assertNotNull(srcCell.getHyperlink());
assertNotNull(destCell.getHyperlink());
links = srcCell.getSheet().getHyperlinkList();
assertEquals("number of hyperlinks on sheet", 2, links.size());
assertEquals("dest hyperlink",
new CellReference(destCell).formatAsString(), links.get(0).getCellRef());
assertEquals("source hyperlink",
new CellReference(srcCell).formatAsString(), links.get(1).getCellRef());
wb.close();
}
private final void setUp_testCopyCellFrom_CellCopyPolicy() {
@SuppressWarnings("resource")
final XSSFWorkbook wb = new XSSFWorkbook();