Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inserting hyperlinked image #499

Merged
merged 4 commits into from
Sep 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# openxlsx (development version)

* It's now possible to insert a hyperlinked image by passing a URL, relative or absolute file path, or mailto string to the new `address` parameter of `insertImage()`.

# openxlsx 4.2.7

* Fixed warning on `dataValidation(..., type = "list")` ([#342](https://github.com/ycphs/openxlsx/issues/342))
Expand Down
33 changes: 28 additions & 5 deletions R/WorkbookClass.R
Original file line number Diff line number Diff line change
Expand Up @@ -3100,10 +3100,11 @@ Workbook$methods(
width,
height,
rowOffset = 0,
colOffset = 0) {
colOffset = 0,
address) {
## within the sheet the drawing node's Id refernce an id in the sheetRels
## sheet rels reference the drawingi.xml file
## drawingi.xml refernece drawingRels
## drawingi.xml reference drawingRels
## drawing rels reference an image in the media folder
## worksheetRels(sheet(i)) references drawings(j)

Expand All @@ -3113,6 +3114,8 @@ Workbook$methods(
imageType <- gsub("^\\.", "", imageType)

imageNo <- length((drawings[[sheet]])) + 1L
imageRelNo <- length((drawings_rels[[sheet]])) + 1L
linkRelNo <- length((drawings_rels[[sheet]])) + 2L
mediaNo <- length(media) + 1L

startCol <- convertFromExcelRef(startCol)
Expand All @@ -3135,10 +3138,17 @@ Workbook$methods(
drawings_rels[[sheet]],
sprintf(
'<Relationship Id="rId%s" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Target="../media/image%s.%s"/>',
imageNo,
imageRelNo,
JanMarvin marked this conversation as resolved.
Show resolved Hide resolved
mediaNo,
imageType
)
),
if (!missing(address)) {
sprintf(
'<Relationship Id="rId%s" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink" Target="%s" TargetMode="External"/>',
linkRelNo,
address
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since I have been wasting the better half of my Sunday on working with hyperlinks in openxlsx2, I doubt that this will survive saving to a file and loading the file again. Afaik loadWorkbook() converts all hyperlink relationships, creates a new index for them and appends an h at the end. So something like rId2 can become rId1h after saving and loading. You could try to count the number of hyperlink objects in the worksheet and use this here or convert straight to a native openxlsx hyperlink object. But I'm not sure how openxlsx handles these native hyperlinks.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I admit I hadn't considered the impact this change would have on saving and loading a file. I have looked into this now and while these hyperlink relationships do survive the process, there is a pre-existing issue that prevents users from inserting an image into a loaded workbook that already has multiple images.

loadWorkbook() reads the drawings xml into one string, regardless of whether there are multiple images. Same for the drawing relationships. But to assign new images an appropriate index (e.g. rId4), openxlsx relies on each image being a separate element in the drawings list. An example of the problematic xml is below.

# Create a workbook.
wb <- createWorkbook()
addWorksheet(wb, "Sheet 1")
# Insert multiple images.
img <- system.file("extdata", "einstein.jpg", package = "openxlsx")
insertImage(wb, "Sheet 1", img)
insertImage(wb, "Sheet 1", img, address = "https://github.com/ycphs/openxlsx")
insertImage(wb, "Sheet 1", img)
# Save workbook.
tf <- tempfile(fileext = ".xlsx")
saveWorkbook(wb, tf)
# Load workbook.
wb_2 <- loadWorkbook(tf)
# Inspect drawings and drawings_rels.
wb_2$drawings[[1]]
# [1] "<xdr:oneCellAnchor xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\"><xdr:from xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\">    <xdr:col xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\">0</xdr:col>    <xdr:colOff xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\">0</xdr:colOff>    <xdr:row xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\">0</xdr:row>    <xdr:rowOff xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\">0</xdr:rowOff>  </xdr:from><xdr:ext xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\" cx=\"5486400\" cy=\"2743200\"/><xdr:pic xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\">      <xdr:nvPicPr xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\">        <xdr:cNvPr xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\" id=\"1\" name=\"Picture 1\"/>        <xdr:cNvPicPr xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\">          <a:picLocks xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" noChangeAspect=\"1\"/>        </xdr:cNvPicPr>      </xdr:nvPicPr>      <xdr:blipFill xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\">        <a:blip xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" r:embed=\"rId1\">        </a:blip>        <a:stretch xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\">          <a:fillRect/>        </a:stretch>      </xdr:blipFill>      <xdr:spPr xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\">        <a:prstGeom xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" prst=\"rect\">          <a:avLst xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\"/>        </a:prstGeom>      </xdr:spPr>    </xdr:pic><xdr:clientData/></xdr:oneCellAnchor><xdr:oneCellAnchor xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\"><xdr:from xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\">    <xdr:col xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\">0</xdr:col>    <xdr:colOff xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\">0</xdr:colOff>    <xdr:row xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\">0</xdr:row>    <xdr:rowOff xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\">0</xdr:rowOff>  </xdr:from><xdr:ext xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\" cx=\"5486400\" cy=\"2743200\"/><xdr:pic xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\">      <xdr:nvPicPr xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\">        <xdr:cNvPr xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\" id=\"2\" name=\"Picture 2\">              <a:hlinkClick xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" r:id=\"rId3\"/>            </xdr:cNvPr>        <xdr:cNvPicPr xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\">          <a:picLocks xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" noChangeAspect=\"1\"/>        </xdr:cNvPicPr>      </xdr:nvPicPr>      <xdr:blipFill xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\">        <a:blip xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" r:embed=\"rId2\">        </a:blip>        <a:stretch xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\">          <a:fillRect/>        </a:stretch>      </xdr:blipFill>      <xdr:spPr xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\">        <a:prstGeom xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" prst=\"rect\">          <a:avLst xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\"/>        </a:prstGeom>      </xdr:spPr>    </xdr:pic><xdr:clientData/></xdr:oneCellAnchor><xdr:oneCellAnchor xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\"><xdr:from xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\">    <xdr:col xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\">0</xdr:col>    <xdr:colOff xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\">0</xdr:colOff>    <xdr:row xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\">0</xdr:row>    <xdr:rowOff xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\">0</xdr:rowOff>  </xdr:from><xdr:ext xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\" cx=\"5486400\" cy=\"2743200\"/><xdr:pic xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\">      <xdr:nvPicPr xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\">        <xdr:cNvPr xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\" id=\"3\" name=\"Picture 3\"/>        <xdr:cNvPicPr xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\">          <a:picLocks xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" noChangeAspect=\"1\"/>        </xdr:cNvPicPr>      </xdr:nvPicPr>      <xdr:blipFill xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\">        <a:blip xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" r:embed=\"rId4\">        </a:blip>        <a:stretch xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\">          <a:fillRect/>        </a:stretch>      </xdr:blipFill>      <xdr:spPr xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\">        <a:prstGeom xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" prst=\"rect\">          <a:avLst xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\"/>        </a:prstGeom>      </xdr:spPr>    </xdr:pic><xdr:clientData/></xdr:oneCellAnchor>"
wb_2$drawings_rels[[1]]
# [1] "<Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image\" Target=\"../media/image1.jpg\"/><Relationship Id=\"rId2\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image\" Target=\"../media/image2.jpg\"/><Relationship Id=\"rId3\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink\" Target=\"https://github.com/ycphs/openxlsx\" TargetMode=\"External\"/><Relationship Id=\"rId4\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image\" Target=\"../media/image3.jpg\"/>"

It looks like this issue was considered at some point (>9 years ago) because there is some code within loadWorkbook() that splits the xml of images into separate list elements, but it has never been uncommented.

openxlsx/R/loadWorkbook.R

Lines 761 to 765 in 06fa7eb

# ptn1 <- "<(mc:AlternateContent|xdr:oneCellAnchor|xdr:twoCellAnchor|xdr:absoluteAnchor)"
# ptn2 <- "</(mc:AlternateContent|xdr:oneCellAnchor|xdr:twoCellAnchor|xdr:absoluteAnchor)>"
## split at one/two cell Anchor
# dXML <- regmatches(dXML, gregexpr(paste0(ptn1, ".*?", ptn2), dXML))

Based on documentation (https://learn.microsoft.com/en-us/dotnet/api/documentformat.openxml.drawing.spreadsheet.worksheetdrawing?view=openxml-3.0.1) this code seems sensible, but I'm no expert. And I'm not familiar with what would create the mc:AlternateContent tag.

I could adapt this code so that it splits the drawings xml by image when it detects one of these expected tags, and does not split otherwise (i.e. resolve the issue in the expected/majority/possibly all situations, and be no worse off otherwise). I'd also need to write comparable code to handle the drawings_rels xml. Does this sound good to you? (sorry for the essay)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, indeed a bummer, I haven't thought about that. But I don't think it's worth going down that rabbit hole ... again. I have fixed many of these annoyances in openxlsx2, but some people still like to use something that is only partially working 🥲
Your PR has inspired me to JanMarvin/openxlsx2#1137, which should provide a clean solution for these shared hyperlinks.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Understandable! Thanks, @JanMarvin. I really appreciate the work you do in this space on openxlsx and openxlsx2. I'll have to make the time to look into switching to openxlsx2 in the future.

)
}
)

## write file path to media slot to copy across on save
Expand Down Expand Up @@ -3171,7 +3181,20 @@ Workbook$methods(
width,
height
),
genBasePic(imageNo),
genBasePic(
imageNo,
imageRelNo,
ifelse(
missing(address),
"/",
sprintf(
'>
<a:hlinkClick xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" r:id="rId%s"/>
</xdr:cNvPr',
linkRelNo
)
)
),
"<xdr:clientData/>",
"</xdr:oneCellAnchor>"
)
Expand Down
8 changes: 3 additions & 5 deletions R/baseXML.R
Original file line number Diff line number Diff line change
Expand Up @@ -236,10 +236,10 @@ genBaseStyleSheet <- function(dxfs = NULL, tableStyles = NULL, extLst = NULL) {
}


genBasePic <- function(imageNo) {
genBasePic <- function(imageNo, imageRelNo, hyperlinkXML) {
sprintf('<xdr:pic xmlns:xdr="http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing">
<xdr:nvPicPr xmlns:xdr="http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing">
<xdr:cNvPr xmlns:xdr="http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing" id="%s" name="Picture %s"/>
<xdr:cNvPr xmlns:xdr="http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing" id="%s" name="Picture %s"%s>
<xdr:cNvPicPr xmlns:xdr="http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing">
<a:picLocks xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" noChangeAspect="1"/>
</xdr:cNvPicPr>
Expand All @@ -256,7 +256,7 @@ genBasePic <- function(imageNo) {
<a:avLst xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"/>
</a:prstGeom>
</xdr:spPr>
</xdr:pic>', imageNo, imageNo, imageNo)
</xdr:pic>', imageNo, imageNo, hyperlinkXML, imageRelNo)
}


Expand All @@ -266,8 +266,6 @@ genBasePic <- function(imageNo) {





genBaseTheme <- function() {
'<a:theme xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" name="Office Theme">
<a:themeElements><a:clrScheme name="Office">
Expand Down
13 changes: 11 additions & 2 deletions R/wrappers.R
Original file line number Diff line number Diff line change
Expand Up @@ -1222,6 +1222,7 @@ convert2EMU <- function(d, units) {
#' @param startCol Column coordinate of upper left corner of the image
#' @param units Units of width and height. Can be "in", "cm" or "px"
#' @param dpi Image resolution used for conversion between units.
#' @param address An optional character string specifying an external URL, relative or absolute path to a file, or mailto string (e.g. "mailto:example@@example.com") that will be opened when the image is clicked.
#' @importFrom grDevices bmp png jpeg
#' @seealso [insertPlot()]
#' @export
Expand All @@ -1233,18 +1234,20 @@ convert2EMU <- function(d, units) {
#' addWorksheet(wb, "Sheet 1")
#' addWorksheet(wb, "Sheet 2")
#' addWorksheet(wb, "Sheet 3")
#' addWorksheet(wb, "Sheet 4")
#'
#' ## Insert images
#' img <- system.file("extdata", "einstein.jpg", package = "openxlsx")
#' insertImage(wb, "Sheet 1", img, startRow = 5, startCol = 3, width = 6, height = 5)
#' insertImage(wb, 2, img, startRow = 2, startCol = 2)
#' insertImage(wb, 3, img, width = 15, height = 12, startRow = 3, startCol = "G", units = "cm")
#' insertImage(wb, 4, img, address = "https://github.com/ycphs/openxlsx")
#'
#' ## Save workbook
#' \dontrun{
#' saveWorkbook(wb, "insertImageExample.xlsx", overwrite = TRUE)
#' }
insertImage <- function(wb, sheet, file, width = 6, height = 3, startRow = 1, startCol = 1, units = "in", dpi = 300) {
insertImage <- function(wb, sheet, file, width = 6, height = 3, startRow = 1, startCol = 1, units = "in", dpi = 300, address) {
op <- get_set_options()
on.exit(options(op), add = TRUE)

Expand All @@ -1262,6 +1265,12 @@ insertImage <- function(wb, sheet, file, width = 6, height = 3, startRow = 1, st
stop("Invalid units.\nunits must be one of: cm, in, px")
}

if (!missing(address)) {
if (!is.character(address) || length(address) != 1 || is.na(address)) {
stop("Invalid address. address must be a string and have a length of one.")
}
}

startCol <- convertFromExcelRef(startCol)
startRow <- as.integer(startRow)

Expand All @@ -1278,7 +1287,7 @@ insertImage <- function(wb, sheet, file, width = 6, height = 3, startRow = 1, st
widthEMU <- as.integer(round(width * 914400L, 0)) # (EMUs per inch)
heightEMU <- as.integer(round(height * 914400L, 0)) # (EMUs per inch)

wb$insertImage(sheet, file = file, startRow = startRow, startCol = startCol, width = widthEMU, height = heightEMU)
wb$insertImage(sheet, file = file, startRow = startRow, startCol = startCol, width = widthEMU, height = heightEMU, address = address)
}

pixels2ExcelColWidth <- function(pixels) {
Expand Down
7 changes: 6 additions & 1 deletion man/insertImage.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

52 changes: 52 additions & 0 deletions tests/testthat/test-insertImage.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@

context("Inserting images")

test_that("Inserting hyperlinked image", {
# Create a workbook.
wb <- createWorkbook()
addWorksheet(wb, "Sheet 1")

# Insert multiple images. Specifically one with a link before and after other
# images to test whether drawings reference the correct index of the drawing
# relationships.
img <- system.file("extdata", "einstein.jpg", package = "openxlsx")
insertImage(wb, "Sheet 1", img)
insertImage(wb, "Sheet 1", img, address = "https://github.com/ycphs/openxlsx")
insertImage(wb, "Sheet 1", img)

# Declare expectations for drawings and drawings_rels xml.
expected_drawings <- list(
"<xdr:oneCellAnchor xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\"><xdr:from xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\">\n <xdr:col xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\">0</xdr:col>\n <xdr:colOff xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\">0</xdr:colOff>\n <xdr:row xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\">0</xdr:row>\n <xdr:rowOff xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\">0</xdr:rowOff>\n </xdr:from><xdr:ext xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\" cx=\"5486400\" cy=\"2743200\"/><xdr:pic xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\">\n <xdr:nvPicPr xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\">\n <xdr:cNvPr xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\" id=\"1\" name=\"Picture 1\"/>\n <xdr:cNvPicPr xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\">\n <a:picLocks xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" noChangeAspect=\"1\"/>\n </xdr:cNvPicPr>\n </xdr:nvPicPr>\n <xdr:blipFill xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\">\n <a:blip xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" r:embed=\"rId1\">\n </a:blip>\n <a:stretch xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\">\n <a:fillRect/>\n </a:stretch>\n </xdr:blipFill>\n <xdr:spPr xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\">\n <a:prstGeom xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" prst=\"rect\">\n <a:avLst xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\"/>\n </a:prstGeom>\n </xdr:spPr>\n </xdr:pic><xdr:clientData/></xdr:oneCellAnchor>",
"<xdr:oneCellAnchor xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\"><xdr:from xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\">\n <xdr:col xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\">0</xdr:col>\n <xdr:colOff xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\">0</xdr:colOff>\n <xdr:row xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\">0</xdr:row>\n <xdr:rowOff xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\">0</xdr:rowOff>\n </xdr:from><xdr:ext xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\" cx=\"5486400\" cy=\"2743200\"/><xdr:pic xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\">\n <xdr:nvPicPr xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\">\n <xdr:cNvPr xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\" id=\"2\" name=\"Picture 2\">\n <a:hlinkClick xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" r:id=\"rId3\"/>\n </xdr:cNvPr>\n <xdr:cNvPicPr xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\">\n <a:picLocks xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" noChangeAspect=\"1\"/>\n </xdr:cNvPicPr>\n </xdr:nvPicPr>\n <xdr:blipFill xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\">\n <a:blip xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" r:embed=\"rId2\">\n </a:blip>\n <a:stretch xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\">\n <a:fillRect/>\n </a:stretch>\n </xdr:blipFill>\n <xdr:spPr xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\">\n <a:prstGeom xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" prst=\"rect\">\n <a:avLst xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\"/>\n </a:prstGeom>\n </xdr:spPr>\n </xdr:pic><xdr:clientData/></xdr:oneCellAnchor>",
"<xdr:oneCellAnchor xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\"><xdr:from xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\">\n <xdr:col xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\">0</xdr:col>\n <xdr:colOff xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\">0</xdr:colOff>\n <xdr:row xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\">0</xdr:row>\n <xdr:rowOff xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\">0</xdr:rowOff>\n </xdr:from><xdr:ext xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\" cx=\"5486400\" cy=\"2743200\"/><xdr:pic xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\">\n <xdr:nvPicPr xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\">\n <xdr:cNvPr xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\" id=\"3\" name=\"Picture 3\"/>\n <xdr:cNvPicPr xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\">\n <a:picLocks xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" noChangeAspect=\"1\"/>\n </xdr:cNvPicPr>\n </xdr:nvPicPr>\n <xdr:blipFill xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\">\n <a:blip xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" r:embed=\"rId4\">\n </a:blip>\n <a:stretch xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\">\n <a:fillRect/>\n </a:stretch>\n </xdr:blipFill>\n <xdr:spPr xmlns:xdr=\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\">\n <a:prstGeom xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" prst=\"rect\">\n <a:avLst xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\"/>\n </a:prstGeom>\n </xdr:spPr>\n </xdr:pic><xdr:clientData/></xdr:oneCellAnchor>"
)
expected_drawings_rels <- list(
"<Relationship Id=\"rId1\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image\" Target=\"../media/image1.jpg\"/>",
"<Relationship Id=\"rId2\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image\" Target=\"../media/image2.jpg\"/>",
"<Relationship Id=\"rId3\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink\" Target=\"https://github.com/ycphs/openxlsx\" TargetMode=\"External\"/>",
"<Relationship Id=\"rId4\" Type=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image\" Target=\"../media/image3.jpg\"/>"
)

# Test expectations for drawings and drawings_rels xml.
expect_equal(expected_drawings, wb$drawings[[1]])
expect_equal(expected_drawings_rels, wb$drawings_rels[[1]])

# Test errors.
expect_error(
insertImage(wb, "Sheet 1", img, address = NULL),
"Invalid address"
)
expect_error(
insertImage(wb, "Sheet 1", img, address = NA),
"Invalid address"
)
expect_error(
insertImage(
wb,
"Sheet 1",
img,
address = c("https://github.com/ycphs/openxlsx", "https://github.com/ycphs/openxlsx/issues")
),
"Invalid address"
)
})
Loading