colearendt / xlsx

An R package to interact with Excel files using the Apache POI java library
https://colearendt.github.io/xlsx/
86 stars 32 forks source link

getColumnWidth #163

Open Sasawaws opened 4 years ago

Sasawaws commented 4 years ago

I'd like a "getColumnWidth" so I've tried adding it into the library but I get an error:

method getColumnWidth with signature (I)V not found

getColumnWidth is in the POI API, I suspect the problem lies in the fact that I only have 20 minutes experience with R and haven't used java for 10 years but it looks to me that I need to declare something somewhere but haven't.

I wondered if you might be able to advise?

Thanks

function (sheet, colIndex)
{
    for (ic in (colIndex - 1)) width[ic] <- .jcall(sheet, "V",
        "getColumnWidth", as.integer(ic))
    return(width)
 #   invisible()
}
colearendt commented 4 years ago

Thanks so much for reaching out here @Sasawaws, and apologies for the delayed response! COVID has kept me busy 😄 Well done finding the details here!! The parts of the POI API that are not exposed through the package are definitely usable and accessible (and PRs are welcome!), but there are some tricks to doing so. Try something like this:

tmp <- function (sheet, colIndex) {
  as.integer(lapply(colIndex-1, function(.x) {rJava::.jcall(sheet, "I",
                                          "getColumnWidth", as.integer(.x))}))
}

library(xlsx)

wb <- createWorkbook()
s <- createSheet(wb)

addDataFrame(iris, sheet = s)

tmp(s, 1)
#> [1] 2048
tmp(s, 1:3)
#> [1] 2048 2048 2048

Created on 2020-09-12 by the reprex package (v0.3.0)

When calling a function in Java, you have to define the input as well as the return type. Since getColumnWidth returns something (an integer, in this case), you have to specify that with I (V stands for void). The return types are here:

image

About halfway down the page here: https://www.rforge.net/rJava/

Ooh, another fun trick:

rJava::.jmethods(s)
all_methods <- rJava::.jmethods(s)
all_methods[grep("getColumnWidth", all_methods)]
# [1] "public int org.apache.poi.xssf.usermodel.XSSFSheet.getColumnWidth(int)"

I should really create a contributing guide or something. 😄 There is a bunch of good stuff in the Apache POI package that we have not exported in this package.

I'll leave this issue open until we implement a getColumnWidth function in the package. I believe I implemented this at a previous place of work, but they have not open sourced it 😭 I should reach out again and see if they will do that 🤔 If you want to contribute, a PR would be most welcome! Just please add some tests and such to ensure that the functionality is protected from future breakages! If you need help with any of that, please feel free to ask 😄

paolopavan commented 4 years ago

A contributing guide would be great

colearendt commented 4 years ago

That's a great call!! I will work on that 😄