├── .Rbuildignore ├── .gitignore ├── tests ├── testthat.R └── testthat │ ├── testfiles │ ├── test_file.xlsx │ └── test_file1.ods │ ├── test-helper_functions.R │ └── test-save_file.R ├── inst ├── testfiles │ ├── test_file.ods │ └── test_file.xlsx └── vbs │ ├── recalculate.vbs │ ├── save.vbs │ └── save_xlsx.vbs ├── NAMESPACE ├── odsconvertr.Rproj ├── DESCRIPTION ├── man ├── vbs_file_path.Rd ├── vbs_execute.Rd ├── evaluate_formula.Rd ├── convert_to_ods.Rd └── convert_to_xlsx.Rd ├── R ├── evaluate_formulas.R ├── helper_functions.R └── save_files.R ├── .github ├── ISSUE_TEMPLATE │ ├── feature_request.md │ └── bug_report.md └── pull_request_template.md ├── README.Rmd └── README.md /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^.*\.Rproj$ 2 | ^\.Rproj\.user$ 3 | ^README.Rmd 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .Rproj.user 2 | .Rhistory 3 | .RData 4 | .Ruserdata 5 | -------------------------------------------------------------------------------- /tests/testthat.R: -------------------------------------------------------------------------------- 1 | library(testthat) 2 | library(odsconvertr) 3 | 4 | test_check("odsconvertr") 5 | -------------------------------------------------------------------------------- /inst/testfiles/test_file.ods: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/department-for-transport/odsconvertr/main/inst/testfiles/test_file.ods -------------------------------------------------------------------------------- /inst/testfiles/test_file.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/department-for-transport/odsconvertr/main/inst/testfiles/test_file.xlsx -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | export(convert_to_ods) 4 | export(convert_to_xlsx) 5 | export(evaluate_formula) 6 | -------------------------------------------------------------------------------- /tests/testthat/testfiles/test_file.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/department-for-transport/odsconvertr/main/tests/testthat/testfiles/test_file.xlsx -------------------------------------------------------------------------------- /tests/testthat/testfiles/test_file1.ods: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/department-for-transport/odsconvertr/main/tests/testthat/testfiles/test_file1.ods -------------------------------------------------------------------------------- /inst/vbs/recalculate.vbs: -------------------------------------------------------------------------------- 1 | Set oExcel = CreateObject("Excel.Application") 2 | oExcel.DisplayAlerts = FALSE 'to avoid prompts 3 | Set oWorkbook = oExcel.Workbooks.Open(WScript.Arguments(0)) 4 | oExcel.Calculate 5 | 6 | oWorkbook.Close True 7 | -------------------------------------------------------------------------------- /tests/testthat/test-helper_functions.R: -------------------------------------------------------------------------------- 1 | test_that("Creates expected vbs filepaths", { 2 | 3 | expect_identical(vbs_file_path("test"), 4 | 5 | paste0('"', system.file("vbs", package = "odsconvertr"), "/test", '"') 6 | ) 7 | 8 | expect_identical(vbs_file_path("empty_file123"), 9 | 10 | paste0('"', system.file("vbs", package = "odsconvertr"), "/empty_file123", '"') 11 | ) 12 | 13 | }) 14 | 15 | -------------------------------------------------------------------------------- /odsconvertr.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: Default 4 | SaveWorkspace: Default 5 | AlwaysSaveHistory: Default 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 2 10 | Encoding: UTF-8 11 | 12 | RnwWeave: Sweave 13 | LaTeX: pdfLaTeX 14 | 15 | AutoAppendNewline: Yes 16 | StripTrailingWhitespace: Yes 17 | 18 | BuildType: Package 19 | PackageUseDevtools: Yes 20 | PackageInstallArgs: --no-multiarch --with-keep.source 21 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: odsconvertr 2 | Type: Package 3 | Title: Package of VBS helper functions to facilitate simple Excel processes in R 4 | Version: 0.2.2 5 | Author: Francesca Bryden 6 | Maintainer: Francesca Bryden 7 | Description: Package of VBS helper functions to facilitate simple Excel processes in R. 8 | License: GPL 9 | Encoding: UTF-8 10 | LazyData: true 11 | RoxygenNote: 7.1.1 12 | Suggests: 13 | testthat (>= 3.0.0) 14 | Config/testthat/edition: 3 15 | -------------------------------------------------------------------------------- /inst/vbs/save.vbs: -------------------------------------------------------------------------------- 1 | if WScript.Arguments.Count < 2 Then 2 | WScript.Echo "Error! Please specify the source path and the destination. Usage: XlsToCsv SourcePath.xls Destination.csv" 3 | Wscript.Quit 4 | End If 5 | Dim oExcel 6 | Set oExcel = CreateObject("Excel.Application") 7 | oExcel.DisplayAlerts = FALSE 'to avoid prompts 8 | Dim oBook, local 9 | Set oBook = oExcel.Workbooks.Open(WScript.Arguments(0)) 10 | local = true 11 | call oBook.SaveAs(WScript.Arguments(1), 60) 12 | oBook.Close False 13 | oExcel.Quit 14 | -------------------------------------------------------------------------------- /inst/vbs/save_xlsx.vbs: -------------------------------------------------------------------------------- 1 | if WScript.Arguments.Count < 2 Then 2 | WScript.Echo "Error! Please specify the source path and the destination. Usage: XlsToCsv SourcePath.xls Destination.csv" 3 | Wscript.Quit 4 | End If 5 | Dim oExcel 6 | Set oExcel = CreateObject("Excel.Application") 7 | oExcel.DisplayAlerts = FALSE 'to avoid prompts 8 | Dim oBook, local 9 | Set oBook = oExcel.Workbooks.Open(WScript.Arguments(0)) 10 | local = true 11 | call oBook.SaveAs(WScript.Arguments(1), 51) 12 | oBook.Close False 13 | oExcel.Quit 14 | 15 | -------------------------------------------------------------------------------- /man/vbs_file_path.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/helper_functions.R 3 | \name{vbs_file_path} 4 | \alias{vbs_file_path} 5 | \title{Formats the name of a VBS script file into the filepath within the package} 6 | \usage{ 7 | vbs_file_path(vbs_file) 8 | } 9 | \arguments{ 10 | \item{vbs_file}{Name of a vbs script file saved as part of the package} 11 | } 12 | \description{ 13 | Create a filepath for a referenced VBS file 14 | } 15 | \details{ 16 | Formats the name of a VBS file to be used 17 | } 18 | -------------------------------------------------------------------------------- /man/vbs_execute.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/helper_functions.R 3 | \name{vbs_execute} 4 | \alias{vbs_execute} 5 | \title{Execute a VBS script including arguments} 6 | \usage{ 7 | vbs_execute(vbs_file, ...) 8 | } 9 | \arguments{ 10 | \item{vbs_file}{Name of a vbs script file saved as part of the package} 11 | 12 | \item{...}{Arguments to be passed to the specified VBS script} 13 | } 14 | \description{ 15 | Create a filepath for a referenced VBS file 16 | } 17 | \details{ 18 | Formats the name of a VBS file to be used 19 | } 20 | -------------------------------------------------------------------------------- /man/evaluate_formula.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/evaluate_formulas.R 3 | \name{evaluate_formula} 4 | \alias{evaluate_formula} 5 | \title{Evaluate all formulae in an existing Excel file} 6 | \usage{ 7 | evaluate_formula(path) 8 | } 9 | \arguments{ 10 | \item{path}{path to Excel file; can be either a relative or absolute file path} 11 | } 12 | \description{ 13 | Uses VBA code to open an Excel file and to recalculate any formula in it. 14 | This ensures that all Excel formulae have been executed in a file which may have been updated without being opened (e.g. using code) 15 | } 16 | -------------------------------------------------------------------------------- /man/convert_to_ods.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/save_files.R 3 | \name{convert_to_ods} 4 | \alias{convert_to_ods} 5 | \title{Save a copy of an xlsx file as an ods file} 6 | \usage{ 7 | convert_to_ods(path) 8 | } 9 | \arguments{ 10 | \item{path}{path to xlsx file; can be either a relative or absolute file path} 11 | } 12 | \description{ 13 | Uses VBA code to save a copy of an xlsx file to the accessible ODS format, retaining all sheets and formatting. 14 | } 15 | \details{ 16 | Files converted can be via a relative (from working directory) or absolute (full) file path. In either case, the output ODS file will be returned in the same folder as the XLSX file. 17 | } 18 | -------------------------------------------------------------------------------- /man/convert_to_xlsx.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/save_files.R 3 | \name{convert_to_xlsx} 4 | \alias{convert_to_xlsx} 5 | \title{Save a copy of an ods file as an xlsx file} 6 | \usage{ 7 | convert_to_xlsx(path) 8 | } 9 | \arguments{ 10 | \item{path}{path to ods file; can be either a relative or absolute file path} 11 | } 12 | \description{ 13 | Uses VBA code to save a copy of an ods file to the easy to use xlsx format, retaining all sheets and formatting. 14 | } 15 | \details{ 16 | Files converted can be via a relative (from working directory) or absolute (full) file path. In either case, the output ODS file will be returned in the same folder as the XLSX file. 17 | } 18 | -------------------------------------------------------------------------------- /R/evaluate_formulas.R: -------------------------------------------------------------------------------- 1 | #' Uses VBA code to open an Excel file and to recalculate any formula in it. 2 | #' This ensures that all Excel formulae have been executed in a file which may have been updated without being opened (e.g. using code) 3 | #' 4 | #' @export 5 | #' @param path path to Excel file; can be either a relative or absolute file path 6 | #' @name evaluate_formula 7 | #' @title Evaluate all formulae in an existing Excel file 8 | #' 9 | evaluate_formula <- function(path){ 10 | 11 | ##Normalise path to an absolute one with backslashes and surrounding quotation marks 12 | path <- paste0('"', normalizePath(path), '"') 13 | 14 | ##Execute specified VBS script to save xlsx files 15 | vbs_execute("recalculate.vbs", path) 16 | 17 | } 18 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: 'enhancement' 6 | assignees: '' 7 | 8 | --- 9 | 10 | * **Is your feature request related to a problem? Please describe.** 11 | 12 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 13 | 14 | * **Describe the solution you'd like** 15 | 16 | A clear and concise description of what you want to happen. 17 | 18 | * **Describe alternatives you've considered** 19 | 20 | A clear and concise description of any alternative solutions or features you've considered. 21 | 22 | * **Additional context** 23 | 24 | Add any other context or screenshots about the feature request here. 25 | -------------------------------------------------------------------------------- /tests/testthat/test-save_file.R: -------------------------------------------------------------------------------- 1 | 2 | test_that("File saves as ODS", { 3 | ##Make note of files at start and at end 4 | start_all_files <- list.files("testfiles") 5 | 6 | convert_to_ods("testfiles/test_file.xlsx") 7 | 8 | end_all_files <- list.files("testfiles") 9 | 10 | expect_equal(sum(grepl("test_file.ods", start_all_files, fixed = TRUE)), 0) 11 | expect_equal(sum(grepl("test_file.ods", end_all_files, fixed = TRUE)), 1) 12 | 13 | }) 14 | 15 | test_that("Returns error when file doesnt exist", { 16 | 17 | expect_error(convert_to_ods("abc.xlsx")) 18 | 19 | }) 20 | 21 | 22 | test_that("File saves as XLSX", { 23 | ##Make note of files at start and at end 24 | start_all_files <- list.files("testfiles") 25 | 26 | convert_to_xlsx("testfiles/test_file1.ods") 27 | 28 | end_all_files <- list.files("testfiles") 29 | 30 | expect_equal(sum(grepl("test_file1.xlsx", start_all_files, fixed = TRUE)), 0) 31 | expect_equal(sum(grepl("test_file1.xlsx", end_all_files, fixed = TRUE)), 1) 32 | 33 | }) 34 | 35 | test_that("Returns error when file doesnt exist", { 36 | 37 | expect_error(convert_to_xlsx("abc.ods")) 38 | 39 | }) 40 | 41 | 42 | #Remove test file 43 | unlink("testfiles/test_file.ods") 44 | unlink("testfiles/test_file1.xlsx") 45 | 46 | -------------------------------------------------------------------------------- /R/helper_functions.R: -------------------------------------------------------------------------------- 1 | #' Create a filepath for a referenced VBS file 2 | #' 3 | #' Formats the name of a VBS file to be used 4 | #' @param vbs_file Name of a vbs script file saved as part of the package 5 | #' @name vbs_file_path 6 | #' @title Formats the name of a VBS script file into the filepath within the package 7 | 8 | vbs_file_path <- function(vbs_file){ 9 | ##Get path of VBS script inside package 10 | paste0('"', 11 | system.file("vbs", package = "odsconvertr"), 12 | '/', vbs_file,'"') 13 | } 14 | 15 | 16 | #' Create a filepath for a referenced VBS file 17 | #' 18 | #' Formats the name of a VBS file to be used 19 | #' @param vbs_file Name of a vbs script file saved as part of the package 20 | #' @param ... Arguments to be passed to the specified VBS script 21 | #' @name vbs_execute 22 | #' @title Execute a VBS script including arguments 23 | 24 | vbs_execute <- function(vbs_file, ...){ 25 | 26 | ##Convert arguments into a single string 27 | arguments <- paste(c(...), collapse = " ") 28 | #Create system command for specified vbs file 29 | system_command <- paste("WScript", 30 | vbs_file_path(vbs_file), 31 | arguments, 32 | sep = " ") 33 | #Run specified command 34 | system(command = system_command) 35 | } 36 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Report an error in this code 4 | title: '' 5 | labels: 'bug' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | 22 | 23 | * **Describe the bug** 24 | 25 | A clear and concise description of what the bug is. 26 | 27 | * **Tell us how to reproduce the error** 28 | 29 | Steps to reproduce the behavior: 30 | 1. Go to '...' 31 | 2. Click on '....' 32 | 3. Scroll down to '....' 33 | 4. See error 34 | 35 | * **Expected behavior** 36 | 37 | A clear and concise description of what you expected to happen. 38 | 39 | * **Platform** 40 | 41 | Were you running the code on: 42 | 43 | - [ ] Local R 44 | - [ ] Citrix 45 | - [ ] Non-network laptop 46 | 47 | * **Screenshots** 48 | 49 | If applicable, add screenshots to help explain your problem. 50 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | ## Proposed changes 2 | 3 | Describe the big picture of your changes here to make it clear what your pull request will change. Make sure to explain the **what** e.g. the functionality it changes not the **how** e.g. what code you have written. If it fixes a bug or resolves a feature request, be sure to link to that issue. 4 | 5 | ## Types of changes 6 | 7 | What types of changes does your code introduce? 8 | _Put an `x` in the boxes that apply_ 9 | 10 | - [ ] Bugfix (change which fixes an issue) 11 | - [ ] New feature (change which adds functionality) 12 | - [ ] Documentation Update (change to naming or other documentation) 13 | 14 | ## Checklist 15 | 16 | _Put an `x` in the boxes that apply. You can also fill these out after creating the PR._ 17 | 18 | - [ ] I have added unit tests that prove my fix is effective or that my feature works 19 | - [ ] I have added necessary documentation (if appropriate) 20 | - [ ] I have checked that my changes have not broken any other functionality 21 | - [ ] I have linked to any issues this PR fixes 22 | 23 | ## Points for review 24 | 25 | Add checkboxes here for any specific aspects of your PR you would like to be checked in peer review. If you don't specify anything here, the reviewer will check: 26 | 27 | - [ ] All of your unit tests pass 28 | - [ ] Your code is clear and easy to understand 29 | - [ ] You have documented any new features 30 | - [ ] They can run the code you have written 31 | - [ ] Your changes do not break any other functionality 32 | 33 | ## Who is reviewing this PR? 34 | 35 | Tag your reviewer here to ensure they get a notification! 36 | -------------------------------------------------------------------------------- /README.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | output: github_document 3 | --- 4 | 5 | ```{r setup, include=FALSE} 6 | knitr::opts_chunk$set(echo = FALSE) 7 | ``` 8 | 9 | # odconvertR 10 | 11 | odsconvertR is an R package which allows converting XLSX files to ODS format within R. ODS files are an open format of data table and preferable to XLSX for publication. While some packages within R allow writing directly to an ODS file, they do not allow writing to a template or more complex formatting, limiting how much you can change the appearance of the resulting file. 12 | 13 | This package uses a Visual Basic script (VBS) to save a copy of an existing XLSX file in an ODS format, retaining data structure and all formatting. This is particularly useful for Reproducible Analytical Pipelines for publication of data; nicely formatted and readable ODS data tables can be produced without the need for manual point-and-click steps. 14 | 15 | ## Installation 16 | 17 | You can install odsconvertR with: 18 | 19 | ``` 20 | install.packages("devtools") 21 | devtools::install_github("departmentfortransport/odsconvertr") 22 | ``` 23 | or 24 | 25 | ``` 26 | install.packages("devtools") 27 | devtools::install_git("git://github.com/departmentfortransport/odsconvertr.git") 28 | ``` 29 | 30 | ## Usage 31 | 32 | The package contains a single function ```convert_to_ods```. 33 | 34 | This function takes two arguments: 35 | 36 | ```xlsx_path```: A string containing the path to the existing xlsx file. This can be a relative path (from the working directory) or an absolute path (the full path to the file). Importantly, because the code passes through VBA, you cannot use the ```"../"``` notation to move up in a working directory, you must provide the full file path in this instance. 37 | 38 | ```relative_file_path```: A boolean which indicates whether you have passed a relative or absolute file path to the first argument. By default this is set to TRUE, and expects a relative file path. 39 | 40 | When called, the function will create an ODS file with the same name, in the same location as the XLSX file. The original file will not be deleted. 41 | -------------------------------------------------------------------------------- /R/save_files.R: -------------------------------------------------------------------------------- 1 | #' Uses VBA code to save a copy of an xlsx file to the accessible ODS format, retaining all sheets and formatting. 2 | #' 3 | #' Files converted can be via a relative (from working directory) or absolute (full) file path. In either case, the output ODS file will be returned in the same folder as the XLSX file. 4 | #' @export 5 | #' @param path path to xlsx file; can be either a relative or absolute file path 6 | #' @name convert_to_ods 7 | #' @title Save a copy of an xlsx file as an ods file 8 | #' 9 | convert_to_ods <- function(path){ 10 | 11 | ##Stop if file is not found 12 | if(file.exists(path) == FALSE){ 13 | stop("File not found") 14 | } 15 | 16 | #Stop if file is not an xlsx 17 | if(grepl(".xlsx", path, fixed = TRUE) == FALSE){ 18 | stop("File is not an xlsx file") 19 | } 20 | 21 | ##Convert path to absolute one 22 | xlsx_all <- paste0('"',normalizePath(path), '"') 23 | 24 | ods_all <- gsub(".xlsx", ".ods", xlsx_all, fixed = TRUE) 25 | 26 | 27 | ##Get path of VBS script inside package 28 | vbs_loc <- vbs_file_path('save.vbs') 29 | 30 | 31 | #Run VBS script passing it the file paths 32 | vbs_execute("save.vbs", 33 | xlsx_all, 34 | ods_all) 35 | 36 | } 37 | 38 | #' Uses VBA code to save a copy of an ods file to the easy to use xlsx format, retaining all sheets and formatting. 39 | #' 40 | #' Files converted can be via a relative (from working directory) or absolute (full) file path. In either case, the output ODS file will be returned in the same folder as the XLSX file. 41 | #' @export 42 | #' @param path path to ods file; can be either a relative or absolute file path 43 | #' @name convert_to_xlsx 44 | #' @title Save a copy of an ods file as an xlsx file 45 | #' 46 | convert_to_xlsx <- function(path){ 47 | 48 | ##Stop if file is not found 49 | if(file.exists(path) == FALSE){ 50 | stop("File not found") 51 | } 52 | 53 | #Stop if file is not an xlsx 54 | if(grepl(".ods", path, fixed = TRUE) == FALSE){ 55 | stop("File is not an ods file") 56 | } 57 | ##Convert path to absolute one 58 | ods_all <- paste0('"',normalizePath(path), '"') 59 | 60 | xlsx_all <- gsub(".ods", ".xlsx", ods_all, fixed = TRUE) 61 | 62 | 63 | ##Get path of VBS script inside package 64 | vbs_loc <- vbs_file_path('save.vbs') 65 | 66 | 67 | #Run VBS script passing it the file paths 68 | vbs_execute("save_xlsx.vbs", 69 | ods_all, 70 | xlsx_all) 71 | 72 | } 73 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # odconvertR 3 | 4 | odsconvertR is an R package which allows interconverting between XLSX and ODS formats within R. ODS files are an open format of data table and preferable to XLSX for publication. While some packages within R allow writing directly to an ODS file, they do not allow writing to a template or more complex formatting, limiting how much you can change the appearance of the resulting file. Reading ODS files in R is also complicated and limited, so conversion back to XLSX is also useful for this purpose. 5 | 6 | This package uses a Visual Basic script (VBS) to save a copy of an existing XLSX file in an ODS format (and vice versa), retaining data structure and all formatting. This is particularly useful for Reproducible Analytical Pipelines for publication of data; nicely formatted and readable ODS data tables can be produced without the need for manual point-and-click steps. 7 | 8 | ## Installation 9 | 10 | You can install odsconvertR with: 11 | 12 | install.packages("devtools") 13 | devtools::install_github("department-for-transport-public/odsconvertr") 14 | 15 | ## Usage 16 | 17 | **`convert_to_ods`**: for conversion of XLSX files to ODS 18 | 19 | This function takes one argument: 20 | 21 | `xlsx_path`: A string containing the path to the existing xlsx file. This can be a relative path (from the working directory) or an absolute path (the full path to the file). Importantly, because the code passes through VBA, you cannot use the `"../"` notation to move up in a working directory, you must provide the full file path in this instance. 22 | 23 | When called, the function will create an ODS file with the same name, in the same location as the XLSX file. The original file will not be deleted. 24 | 25 | **`convert_to_xlsx`**: for conversion of ODS files to XLSX 26 | 27 | This function takes one argument: 28 | 29 | `ods_path`: A string containing the path to the existing ods file. This can be a relative path (from the working directory) or an absolute path (the full path to the file). Importantly, because the code passes through VBA, you cannot use the `"../"` notation to move up in a working directory, you must provide the full file path in this instance. 30 | 31 | When called, the function will create an XLSX file with the same name, in the same location as the ODS file. The original file will not be deleted. 32 | 33 | **`evaluate_formulas`**: for evaluating formulas in automatically generated xlsx files. This is useful when an Excel file is created via code with formulas in, and you want to be able to read this in without manually opening the file. 34 | 35 | The function takes a single argument, the filepath of the file. Importantly, because the code passes through VBA, you cannot use the `"../"` notation to move up in a working directory, you must provide the full file path in this instance. 36 | 37 | 38 | --------------------------------------------------------------------------------