You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

XSSFHyperlink.java 9.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  1. /* ====================================================================
  2. Licensed to the Apache Software Foundation (ASF) under one or more
  3. contributor license agreements. See the NOTICE file distributed with
  4. this work for additional information regarding copyright ownership.
  5. The ASF licenses this file to You under the Apache License, Version 2.0
  6. (the "License"); you may not use this file except in compliance with
  7. the License. You may obtain a copy of the License at
  8. http://www.apache.org/licenses/LICENSE-2.0
  9. Unless required by applicable law or agreed to in writing, software
  10. distributed under the License is distributed on an "AS IS" BASIS,
  11. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. See the License for the specific language governing permissions and
  13. limitations under the License.
  14. ==================================================================== */
  15. package org.apache.poi.xssf.usermodel;
  16. import java.net.URI;
  17. import java.net.URISyntaxException;
  18. import org.apache.poi.openxml4j.opc.PackagePart;
  19. import org.apache.poi.openxml4j.opc.PackageRelationship;
  20. import org.apache.poi.ss.usermodel.Hyperlink;
  21. import org.apache.poi.ss.util.CellReference;
  22. import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTHyperlink;
  23. /**
  24. * XSSF Implementation of a Hyperlink.
  25. * Note - unlike with HSSF, many kinds of hyperlink
  26. * are largely stored as relations of the sheet
  27. */
  28. public class XSSFHyperlink implements Hyperlink {
  29. private int _type;
  30. private PackageRelationship _externalRel;
  31. private CTHyperlink _ctHyperlink;
  32. private String _location;
  33. /**
  34. * Create a new XSSFHyperlink. This method is protected to be used only by XSSFCreationHelper
  35. *
  36. * @param type - the type of hyperlink to create
  37. */
  38. protected XSSFHyperlink(int type) {
  39. _type = type;
  40. _ctHyperlink = CTHyperlink.Factory.newInstance();
  41. }
  42. /**
  43. * Create a XSSFHyperlink amd initialize it from the supplied CTHyperlink bean and package relationship
  44. *
  45. * @param ctHyperlink the xml bean containing xml properties
  46. * @param hyperlinkRel the relationship in the underlying OPC package which stores the actual link's address
  47. */
  48. protected XSSFHyperlink(CTHyperlink ctHyperlink, PackageRelationship hyperlinkRel) {
  49. _ctHyperlink = ctHyperlink;
  50. _externalRel = hyperlinkRel;
  51. // Figure out the Hyperlink type and distination
  52. // If it has a location, it's internal
  53. if (ctHyperlink.getLocation() != null) {
  54. _type = Hyperlink.LINK_DOCUMENT;
  55. _location = ctHyperlink.getLocation();
  56. } else {
  57. // Otherwise it's somehow external, check
  58. // the relation to see how
  59. if (_externalRel == null) {
  60. if (ctHyperlink.getId() != null) {
  61. throw new IllegalStateException("The hyperlink for cell " + ctHyperlink.getRef() +
  62. " references relation " + ctHyperlink.getId() + ", but that didn't exist!");
  63. }
  64. // hyperlink is internal and is not related to other parts
  65. _type = Hyperlink.LINK_DOCUMENT;
  66. } else {
  67. URI target = _externalRel.getTargetURI();
  68. _location = target.toString();
  69. // Try to figure out the type
  70. if (_location.startsWith("http://") || _location.startsWith("https://")
  71. || _location.startsWith("ftp://")) {
  72. _type = Hyperlink.LINK_URL;
  73. } else if (_location.startsWith("mailto:")) {
  74. _type = Hyperlink.LINK_EMAIL;
  75. } else {
  76. _type = Hyperlink.LINK_FILE;
  77. }
  78. }
  79. }
  80. }
  81. /**
  82. * @return the underlying CTHyperlink object
  83. */
  84. public CTHyperlink getCTHyperlink() {
  85. return _ctHyperlink;
  86. }
  87. /**
  88. * Do we need to a relation too, to represent
  89. * this hyperlink?
  90. */
  91. public boolean needsRelationToo() {
  92. return (_type != Hyperlink.LINK_DOCUMENT);
  93. }
  94. /**
  95. * Generates the relation if required
  96. */
  97. protected void generateRelationIfNeeded(PackagePart sheetPart) {
  98. if (needsRelationToo()) {
  99. // Generate the relation
  100. PackageRelationship rel =
  101. sheetPart.addExternalRelationship(_location, XSSFRelation.SHEET_HYPERLINKS.getRelation());
  102. // Update the r:id
  103. _ctHyperlink.setId(rel.getId());
  104. }
  105. }
  106. /**
  107. * Return the type of this hyperlink
  108. *
  109. * @return the type of this hyperlink
  110. */
  111. public int getType() {
  112. return _type;
  113. }
  114. /**
  115. * Get the reference of the cell this applies to,
  116. * es A55
  117. */
  118. public String getCellRef() {
  119. return _ctHyperlink.getRef();
  120. }
  121. /**
  122. * Hypelink address. Depending on the hyperlink type it can be URL, e-mail, path to a file
  123. *
  124. * @return the address of this hyperlink
  125. */
  126. public String getAddress() {
  127. return _location;
  128. }
  129. /**
  130. * Return text label for this hyperlink
  131. *
  132. * @return text to display
  133. */
  134. public String getLabel() {
  135. return _ctHyperlink.getDisplay();
  136. }
  137. /**
  138. * Location within target. If target is a workbook (or this workbook) this shall refer to a
  139. * sheet and cell or a defined name. Can also be an HTML anchor if target is HTML file.
  140. *
  141. * @return location
  142. */
  143. public String getLocation() {
  144. return _ctHyperlink.getLocation();
  145. }
  146. /**
  147. * Sets text label for this hyperlink
  148. *
  149. * @param label text label for this hyperlink
  150. */
  151. public void setLabel(String label) {
  152. _ctHyperlink.setDisplay(label);
  153. }
  154. /**
  155. * Location within target. If target is a workbook (or this workbook) this shall refer to a
  156. * sheet and cell or a defined name. Can also be an HTML anchor if target is HTML file.
  157. *
  158. * @param location - string representing a location of this hyperlink
  159. */
  160. public void setLocation(String location) {
  161. _ctHyperlink.setLocation(location);
  162. }
  163. /**
  164. * Hyperlink address. Depending on the hyperlink type it can be URL, e-mail, path to a file
  165. *
  166. * @param address - the address of this hyperlink
  167. */
  168. public void setAddress(String address) {
  169. validate(address);
  170. _location = address;
  171. //we must set location for internal hyperlinks
  172. if (_type == Hyperlink.LINK_DOCUMENT) {
  173. setLocation(address);
  174. }
  175. }
  176. private void validate(String address) {
  177. switch (_type){
  178. // email, path to file and url must be valid URIs
  179. case Hyperlink.LINK_EMAIL:
  180. case Hyperlink.LINK_FILE:
  181. case Hyperlink.LINK_URL:
  182. try {
  183. new URI(address);
  184. } catch (URISyntaxException x) {
  185. IllegalArgumentException y = new IllegalArgumentException("Address of hyperlink must be a valid URI");
  186. y.initCause(x);
  187. throw y;
  188. }
  189. break;
  190. }
  191. }
  192. /**
  193. * Assigns this hyperlink to the given cell reference
  194. */
  195. protected void setCellReference(String ref) {
  196. _ctHyperlink.setRef(ref);
  197. }
  198. private CellReference buildCellReference() {
  199. return new CellReference(_ctHyperlink.getRef());
  200. }
  201. /**
  202. * Return the column of the first cell that contains the hyperlink
  203. *
  204. * @return the 0-based column of the first cell that contains the hyperlink
  205. */
  206. public int getFirstColumn() {
  207. return buildCellReference().getCol();
  208. }
  209. /**
  210. * Return the column of the last cell that contains the hyperlink
  211. *
  212. * @return the 0-based column of the last cell that contains the hyperlink
  213. */
  214. public int getLastColumn() {
  215. return buildCellReference().getCol();
  216. }
  217. /**
  218. * Return the row of the first cell that contains the hyperlink
  219. *
  220. * @return the 0-based row of the cell that contains the hyperlink
  221. */
  222. public int getFirstRow() {
  223. return buildCellReference().getRow();
  224. }
  225. /**
  226. * Return the row of the last cell that contains the hyperlink
  227. *
  228. * @return the 0-based row of the last cell that contains the hyperlink
  229. */
  230. public int getLastRow() {
  231. return buildCellReference().getRow();
  232. }
  233. /**
  234. * Set the column of the first cell that contains the hyperlink
  235. *
  236. * @param col the 0-based column of the first cell that contains the hyperlink
  237. */
  238. public void setFirstColumn(int col) {
  239. _ctHyperlink.setRef(
  240. new CellReference(
  241. getFirstRow(), col
  242. ).formatAsString()
  243. );
  244. }
  245. /**
  246. * Set the column of the last cell that contains the hyperlink
  247. *
  248. * @param col the 0-based column of the last cell that contains the hyperlink
  249. */
  250. public void setLastColumn(int col) {
  251. setFirstColumn(col);
  252. }
  253. /**
  254. * Set the row of the first cell that contains the hyperlink
  255. *
  256. * @param row the 0-based row of the first cell that contains the hyperlink
  257. */
  258. public void setFirstRow(int row) {
  259. _ctHyperlink.setRef(
  260. new CellReference(
  261. row, getFirstColumn()
  262. ).formatAsString()
  263. );
  264. }
  265. /**
  266. * Set the row of the last cell that contains the hyperlink
  267. *
  268. * @param row the 0-based row of the last cell that contains the hyperlink
  269. */
  270. public void setLastRow(int row) {
  271. setFirstRow(row);
  272. }
  273. /**
  274. * @return additional text to help the user understand more about the hyperlink
  275. */
  276. public String getTooltip() {
  277. return _ctHyperlink.getTooltip();
  278. }
  279. /**
  280. * @param text additional text to help the user understand more about the hyperlink
  281. */
  282. public void setTooltip(String text) {
  283. _ctHyperlink.setTooltip(text);
  284. }
  285. }