-
Notifications
You must be signed in to change notification settings - Fork 15
/
Copy pathconverters.R
100 lines (80 loc) · 2.89 KB
/
converters.R
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# columns -----------------------------------------------------------------
#' @name int2col
#' @title Convert integer to Excel column
#' @description Converts an integer to an Excel column label.
#' @param x A numeric vector
#' @export
#' @examples
#' int2col(1:10)
int2col <- function(x) {
if (!is.numeric(x)) {
stop("x must be numeric.")
}
sapply(x, int_to_col)
}
#' @name col2int
#' @title Convert Excel column to integer
#' @description Converts an Excel column label to an integer.
#' @param x A character vector
#' @export
#' @examples
#' col2int(LETTERS)
col2int <- function(x) {
if (is.numeric(x) || is.integer(x) || is.factor(x))
return(as.numeric(x))
if (!is.character(x)) {
stop("x must be character")
if (any(is.na(x)))
stop("x must be a valid character")
}
col_to_int(x)
}
#' @name get_cell_refs
#' @title Return excel cell coordinates from (x,y) coordinates
#' @description Return excel cell coordinates from (x,y) coordinates
#' @param cellCoords A data.frame with two columns coordinate pairs.
#' @return Excel alphanumeric cell reference
#' @examples
#' get_cell_refs(data.frame(1, 2))
#' # "B1"
#' get_cell_refs(data.frame(1:3, 2:4))
#' # "B1" "C2" "D3"
#' @export
get_cell_refs <- function(cellCoords) {
assert_class(cellCoords, "data.frame")
stopifnot(ncol(cellCoords) == 2L)
if (!all(vapply(cellCoords, is_integer_ish, NA))) {
stop("cellCoords must only contain integers", call. = FALSE)
}
l <- int2col(unlist(cellCoords[, 2]))
paste0(l, cellCoords[, 1])
}
#' calculate the required column width
#'
#' @param base_font the base font name and fontsize
#' @param col_width column width
#' @keywords internal
#' @examples
#' base_font <- wb_get_base_font(wb)
#' calc_col_width(base_font, col_width = 10)
#' @noRd
calc_col_width <- function(base_font, col_width) {
# TODO save this instead as internal package data for quicker loading
fw <- system.file("extdata", "fontwidth/FontWidth.csv", package = "openxlsx2")
font_width_tab <- read.csv(fw)
# TODO base font might not be the font used in this column
font <- base_font$name$val
size <- as.integer(base_font$size$val)
sel <- font_width_tab$FontFamilyName == font & font_width_tab$FontSize == size
# maximum digit width of selected font
mdw <- font_width_tab$Width[sel]
# formula from openxml.spreadsheet.column documentation. The formula returns exactly the expected
# value, but the output in excel is still off. Therefore round to create even numbers. In my tests
# the results were close to the initial col_width sizes. Character width is still bad, numbers are
# way larger, therefore characters cells are to wide. Not sure if we need improve this.
# Note: cannot reproduce the exact values with MS365 on Mac. Nevertheless, these values are closer
# to the expected widths
widths <- trunc((as.numeric(col_width) * mdw + 5) / mdw * 256) / 256
widths <- round(widths, 3)
widths
}