├── .github ├── .gitignore ├── workflows │ ├── recheck.yml │ ├── stale.yaml │ ├── test-coverage.yaml │ ├── lint.yaml │ ├── pkgdown.yaml │ ├── R-CMD-check.yaml │ └── pr_commands.yaml ├── ISSUE_TEMPLATE │ ├── feature_request.md │ └── bug_report.md ├── SUPPORT.md └── CONTRIBUTING.md ├── R ├── .gitignore ├── sysdata.rda ├── onUnload.R ├── openxlsx-package.R ├── zzz.R ├── data-fontSizeLookupTables.R ├── chartsheet_class.R ├── utils.R ├── setWindowSize.R ├── writexlsx.R ├── asserts.R ├── sheet_data_class.R └── HyperlinkClass.R ├── src └── .gitignore ├── tests ├── testthat │ ├── .gitignore │ ├── test-fontSizeLookupTables.R │ ├── test-silent_worksheet_entries.R │ ├── test-read_xlsx_random_seed.R │ ├── test-v3_0_0_bugs.R │ ├── test-getCellRefs.R │ ├── test-write-permissions.R │ ├── test-getBaseFont.R │ ├── test-validate_data.R │ ├── test-loading_workbook_unzipped.R │ ├── test-writeDataTable.R │ ├── test-CommentClass.R │ ├── test-protect-worksheet.R │ ├── test-cloneWorksheet.R │ ├── test-protect-workbook.R │ ├── test-activeSheet.R │ ├── test-Worksheet_naming.R │ ├── test-read_write_logicals.R │ ├── test-page_setup.R │ ├── test-setColWidths.R │ ├── test-read_xlsx_correct_sheet.R │ ├── test-build_workbook.R │ ├── test-styles.R │ ├── test-date_time_conversion.R │ ├── test-remove_worksheets.R │ ├── test-fill_merged_cells.R │ ├── test-loading_workbook_tables.R │ ├── test-options.R │ ├── test-saveWorkbook.R │ ├── test-read_sources.R │ ├── test-Workbook_properties.R │ ├── test-worksheet_renaming.R │ ├── test-writeData.R │ ├── test-setWindowSize.R │ ├── test-validate_table_name.R │ └── test-encoding.R └── testthat.R ├── _pkgdown.yml ├── LICENSE ├── man ├── figures │ ├── logo.png │ ├── tableoptions.pdf │ ├── tableoptions.png │ ├── lifecycle-stable.svg │ ├── lifecycle-defunct.svg │ ├── lifecycle-retired.svg │ ├── lifecycle-archived.svg │ ├── lifecycle-maturing.svg │ ├── lifecycle-deprecated.svg │ ├── lifecycle-experimental.svg │ ├── lifecycle-questioning.svg │ └── lifecycle-soft-deprecated.svg ├── int2col.Rd ├── col2int.Rd ├── as_POSIXct_utc.Rd ├── temp_xlsx.Rd ├── all.equal.Rd ├── if_null_then.Rd ├── getCreators.Rd ├── addCreator.Rd ├── getSheetNames.Rd ├── as.character.formula.Rd ├── convertFromExcelRef.Rd ├── getStyles.Rd ├── ungroupRows.Rd ├── setLastModifiedBy.Rd ├── copyWorkbook.Rd ├── ungroupColumns.Rd ├── openxlsxFontSizeLookupTable.Rd ├── getCellRefs.Rd ├── getBaseFont.Rd ├── removeCellMerge.Rd ├── names.Rd ├── getTables.Rd ├── removeComment.Rd ├── removeWorksheet.Rd ├── convertToDate.Rd ├── convertToDateTime.Rd ├── get_worksheet_entries.Rd ├── showGridLines.Rd ├── cloneWorksheet.Rd ├── removeColWidths.Rd ├── activeSheet.Rd ├── removeRowHeights.Rd ├── sheets.Rd ├── sheetVisible.Rd ├── removeFilter.Rd ├── pageBreak.Rd ├── deleteDataColumn.Rd ├── sheetVisibility.Rd ├── replaceStyle.Rd ├── setFooter.Rd ├── setHeader.Rd ├── getDateOrigin.Rd ├── modifyBaseFont.Rd ├── renameWorksheet.Rd ├── deleteData.Rd ├── setWindowSize.Rd ├── addFilter.Rd ├── loadWorkbook.Rd ├── createWorkbook.Rd ├── saveWorkbook.Rd ├── getNamedRegions.Rd ├── openxlsx_options.Rd ├── writeComment.Rd ├── openXL.Rd ├── conditionalFormat.Rd ├── freezePane.Rd ├── groupColumns.Rd ├── auto_heights.Rd ├── removeTable.Rd ├── worksheetOrder.Rd ├── createComment.Rd ├── protectWorkbook.Rd ├── mergeCells.Rd ├── addStyle.Rd ├── NamedRegion.Rd ├── setRowHeights.Rd ├── setColWidths.Rd ├── insertImage.Rd ├── insertPlot.Rd ├── groupRows.Rd ├── openxlsx.Rd ├── dataValidation.Rd ├── protectWorksheet.Rd ├── readWorkbook.Rd ├── makeHyperlinkString.Rd └── setHeaderFooter.Rd ├── inst ├── extdata │ ├── einstein.jpg │ ├── readTest.xlsx │ ├── ColorTabs3.xlsx │ ├── groupTest.xlsx │ ├── inlineStr.xlsx │ ├── loadExample.xlsx │ ├── na_convert.xlsx │ ├── gh_issue_288.xlsx │ ├── namedRegions.xlsx │ ├── namedRegions2.xlsx │ ├── namedRegions3.xlsx │ ├── loadPivotTables.xlsx │ ├── loadThreadComment.xlsx │ ├── read_failure_test.xlsx │ ├── cloneWorksheetExample.xlsx │ ├── nested_grouped_rowscols.xlsx │ ├── cloneEmptyWorksheetExample.xlsx │ ├── silent_worksheet_entries.xlsx │ └── build_font_size_lookup.R └── WORDLIST ├── vignettes └── tableStyles.PNG ├── pkgdown └── favicon │ ├── favicon.ico │ ├── favicon-16x16.png │ ├── favicon-32x32.png │ ├── apple-touch-icon.png │ ├── apple-touch-icon-120x120.png │ ├── apple-touch-icon-152x152.png │ ├── apple-touch-icon-180x180.png │ ├── apple-touch-icon-60x60.png │ └── apple-touch-icon-76x76.png ├── data ├── openxlsxFontSizeLookupTable.rda └── openxlsxFontSizeLookupTableBold.rda ├── codecov.yml ├── .gitignore ├── .Rbuildignore ├── data-raw └── lookupTables.R ├── openxlsx.Rproj ├── .lintr ├── .pre-commit-config.yaml ├── README.md └── NAMESPACE /.github/.gitignore: -------------------------------------------------------------------------------- 1 | *.html 2 | -------------------------------------------------------------------------------- /R/.gitignore: -------------------------------------------------------------------------------- 1 | RcppExports.R 2 | -------------------------------------------------------------------------------- /src/.gitignore: -------------------------------------------------------------------------------- 1 | RcppExports.cpp 2 | -------------------------------------------------------------------------------- /tests/testthat/.gitignore: -------------------------------------------------------------------------------- 1 | Rplots.pdf 2 | -------------------------------------------------------------------------------- /_pkgdown.yml: -------------------------------------------------------------------------------- 1 | development: 2 | mode: auto 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | YEAR: 2014-2025 2 | COPYRIGHT HOLDER: openxlsx authors 3 | -------------------------------------------------------------------------------- /R/sysdata.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ycphs/openxlsx/HEAD/R/sysdata.rda -------------------------------------------------------------------------------- /man/figures/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ycphs/openxlsx/HEAD/man/figures/logo.png -------------------------------------------------------------------------------- /tests/testthat.R: -------------------------------------------------------------------------------- 1 | library(testthat) 2 | library(openxlsx) 3 | 4 | test_check("openxlsx") 5 | -------------------------------------------------------------------------------- /R/onUnload.R: -------------------------------------------------------------------------------- 1 | .onUnload <- function(libpath) { 2 | library.dynam.unload("openxlsx", libpath) 3 | } 4 | -------------------------------------------------------------------------------- /inst/extdata/einstein.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ycphs/openxlsx/HEAD/inst/extdata/einstein.jpg -------------------------------------------------------------------------------- /inst/extdata/readTest.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ycphs/openxlsx/HEAD/inst/extdata/readTest.xlsx -------------------------------------------------------------------------------- /vignettes/tableStyles.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ycphs/openxlsx/HEAD/vignettes/tableStyles.PNG -------------------------------------------------------------------------------- /inst/extdata/ColorTabs3.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ycphs/openxlsx/HEAD/inst/extdata/ColorTabs3.xlsx -------------------------------------------------------------------------------- /inst/extdata/groupTest.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ycphs/openxlsx/HEAD/inst/extdata/groupTest.xlsx -------------------------------------------------------------------------------- /inst/extdata/inlineStr.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ycphs/openxlsx/HEAD/inst/extdata/inlineStr.xlsx -------------------------------------------------------------------------------- /inst/extdata/loadExample.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ycphs/openxlsx/HEAD/inst/extdata/loadExample.xlsx -------------------------------------------------------------------------------- /inst/extdata/na_convert.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ycphs/openxlsx/HEAD/inst/extdata/na_convert.xlsx -------------------------------------------------------------------------------- /man/figures/tableoptions.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ycphs/openxlsx/HEAD/man/figures/tableoptions.pdf -------------------------------------------------------------------------------- /man/figures/tableoptions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ycphs/openxlsx/HEAD/man/figures/tableoptions.png -------------------------------------------------------------------------------- /pkgdown/favicon/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ycphs/openxlsx/HEAD/pkgdown/favicon/favicon.ico -------------------------------------------------------------------------------- /inst/extdata/gh_issue_288.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ycphs/openxlsx/HEAD/inst/extdata/gh_issue_288.xlsx -------------------------------------------------------------------------------- /inst/extdata/namedRegions.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ycphs/openxlsx/HEAD/inst/extdata/namedRegions.xlsx -------------------------------------------------------------------------------- /inst/extdata/namedRegions2.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ycphs/openxlsx/HEAD/inst/extdata/namedRegions2.xlsx -------------------------------------------------------------------------------- /inst/extdata/namedRegions3.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ycphs/openxlsx/HEAD/inst/extdata/namedRegions3.xlsx -------------------------------------------------------------------------------- /inst/extdata/loadPivotTables.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ycphs/openxlsx/HEAD/inst/extdata/loadPivotTables.xlsx -------------------------------------------------------------------------------- /pkgdown/favicon/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ycphs/openxlsx/HEAD/pkgdown/favicon/favicon-16x16.png -------------------------------------------------------------------------------- /pkgdown/favicon/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ycphs/openxlsx/HEAD/pkgdown/favicon/favicon-32x32.png -------------------------------------------------------------------------------- /data/openxlsxFontSizeLookupTable.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ycphs/openxlsx/HEAD/data/openxlsxFontSizeLookupTable.rda -------------------------------------------------------------------------------- /inst/extdata/loadThreadComment.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ycphs/openxlsx/HEAD/inst/extdata/loadThreadComment.xlsx -------------------------------------------------------------------------------- /inst/extdata/read_failure_test.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ycphs/openxlsx/HEAD/inst/extdata/read_failure_test.xlsx -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ycphs/openxlsx/HEAD/pkgdown/favicon/apple-touch-icon.png -------------------------------------------------------------------------------- /R/openxlsx-package.R: -------------------------------------------------------------------------------- 1 | ## usethis namespace: start 2 | #' @importFrom lifecycle deprecate_soft 3 | ## usethis namespace: end 4 | -------------------------------------------------------------------------------- /inst/extdata/cloneWorksheetExample.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ycphs/openxlsx/HEAD/inst/extdata/cloneWorksheetExample.xlsx -------------------------------------------------------------------------------- /data/openxlsxFontSizeLookupTableBold.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ycphs/openxlsx/HEAD/data/openxlsxFontSizeLookupTableBold.rda -------------------------------------------------------------------------------- /inst/extdata/nested_grouped_rowscols.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ycphs/openxlsx/HEAD/inst/extdata/nested_grouped_rowscols.xlsx -------------------------------------------------------------------------------- /inst/extdata/cloneEmptyWorksheetExample.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ycphs/openxlsx/HEAD/inst/extdata/cloneEmptyWorksheetExample.xlsx -------------------------------------------------------------------------------- /inst/extdata/silent_worksheet_entries.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ycphs/openxlsx/HEAD/inst/extdata/silent_worksheet_entries.xlsx -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ycphs/openxlsx/HEAD/pkgdown/favicon/apple-touch-icon-120x120.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ycphs/openxlsx/HEAD/pkgdown/favicon/apple-touch-icon-152x152.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ycphs/openxlsx/HEAD/pkgdown/favicon/apple-touch-icon-180x180.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ycphs/openxlsx/HEAD/pkgdown/favicon/apple-touch-icon-60x60.png -------------------------------------------------------------------------------- /pkgdown/favicon/apple-touch-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ycphs/openxlsx/HEAD/pkgdown/favicon/apple-touch-icon-76x76.png -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | comment: no # do not comment PR with the result 2 | 3 | coverage: 4 | status: 5 | project: false 6 | patch: false 7 | -------------------------------------------------------------------------------- /R/zzz.R: -------------------------------------------------------------------------------- 1 | .onAttach <- function(libname, pkgname) { 2 | op <- options() 3 | toset <- !(names(op.openxlsx) %in% names(op)) 4 | if (any(toset)) { 5 | options(op.openxlsx[toset]) 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /tests/testthat/test-fontSizeLookupTables.R: -------------------------------------------------------------------------------- 1 | test_that("lookup tables dimensions", { 2 | expect_equal(dim(openxlsxFontSizeLookupTable), c(29L, 225L)) 3 | expect_equal(dim(openxlsxFontSizeLookupTableBold), c(29L, 225L)) 4 | }) 5 | -------------------------------------------------------------------------------- /tests/testthat/test-silent_worksheet_entries.R: -------------------------------------------------------------------------------- 1 | context("silent get_worksheet_entries") 2 | 3 | test_that("get_worksheet_entries is silent in reference to string in other sheet", { 4 | fl <- system.file("extdata", "silent_worksheet_entries.xlsx", package = "openxlsx") 5 | wb <- loadWorkbook(fl) 6 | expect_silent(get_worksheet_entries(wb, 1)) 7 | }) 8 | -------------------------------------------------------------------------------- /man/int2col.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/wrappers.R 3 | \name{int2col} 4 | \alias{int2col} 5 | \title{Convert integer to Excel column} 6 | \usage{ 7 | int2col(x) 8 | } 9 | \arguments{ 10 | \item{x}{A numeric vector} 11 | } 12 | \description{ 13 | Converts an integer to an Excel column label. 14 | } 15 | \examples{ 16 | int2col(1:10) 17 | } 18 | -------------------------------------------------------------------------------- /tests/testthat/test-read_xlsx_random_seed.R: -------------------------------------------------------------------------------- 1 | test_that("read_xlsx() does not change random seed", { 2 | rs <- .Random.seed 3 | expect_identical(rs, .Random.seed) 4 | tf <- temp_xlsx() 5 | expect_identical(rs, .Random.seed) 6 | write.xlsx(data.frame(a = 1), tf) 7 | expect_identical(rs, .Random.seed) 8 | read.xlsx(tf) 9 | expect_identical(rs, .Random.seed) 10 | unlink(tf) 11 | }) 12 | -------------------------------------------------------------------------------- /man/col2int.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/wrappers.R 3 | \name{col2int} 4 | \alias{col2int} 5 | \title{Convert Excel column to integer} 6 | \usage{ 7 | col2int(x) 8 | } 9 | \arguments{ 10 | \item{x}{A character vector} 11 | } 12 | \description{ 13 | Converts an Excel column label to an integer. 14 | } 15 | \examples{ 16 | col2int(LETTERS) 17 | } 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .Rproj.user 2 | .Rhistory 3 | .RData 4 | .DS_Store 5 | src/*.o 6 | src/*.so 7 | src/*.dll 8 | src-i386/*.dll 9 | src-i386/*.so 10 | src-i386/*.o 11 | src-i386/*.cpp 12 | src-x64/*.dll 13 | src-x64/*.so 14 | src-x64/*.o 15 | src-x64/*.cpp 16 | Rprof.out 17 | docs/*.* 18 | docs/reference/*.html 19 | docs/ 20 | openxlsx.Rcheck/ 21 | openxlsx*.tar.gz 22 | openxlsx*.tgz 23 | vignettes/*.R 24 | vignettes/*.html -------------------------------------------------------------------------------- /man/as_POSIXct_utc.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/wrappers.R 3 | \name{as_POSIXct_utc} 4 | \alias{as_POSIXct_utc} 5 | \title{Convert to POSIXct with timezone UTC} 6 | \usage{ 7 | as_POSIXct_utc(x) 8 | } 9 | \arguments{ 10 | \item{x}{something as.POSIXct can convert} 11 | } 12 | \description{ 13 | Convert to POSIXct with timezone UTC 14 | } 15 | \keyword{internal} 16 | -------------------------------------------------------------------------------- /R/data-fontSizeLookupTables.R: -------------------------------------------------------------------------------- 1 | #' Font Size Lookup tables 2 | #' 3 | #' Lookup tables for font size 4 | #' 5 | #' @format A data.frame with column names corresponding to font names 6 | #' @examples 7 | #' data(openxlsxFontSizeLookupTable) 8 | #' data(openxlsxFontSizeLookupTableBold) 9 | "openxlsxFontSizeLookupTable" 10 | 11 | #' @rdname openxlsxFontSizeLookupTable 12 | #' @format NULL 13 | "openxlsxFontSizeLookupTableBold" 14 | -------------------------------------------------------------------------------- /man/temp_xlsx.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/utils.R 3 | \name{temp_xlsx} 4 | \alias{temp_xlsx} 5 | \title{helper function to create tempory directory for testing purpose} 6 | \usage{ 7 | temp_xlsx(name = "temp_xlsx") 8 | } 9 | \arguments{ 10 | \item{name}{for the temp file} 11 | } 12 | \description{ 13 | helper function to create tempory directory for testing purpose 14 | } 15 | -------------------------------------------------------------------------------- /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^.*\.Rproj$ 2 | ^\.Rproj\.user$ 3 | cran-comments.md 4 | ^revdep$ 5 | ^.*\.github\* 6 | .travis.yml 7 | .appveyor.yml 8 | .lintr 9 | ^cran-comments\.md$ 10 | ^CRAN-RELEASE$ 11 | ^_pkgdown\.yml$ 12 | ^docs$ 13 | ^pkgdown$ 14 | ^\.travis\.yml$ 15 | ^\.github$ 16 | ^azure-pipelines\.yml$ 17 | ^\.pre-commit-config\.yaml$ 18 | ^img$ 19 | ^openxlsx\.Rcheck$ 20 | ^openxlsx.*\.tar\.gz$ 21 | ^openxlsx.*\.tgz$ 22 | ^data-raw$ 23 | ^codecov.yml$ 24 | ^CRAN-SUBMISSION$ 25 | -------------------------------------------------------------------------------- /tests/testthat/test-v3_0_0_bugs.R: -------------------------------------------------------------------------------- 1 | 2 | 3 | context("v3.0.0 Bug Fixes") 4 | 5 | 6 | 7 | test_that("read.xlsx bug fixes", { 8 | file <- system.file("extdata", "readTest.xlsx", package = "openxlsx") 9 | df <- read.xlsx(file, sheet = 1, rows = 1:2, cols = 1) 10 | expect_equal(df, data.frame("Var1" = TRUE)) 11 | 12 | df <- read.xlsx(file, sheet = 1, rows = 1, cols = 1, colNames = FALSE) 13 | expect_equal(df, data.frame("X1" = "Var1", stringsAsFactors = FALSE)) 14 | }) 15 | -------------------------------------------------------------------------------- /.github/workflows/recheck.yml: -------------------------------------------------------------------------------- 1 | on: 2 | workflow_dispatch: 3 | inputs: 4 | which: 5 | type: choice 6 | description: Which dependents to check 7 | options: 8 | - strong 9 | - most 10 | 11 | name: Reverse dependency check 12 | 13 | jobs: 14 | revdep_check: 15 | name: Reverse check ${{ inputs.which }} dependents 16 | uses: r-devel/recheck/.github/workflows/recheck.yml@v1 17 | with: 18 | which: ${{ inputs.which }} 19 | -------------------------------------------------------------------------------- /data-raw/lookupTables.R: -------------------------------------------------------------------------------- 1 | 2 | openxlsxFontSizeLookupTable <- utils::read.csv("data-raw/openxlsxFontSizeLookupTable.csv") 3 | openxlsxFontSizeLookupTableBold <- utils::read.csv("data-raw/openxlsxFontSizeLookupTableBold.csv") 4 | 5 | usethis::use_data( 6 | openxlsxFontSizeLookupTable, 7 | openxlsxFontSizeLookupTableBold, 8 | internal = TRUE 9 | ) 10 | 11 | # usethis::use_data(openxlsxFontSizeLookupTable, overwrite = TRUE) 12 | # usethis::use_data(openxlsxFontSizeLookupTableBold, overwrite = TRUE) 13 | -------------------------------------------------------------------------------- /man/all.equal.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/wrappers.R 3 | \name{all.equal} 4 | \alias{all.equal} 5 | \alias{all.equal.Workbook} 6 | \title{Check equality of workbooks} 7 | \usage{ 8 | \method{all.equal}{Workbook}(target, current, ...) 9 | } 10 | \arguments{ 11 | \item{target}{A \code{Workbook} object} 12 | 13 | \item{current}{A \code{Workbook} object} 14 | 15 | \item{...}{ignored} 16 | } 17 | \description{ 18 | Check equality of workbooks 19 | } 20 | -------------------------------------------------------------------------------- /man/if_null_then.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/utils.R 3 | \name{if_null_then} 4 | \alias{if_null_then} 5 | \alias{\%||\%} 6 | \title{If NULL then ...} 7 | \usage{ 8 | x \%||\% y 9 | } 10 | \arguments{ 11 | \item{x}{A value to check} 12 | 13 | \item{y}{A value to substitute if x is null} 14 | } 15 | \description{ 16 | Replace NULL 17 | } 18 | \examples{ 19 | \dontrun{ 20 | x <- NULL 21 | x <- x \%||\% "none" 22 | x <- x \%||\% NA 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /openxlsx.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | ProjectId: cf9277f2-97e4-45cd-93e7-a3cd24ebd3cf 3 | 4 | RestoreWorkspace: Default 5 | SaveWorkspace: Default 6 | AlwaysSaveHistory: Default 7 | 8 | EnableCodeIndexing: Yes 9 | UseSpacesForTab: Yes 10 | NumSpacesForTab: 2 11 | Encoding: UTF-8 12 | 13 | RnwWeave: knitr 14 | LaTeX: pdfLaTeX 15 | 16 | BuildType: Package 17 | PackageUseDevtools: Yes 18 | PackageInstallArgs: --no-multiarch --with-keep.source 19 | PackageCheckArgs: --as-cran 20 | PackageRoxygenize: rd,collate,namespace,vignette 21 | -------------------------------------------------------------------------------- /tests/testthat/test-getCellRefs.R: -------------------------------------------------------------------------------- 1 | 2 | 3 | context("Check Cell Ref") 4 | 5 | 6 | 7 | test_that("Provide tests for single getCellRefs", { 8 | expect_equal(getCellRefs(data.frame(1, 2)), "B1") 9 | 10 | 11 | expect_error(getCellRefs(c(1, 2))) 12 | 13 | expect_error(getCellRefs(c(1, "a"))) 14 | }) 15 | 16 | 17 | test_that("Provide tests for multiple getCellRefs", { 18 | expect_equal(getCellRefs(data.frame(1:3, 2:4)), c("B1", "C2", "D3")) 19 | 20 | 21 | 22 | 23 | expect_error(getCellRefs(c(1:2, c("a", "b")))) 24 | }) 25 | -------------------------------------------------------------------------------- /man/getCreators.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/wrappers.R 3 | \name{getCreators} 4 | \alias{getCreators} 5 | \title{Get the names of the authors from the meta data of the file.} 6 | \usage{ 7 | getCreators(wb) 8 | } 9 | \arguments{ 10 | \item{wb}{A workbook object} 11 | } 12 | \value{ 13 | vector of creators 14 | } 15 | \description{ 16 | Just a wrapper of wb$getCreators() 17 | } 18 | \examples{ 19 | 20 | wb <- createWorkbook() 21 | getCreators(wb) 22 | } 23 | \author{ 24 | Philipp Schauberger 25 | } 26 | -------------------------------------------------------------------------------- /man/addCreator.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/wrappers.R 3 | \name{addCreator} 4 | \alias{addCreator} 5 | \title{Add another author to the meta data of the file.} 6 | \usage{ 7 | addCreator(wb, Creator) 8 | } 9 | \arguments{ 10 | \item{wb}{A workbook object} 11 | 12 | \item{Creator}{A string object with the name of the creator} 13 | } 14 | \description{ 15 | Just a wrapper of wb$addCreator() 16 | } 17 | \examples{ 18 | 19 | wb <- createWorkbook() 20 | addCreator(wb, "test") 21 | } 22 | \author{ 23 | Philipp Schauberger 24 | } 25 | -------------------------------------------------------------------------------- /man/getSheetNames.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/wrappers.R 3 | \name{getSheetNames} 4 | \alias{getSheetNames} 5 | \title{Get names of worksheets} 6 | \usage{ 7 | getSheetNames(file) 8 | } 9 | \arguments{ 10 | \item{file}{An xlsx or xlsm file.} 11 | } 12 | \value{ 13 | Character vector of worksheet names. 14 | } 15 | \description{ 16 | Returns the worksheet names within an xlsx file 17 | } 18 | \examples{ 19 | getSheetNames(system.file("extdata", "readTest.xlsx", package = "openxlsx")) 20 | } 21 | \author{ 22 | Alexander Walker 23 | } 24 | -------------------------------------------------------------------------------- /man/as.character.formula.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/writeData.R 3 | \name{as.character.formula} 4 | \alias{as.character.formula} 5 | \title{\code{as.character.formula()}} 6 | \usage{ 7 | \method{as.character}{formula}(x, ...) 8 | } 9 | \arguments{ 10 | \item{x}{object to be coerced or tested.} 11 | 12 | \item{...}{Not implemented} 13 | } 14 | \value{ 15 | \code{base::as.character.default(x)} 16 | } 17 | \description{ 18 | This function exists to prevent conflicts with \code{as.character.formula} methods 19 | from other packages 20 | } 21 | -------------------------------------------------------------------------------- /man/convertFromExcelRef.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/wrappers.R 3 | \name{convertFromExcelRef} 4 | \alias{convertFromExcelRef} 5 | \title{Convert excel column name to integer index} 6 | \usage{ 7 | convertFromExcelRef(col) 8 | } 9 | \arguments{ 10 | \item{col}{An excel column reference} 11 | } 12 | \description{ 13 | Convert excel column name to integer index e.g. "J" to 10 14 | } 15 | \examples{ 16 | convertFromExcelRef("DOG") 17 | convertFromExcelRef("COW") 18 | 19 | ## numbers will be removed 20 | convertFromExcelRef("R22") 21 | } 22 | -------------------------------------------------------------------------------- /tests/testthat/test-write-permissions.R: -------------------------------------------------------------------------------- 1 | 2 | context("error without write permissions") 3 | 4 | test_that("test failed write errors for saveWorkbook", { 5 | 6 | skip_on_cran() 7 | skip_on_ci() 8 | 9 | temp_file <- tempfile() 10 | file.create(temp_file) 11 | Sys.chmod(path = temp_file, mode = "444") 12 | 13 | wb <- createWorkbook() 14 | addWorksheet(wb, "name") 15 | 16 | expect_warning(write.xlsx( 17 | x = cars, file = temp_file, overwrite = TRUE 18 | ), 19 | regexp = "Permission denied" 20 | ) 21 | 22 | unlink(temp_file, recursive = TRUE, force = TRUE) 23 | }) 24 | -------------------------------------------------------------------------------- /man/getStyles.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/wrappers.R 3 | \name{getStyles} 4 | \alias{getStyles} 5 | \title{Returns a list of all styles in the workbook} 6 | \usage{ 7 | getStyles(wb) 8 | } 9 | \arguments{ 10 | \item{wb}{A workbook object} 11 | } 12 | \description{ 13 | Returns list of style objects in the workbook 14 | } 15 | \examples{ 16 | ## load a workbook 17 | wb <- loadWorkbook(file = system.file("extdata", "loadExample.xlsx", package = "openxlsx")) 18 | getStyles(wb)[1:3] 19 | } 20 | \seealso{ 21 | \code{\link[=replaceStyle]{replaceStyle()}} 22 | } 23 | -------------------------------------------------------------------------------- /tests/testthat/test-getBaseFont.R: -------------------------------------------------------------------------------- 1 | test_that("getBaseFont works", { 2 | wb <- createWorkbook() 3 | expect_equal( 4 | getBaseFont(wb), 5 | list( 6 | size = list(val = "11"), 7 | # should this be "#000000"? 8 | colour = list(rgb = "FF000000"), 9 | name = list(val = "Calibri") 10 | ) 11 | ) 12 | 13 | modifyBaseFont(wb, fontSize = 9, fontName = "Arial", fontColour = "red") 14 | expect_equal( 15 | getBaseFont(wb), 16 | list( 17 | size = list(val = "9"), 18 | colour = list(rgb = "FFFF0000"), 19 | name = list(val = "Arial") 20 | ) 21 | ) 22 | }) 23 | -------------------------------------------------------------------------------- /man/ungroupRows.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/wrappers.R 3 | \name{ungroupRows} 4 | \alias{ungroupRows} 5 | \title{Ungroup Rows} 6 | \usage{ 7 | ungroupRows(wb, sheet, rows) 8 | } 9 | \arguments{ 10 | \item{wb}{A workbook object} 11 | 12 | \item{sheet}{A name or index of a worksheet} 13 | 14 | \item{rows}{Indices of rows to ungroup} 15 | } 16 | \description{ 17 | Ungroup a selection of rows 18 | } 19 | \details{ 20 | If row was previously hidden, it will now be shown 21 | } 22 | \seealso{ 23 | \code{\link[=ungroupColumns]{ungroupColumns()}} 24 | } 25 | \author{ 26 | Joshua Sturm 27 | } 28 | -------------------------------------------------------------------------------- /man/setLastModifiedBy.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/wrappers.R 3 | \name{setLastModifiedBy} 4 | \alias{setLastModifiedBy} 5 | \title{Set the author who modified the file last.} 6 | \usage{ 7 | setLastModifiedBy(wb, LastModifiedBy) 8 | } 9 | \arguments{ 10 | \item{wb}{A workbook object} 11 | 12 | \item{LastModifiedBy}{A string object with the name of the LastModifiedBy-User} 13 | } 14 | \description{ 15 | Just a wrapper of wb$changeLastModifiedBy() 16 | } 17 | \examples{ 18 | 19 | wb <- createWorkbook() 20 | setLastModifiedBy(wb, "test") 21 | } 22 | \author{ 23 | Philipp Schauberger 24 | } 25 | -------------------------------------------------------------------------------- /man/copyWorkbook.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/wrappers.R 3 | \name{copyWorkbook} 4 | \alias{copyWorkbook} 5 | \title{Copy a Workbook object.} 6 | \usage{ 7 | copyWorkbook(wb) 8 | } 9 | \arguments{ 10 | \item{wb}{A workbook object} 11 | } 12 | \value{ 13 | Workbook 14 | } 15 | \description{ 16 | Just a wrapper of wb$copy() 17 | } 18 | \examples{ 19 | 20 | wb <- createWorkbook() 21 | wb2 <- wb ## does not create a copy 22 | wb3 <- copyWorkbook(wb) ## wrapper for wb$copy() 23 | 24 | addWorksheet(wb, "Sheet1") ## adds worksheet to both wb and wb2 but not wb3 25 | 26 | names(wb) 27 | names(wb2) 28 | names(wb3) 29 | } 30 | -------------------------------------------------------------------------------- /man/ungroupColumns.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/wrappers.R 3 | \name{ungroupColumns} 4 | \alias{ungroupColumns} 5 | \title{Ungroup Columns} 6 | \usage{ 7 | ungroupColumns(wb, sheet, cols) 8 | } 9 | \arguments{ 10 | \item{wb}{A workbook object} 11 | 12 | \item{sheet}{A name or index of a worksheet} 13 | 14 | \item{cols}{Indices of columns to ungroup} 15 | } 16 | \description{ 17 | Ungroup a selection of columns 18 | } 19 | \details{ 20 | If column was previously hidden, it will now be shown 21 | } 22 | \seealso{ 23 | \code{\link[=ungroupRows]{ungroupRows()}} To ungroup rows 24 | } 25 | \author{ 26 | Joshua Sturm 27 | } 28 | -------------------------------------------------------------------------------- /man/openxlsxFontSizeLookupTable.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/data-fontSizeLookupTables.R 3 | \docType{data} 4 | \name{openxlsxFontSizeLookupTable} 5 | \alias{openxlsxFontSizeLookupTable} 6 | \alias{openxlsxFontSizeLookupTableBold} 7 | \title{Font Size Lookup tables} 8 | \format{ 9 | A data.frame with column names corresponding to font names 10 | } 11 | \usage{ 12 | openxlsxFontSizeLookupTable 13 | 14 | openxlsxFontSizeLookupTableBold 15 | } 16 | \description{ 17 | Lookup tables for font size 18 | } 19 | \examples{ 20 | data(openxlsxFontSizeLookupTable) 21 | data(openxlsxFontSizeLookupTableBold) 22 | } 23 | \keyword{datasets} 24 | -------------------------------------------------------------------------------- /man/getCellRefs.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/wrappers.R 3 | \name{getCellRefs} 4 | \alias{getCellRefs} 5 | \title{Return excel cell coordinates from (x,y) coordinates} 6 | \usage{ 7 | getCellRefs(cellCoords) 8 | } 9 | \arguments{ 10 | \item{cellCoords}{A data.frame with two columns coordinate pairs.} 11 | } 12 | \value{ 13 | Excel alphanumeric cell reference 14 | } 15 | \description{ 16 | Return excel cell coordinates from (x,y) coordinates 17 | } 18 | \examples{ 19 | getCellRefs(data.frame(1, 2)) 20 | # "B1" 21 | getCellRefs(data.frame(1:3, 2:4)) 22 | # "B1" "C2" "D3" 23 | } 24 | \author{ 25 | Philipp Schauberger, Alexander Walker 26 | } 27 | -------------------------------------------------------------------------------- /tests/testthat/test-validate_data.R: -------------------------------------------------------------------------------- 1 | context("Data validation") 2 | 3 | # Basic test workbook ========================================================== 4 | 5 | wb <- createWorkbook() 6 | addWorksheet(wb, "Sheet 1") 7 | addWorksheet(wb, "Sheet 2") 8 | writeDataTable(wb, sheet = 1, x = iris[1:30, ]) 9 | writeData(wb, sheet = 2, x = sample(iris$Sepal.Length, 10)) 10 | 11 | # Unit tests =================================================================== 12 | 13 | test_that("Data validation for lists is performed without warnings", { 14 | expect_invisible( 15 | dataValidation( 16 | wb, 1, col = 1, rows = 2:31, type = "list", value = "'Sheet 2'!$A$1:$A$10" 17 | ) 18 | ) 19 | }) 20 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 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 | -------------------------------------------------------------------------------- /man/getBaseFont.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/wrappers.R 3 | \name{getBaseFont} 4 | \alias{getBaseFont} 5 | \title{Return the workbook default font} 6 | \usage{ 7 | getBaseFont(wb) 8 | } 9 | \arguments{ 10 | \item{wb}{A workbook object} 11 | } 12 | \description{ 13 | Return the workbook default font 14 | 15 | Returns the base font used in the workbook. 16 | } 17 | \examples{ 18 | ## create a workbook 19 | wb <- createWorkbook() 20 | getBaseFont(wb) 21 | 22 | ## modify base font to size 10 Arial Narrow in red 23 | modifyBaseFont(wb, fontSize = 10, fontColour = "#FF0000", fontName = "Arial Narrow") 24 | 25 | getBaseFont(wb) 26 | } 27 | \author{ 28 | Alexander Walker 29 | } 30 | -------------------------------------------------------------------------------- /man/removeCellMerge.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/wrappers.R 3 | \name{removeCellMerge} 4 | \alias{removeCellMerge} 5 | \title{Create a new Workbook object} 6 | \usage{ 7 | removeCellMerge(wb, sheet, cols, rows) 8 | } 9 | \arguments{ 10 | \item{wb}{A workbook object} 11 | 12 | \item{sheet}{A name or index of a worksheet} 13 | 14 | \item{cols}{vector of column indices} 15 | 16 | \item{rows}{vector of row indices} 17 | } 18 | \description{ 19 | Unmerges any merged cells that intersect 20 | with the region specified by, min(cols):max(cols) X min(rows):max(rows) 21 | } 22 | \seealso{ 23 | \code{\link[=mergeCells]{mergeCells()}} 24 | } 25 | \author{ 26 | Alexander Walker 27 | } 28 | -------------------------------------------------------------------------------- /tests/testthat/test-loading_workbook_unzipped.R: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | context("Load Unzipped Workbook Object") 6 | 7 | 8 | test_that("Loading unzipped readTest.xlsx", { 9 | fl <- system.file("extdata", "readTest.xlsx", package = "openxlsx") 10 | wb <- loadWorkbook(fl) 11 | 12 | ## make unzipped file & load 13 | tmp_dir <- file.path(tempdir(), paste(sample(LETTERS, 6), collapse = "")) 14 | if (dir.exists(tmp_dir)) unlink(tmp_dir, recursive = TRUE) 15 | dir.create(tmp_dir) 16 | 17 | unzip(zipfile = fl, exdir = tmp_dir) 18 | wb2 <- loadWorkbook(file = tmp_dir, isUnzipped = TRUE) 19 | 20 | expect_true(all.equal(wb, wb2)) 21 | 22 | unlink(tmp_dir, recursive = TRUE) 23 | }) 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | "" 33 | -------------------------------------------------------------------------------- /man/names.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/wrappers.R 3 | \name{names} 4 | \alias{names} 5 | \alias{names.Workbook} 6 | \alias{names<-.Workbook} 7 | \title{get or set worksheet names} 8 | \usage{ 9 | \method{names}{Workbook}(x) 10 | 11 | \method{names}{Workbook}(x) <- value 12 | } 13 | \arguments{ 14 | \item{x}{A \code{Workbook} object} 15 | 16 | \item{value}{a character vector the same length as wb} 17 | } 18 | \description{ 19 | get or set worksheet names 20 | } 21 | \examples{ 22 | 23 | wb <- createWorkbook() 24 | addWorksheet(wb, "S1") 25 | addWorksheet(wb, "S2") 26 | addWorksheet(wb, "S3") 27 | 28 | names(wb) 29 | names(wb)[[2]] <- "S2a" 30 | names(wb) 31 | names(wb) <- paste("Sheet", 1:3) 32 | } 33 | -------------------------------------------------------------------------------- /man/getTables.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/wrappers.R 3 | \name{getTables} 4 | \alias{getTables} 5 | \title{List Excel tables in a workbook} 6 | \usage{ 7 | getTables(wb, sheet) 8 | } 9 | \arguments{ 10 | \item{wb}{A workbook object} 11 | 12 | \item{sheet}{A name or index of a worksheet} 13 | } 14 | \value{ 15 | character vector of table names on the specified sheet 16 | } 17 | \description{ 18 | List Excel tables in a workbook 19 | } 20 | \examples{ 21 | 22 | wb <- createWorkbook() 23 | addWorksheet(wb, sheetName = "Sheet 1") 24 | writeDataTable(wb, sheet = "Sheet 1", x = iris) 25 | writeDataTable(wb, sheet = 1, x = mtcars, tableName = "mtcars", startCol = 10) 26 | 27 | getTables(wb, sheet = "Sheet 1") 28 | } 29 | -------------------------------------------------------------------------------- /tests/testthat/test-writeDataTable.R: -------------------------------------------------------------------------------- 1 | test_that("writeDataTable() warns about Excel limitations", { 2 | 3 | dt <- data.frame(var = c(1)) 4 | header_255 <- paste(sample(tolower(LETTERS), 255, TRUE), collapse = "") 5 | header_256 <- paste(sample(tolower(LETTERS), 256, TRUE), collapse = "") 6 | 7 | wb <- createWorkbook() 8 | addWorksheet(wb, "sheetA") 9 | addWorksheet(wb, "sheetB") 10 | 11 | expect_warning({ 12 | colnames(dt) <- header_255 13 | writeDataTable(wb, sheet = "sheetA", x = dt) 14 | }, 15 | regexp = NA 16 | ) 17 | 18 | expect_warning({ 19 | colnames(dt) <- header_256 20 | writeDataTable(wb, sheet = "sheetB", x = dt) 21 | }, 22 | regexp = "Column name exceeds 255 chars, possible incompatibility with MS Excel. Index: 1" 23 | ) 24 | }) -------------------------------------------------------------------------------- /tests/testthat/test-CommentClass.R: -------------------------------------------------------------------------------- 1 | test_that("createComment() works", { 2 | # error checking 3 | expect_error(createComment("hi", width = 1), NA) 4 | expect_error(createComment("hi", width = 1L), NA) 5 | expect_error(createComment("hi", width = 1:2), "width") 6 | 7 | expect_error(createComment("hi", height = 1), NA) 8 | expect_error(createComment("hi", height = 1L), NA) 9 | expect_error(createComment("hi", height = 1:2), "height") 10 | 11 | expect_error(createComment("hi", visible = NULL)) 12 | expect_error(createComment("hi", visible = c(TRUE, FALSE)), "visible") 13 | 14 | expect_error(createComment("hi", author = 1)) 15 | expect_error(createComment("hi", author = c("a", "a")), "author") 16 | 17 | expect_s4_class(createComment("hello"), "Comment") 18 | }) 19 | -------------------------------------------------------------------------------- /man/removeComment.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/CommentClass.R 3 | \name{removeComment} 4 | \alias{removeComment} 5 | \title{Remove a comment from a cell} 6 | \usage{ 7 | removeComment(wb, sheet, cols, rows, gridExpand = TRUE) 8 | } 9 | \arguments{ 10 | \item{wb}{A workbook object} 11 | 12 | \item{sheet}{A vector of names or indices of worksheets} 13 | 14 | \item{cols}{Columns to delete comments from} 15 | 16 | \item{rows}{Rows to delete comments from} 17 | 18 | \item{gridExpand}{If \code{TRUE}, all data in rectangle min(rows):max(rows) X min(cols):max(cols) 19 | will be removed.} 20 | } 21 | \description{ 22 | Remove a cell comment from a worksheet 23 | } 24 | \seealso{ 25 | \code{\link[=createComment]{createComment()}} 26 | 27 | \code{\link[=writeComment]{writeComment()}} 28 | } 29 | -------------------------------------------------------------------------------- /man/removeWorksheet.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/wrappers.R 3 | \name{removeWorksheet} 4 | \alias{removeWorksheet} 5 | \title{Remove a worksheet from a workbook} 6 | \usage{ 7 | removeWorksheet(wb, sheet) 8 | } 9 | \arguments{ 10 | \item{wb}{A workbook object} 11 | 12 | \item{sheet}{A name or index of a worksheet} 13 | } 14 | \description{ 15 | Remove a worksheet from a Workbook object 16 | 17 | Remove a worksheet from a workbook 18 | } 19 | \examples{ 20 | ## load a workbook 21 | wb <- loadWorkbook(file = system.file("extdata", "loadExample.xlsx", package = "openxlsx")) 22 | 23 | ## Remove sheet 2 24 | removeWorksheet(wb, 2) 25 | 26 | ## save the modified workbook 27 | \dontrun{ 28 | saveWorkbook(wb, "removeWorksheetExample.xlsx", overwrite = TRUE) 29 | } 30 | } 31 | \author{ 32 | Alexander Walker 33 | } 34 | -------------------------------------------------------------------------------- /man/convertToDate.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/wrappers.R 3 | \name{convertToDate} 4 | \alias{convertToDate} 5 | \title{Convert from excel date number to R Date type} 6 | \usage{ 7 | convertToDate(x, origin = "1900-01-01", ...) 8 | } 9 | \arguments{ 10 | \item{x}{A vector of integers} 11 | 12 | \item{origin}{date. Default value is for Windows Excel 2010} 13 | 14 | \item{...}{additional parameters passed to as.Date()} 15 | } 16 | \description{ 17 | Convert from excel date number to R Date type 18 | } 19 | \details{ 20 | Excel stores dates as number of days from some origin day 21 | } 22 | \examples{ 23 | ## 2014 April 21st to 25th 24 | convertToDate(c(41750, 41751, 41752, 41753, 41754, NA)) 25 | convertToDate(c(41750.2, 41751.99, NA, 41753)) 26 | } 27 | \seealso{ 28 | \code{\link[=writeData]{writeData()}} 29 | } 30 | -------------------------------------------------------------------------------- /man/convertToDateTime.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/wrappers.R 3 | \name{convertToDateTime} 4 | \alias{convertToDateTime} 5 | \title{Convert from excel time number to R POSIXct type.} 6 | \usage{ 7 | convertToDateTime(x, origin = "1900-01-01", ...) 8 | } 9 | \arguments{ 10 | \item{x}{A numeric vector} 11 | 12 | \item{origin}{date. Default value is for Windows Excel 2010} 13 | 14 | \item{...}{Additional parameters passed to as.POSIXct} 15 | } 16 | \description{ 17 | Convert from excel time number to R POSIXct type. 18 | } 19 | \details{ 20 | Excel stores dates as number of days from some origin date 21 | } 22 | \examples{ 23 | ## 2014-07-01, 2014-06-30, 2014-06-29 24 | x <- c(41821.8127314815, 41820.8127314815, NA, 41819, NaN) 25 | convertToDateTime(x) 26 | convertToDateTime(x, tz = "Australia/Perth") 27 | convertToDateTime(x, tz = "UTC") 28 | } 29 | -------------------------------------------------------------------------------- /man/get_worksheet_entries.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/helperFunctions.R 3 | \name{get_worksheet_entries} 4 | \alias{get_worksheet_entries} 5 | \title{Get entries from workbook worksheet} 6 | \usage{ 7 | get_worksheet_entries(wb, sheet) 8 | } 9 | \arguments{ 10 | \item{wb}{workbook} 11 | 12 | \item{sheet}{worksheet} 13 | } 14 | \value{ 15 | vector of strings 16 | } 17 | \description{ 18 | Get all entries from workbook worksheet without xml tags 19 | } 20 | \examples{ 21 | ## Create new workbook 22 | wb <- createWorkbook() 23 | addWorksheet(wb, "Sheet") 24 | sheet <- 1 25 | 26 | ## Write dummy data 27 | writeData(wb, sheet, c("A", "BB", "CCC"), startCol = 2, startRow = 3) 28 | writeData(wb, sheet, c(4, 5), startCol = 4, startRow = 3) 29 | 30 | ## Get text entries 31 | get_worksheet_entries(wb, sheet) 32 | 33 | } 34 | \author{ 35 | David Breuer 36 | } 37 | -------------------------------------------------------------------------------- /.github/workflows/stale.yaml: -------------------------------------------------------------------------------- 1 | # adapted from https://github.com/actions/stale 2 | name: 'Close stale issues and PR' 3 | on: 4 | schedule: 5 | - cron: '11 1 * * 6' 6 | 7 | jobs: 8 | stale: 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/stale@v4 12 | with: 13 | stale-issue-message: 'This issue is stale because it has been open 365 days with no activity. Remove stale label or comment or this will be closed in 7 days.' 14 | stale-pr-message: 'This PR is stale because it has been open 45 days with no activity. Remove stale label or comment or this will be closed in 10 days.' 15 | close-issue-message: 'This issue was closed because it has been stalled for 7 days with no activity.' 16 | exempt-issue-labels: 'blocked,must,should,keep' 17 | days-before-stale: 365 18 | days-before-close: 7 19 | days-before-pr-close: -1 20 | 21 | -------------------------------------------------------------------------------- /.github/workflows/test-coverage.yaml: -------------------------------------------------------------------------------- 1 | # Workflow derived from https://github.com/r-lib/actions/tree/v2/examples 2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help 3 | on: 4 | push: 5 | branches: [main, master, development] 6 | pull_request: 7 | branches: [main, master, development] 8 | 9 | name: test-coverage 10 | 11 | jobs: 12 | test-coverage: 13 | runs-on: ubuntu-latest 14 | env: 15 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 16 | 17 | steps: 18 | - uses: actions/checkout@v2 19 | 20 | - uses: r-lib/actions/setup-r@v2 21 | with: 22 | use-public-rspm: true 23 | 24 | - uses: r-lib/actions/setup-r-dependencies@v2 25 | with: 26 | extra-packages: any::covr 27 | needs: coverage 28 | 29 | - name: Test coverage 30 | run: covr::codecov(quiet = FALSE) 31 | shell: Rscript {0} -------------------------------------------------------------------------------- /tests/testthat/test-protect-worksheet.R: -------------------------------------------------------------------------------- 1 | 2 | 3 | context("Protection") 4 | 5 | 6 | test_that("Protection", { 7 | wb <- createWorkbook() 8 | addWorksheet(wb, "s1") 9 | addWorksheet(wb, "s2") 10 | 11 | 12 | protectWorksheet(wb, sheet = "s1", protect = TRUE, password = "abcdefghij", lockSelectingLockedCells = FALSE, lockSelectingUnlockedCells = FALSE, lockFormattingCells = TRUE, lockFormattingColumns = TRUE, lockPivotTables = TRUE) 13 | 14 | expect_true(wb$worksheets[[1]]$sheetProtection == "") 15 | 16 | protectWorksheet(wb, sheet = "s2", protect = TRUE) 17 | expect_true(wb$worksheets[[2]]$sheetProtection == "") 18 | protectWorksheet(wb, sheet = "s2", protect = FALSE) 19 | expect_true(wb$worksheets[[2]]$sheetProtection == "") 20 | }) 21 | -------------------------------------------------------------------------------- /man/showGridLines.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/wrappers.R 3 | \name{showGridLines} 4 | \alias{showGridLines} 5 | \title{Set worksheet gridlines to show or hide.} 6 | \usage{ 7 | showGridLines(wb, sheet, showGridLines = FALSE) 8 | } 9 | \arguments{ 10 | \item{wb}{A workbook object} 11 | 12 | \item{sheet}{A name or index of a worksheet} 13 | 14 | \item{showGridLines}{A logical. If \code{FALSE}, grid lines are hidden.} 15 | } 16 | \description{ 17 | Set worksheet gridlines to show or hide. 18 | } 19 | \examples{ 20 | wb <- loadWorkbook(file = system.file("extdata", "loadExample.xlsx", package = "openxlsx")) 21 | names(wb) ## list worksheets in workbook 22 | showGridLines(wb, 1, showGridLines = FALSE) 23 | showGridLines(wb, "testing", showGridLines = FALSE) 24 | \dontrun{ 25 | saveWorkbook(wb, "showGridLinesExample.xlsx", overwrite = TRUE) 26 | } 27 | } 28 | \author{ 29 | Alexander Walker 30 | } 31 | -------------------------------------------------------------------------------- /man/figures/lifecycle-stable.svg: -------------------------------------------------------------------------------- 1 | lifecyclelifecyclestablestable -------------------------------------------------------------------------------- /man/cloneWorksheet.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/wrappers.R 3 | \name{cloneWorksheet} 4 | \alias{cloneWorksheet} 5 | \title{Clone a worksheet to a workbook} 6 | \usage{ 7 | cloneWorksheet(wb, sheetName, clonedSheet) 8 | } 9 | \arguments{ 10 | \item{wb}{A Workbook object to attach the new worksheet} 11 | 12 | \item{sheetName}{A name for the new worksheet} 13 | 14 | \item{clonedSheet}{The name of the existing worksheet to be cloned.} 15 | } 16 | \value{ 17 | XML tree 18 | } 19 | \description{ 20 | Clone a worksheet to a Workbook object 21 | } 22 | \examples{ 23 | ## Create a new workbook 24 | wb <- createWorkbook("Fred") 25 | 26 | ## Add 3 worksheets 27 | addWorksheet(wb, "Sheet 1") 28 | cloneWorksheet(wb, "Sheet 2", clonedSheet = "Sheet 1") 29 | 30 | ## Save workbook 31 | \dontrun{ 32 | saveWorkbook(wb, "cloneWorksheetExample.xlsx", overwrite = TRUE) 33 | } 34 | } 35 | \author{ 36 | Reinhold Kainhofer 37 | } 38 | -------------------------------------------------------------------------------- /man/figures/lifecycle-defunct.svg: -------------------------------------------------------------------------------- 1 | lifecyclelifecycledefunctdefunct -------------------------------------------------------------------------------- /man/figures/lifecycle-retired.svg: -------------------------------------------------------------------------------- 1 | lifecyclelifecycleretiredretired -------------------------------------------------------------------------------- /man/figures/lifecycle-archived.svg: -------------------------------------------------------------------------------- 1 | lifecyclelifecyclearchivedarchived -------------------------------------------------------------------------------- /man/figures/lifecycle-maturing.svg: -------------------------------------------------------------------------------- 1 | lifecyclelifecyclematuringmaturing -------------------------------------------------------------------------------- /.github/workflows/lint.yaml: -------------------------------------------------------------------------------- 1 | # Workflow derived from https://github.com/r-lib/actions/tree/v2/examples 2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help 3 | on: 4 | push: 5 | branches: [main, master, development] 6 | pull_request: 7 | branches: [main, master, development] 8 | 9 | name: lint 10 | 11 | permissions: read-all 12 | 13 | jobs: 14 | lint: 15 | runs-on: ubuntu-latest 16 | env: 17 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 18 | steps: 19 | - uses: actions/checkout@v4 20 | 21 | - uses: r-lib/actions/setup-r@v2 22 | with: 23 | use-public-rspm: true 24 | 25 | - uses: r-lib/actions/setup-r-dependencies@v2 26 | with: 27 | extra-packages: any::lintr, local::. 28 | needs: lint 29 | 30 | - name: Lint 31 | run: lintr::lint_package() 32 | shell: Rscript {0} 33 | env: 34 | LINTR_ERROR_ON_LINT: true -------------------------------------------------------------------------------- /man/figures/lifecycle-deprecated.svg: -------------------------------------------------------------------------------- 1 | lifecyclelifecycledeprecateddeprecated -------------------------------------------------------------------------------- /man/removeColWidths.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/wrappers.R 3 | \name{removeColWidths} 4 | \alias{removeColWidths} 5 | \title{Remove column widths from a worksheet} 6 | \usage{ 7 | removeColWidths(wb, sheet, cols) 8 | } 9 | \arguments{ 10 | \item{wb}{A workbook object} 11 | 12 | \item{sheet}{A name or index of a worksheet} 13 | 14 | \item{cols}{Indices of columns to remove custom width (if any) from.} 15 | } 16 | \description{ 17 | Remove column widths from a worksheet 18 | } 19 | \examples{ 20 | ## Create a new workbook 21 | wb <- loadWorkbook(file = system.file("extdata", "loadExample.xlsx", package = "openxlsx")) 22 | 23 | ## remove column widths in columns 1 to 20 24 | removeColWidths(wb, 1, cols = 1:20) 25 | \dontrun{ 26 | saveWorkbook(wb, "removeColWidthsExample.xlsx", overwrite = TRUE) 27 | } 28 | } 29 | \seealso{ 30 | \code{\link[=setColWidths]{setColWidths()}} 31 | } 32 | \author{ 33 | Alexander Walker 34 | } 35 | -------------------------------------------------------------------------------- /man/figures/lifecycle-experimental.svg: -------------------------------------------------------------------------------- 1 | lifecyclelifecycleexperimentalexperimental -------------------------------------------------------------------------------- /man/figures/lifecycle-questioning.svg: -------------------------------------------------------------------------------- 1 | lifecyclelifecyclequestioningquestioning -------------------------------------------------------------------------------- /man/activeSheet.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/wrappers.R 3 | \name{activeSheet} 4 | \alias{activeSheet} 5 | \alias{activeSheet<-} 6 | \title{Get/set active sheet of the workbook} 7 | \usage{ 8 | activeSheet(wb) 9 | 10 | activeSheet(wb) <- value 11 | } 12 | \arguments{ 13 | \item{wb}{A workbook object} 14 | 15 | \item{value}{index of the active sheet or name of the active sheet} 16 | } 17 | \value{ 18 | return the active sheet of the workbook 19 | } 20 | \description{ 21 | Get and set active sheet of the workbook 22 | } 23 | \examples{ 24 | 25 | wb <- createWorkbook() 26 | addWorksheet(wb, sheetName = "S1") 27 | addWorksheet(wb, sheetName = "S2") 28 | addWorksheet(wb, sheetName = "S3") 29 | 30 | activeSheet(wb) # default value is the first sheet active 31 | activeSheet(wb) <- 1 ## active sheet S1 32 | activeSheet(wb) 33 | activeSheet(wb) <- "S2" ## active sheet S2 34 | activeSheet(wb) 35 | } 36 | \author{ 37 | Philipp Schauberger 38 | } 39 | -------------------------------------------------------------------------------- /man/figures/lifecycle-soft-deprecated.svg: -------------------------------------------------------------------------------- 1 | lifecyclelifecyclesoft-deprecatedsoft-deprecated -------------------------------------------------------------------------------- /man/removeRowHeights.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/wrappers.R 3 | \name{removeRowHeights} 4 | \alias{removeRowHeights} 5 | \title{Remove custom row heights from a worksheet} 6 | \usage{ 7 | removeRowHeights(wb, sheet, rows) 8 | } 9 | \arguments{ 10 | \item{wb}{A workbook object} 11 | 12 | \item{sheet}{A name or index of a worksheet} 13 | 14 | \item{rows}{Indices of rows to remove custom height (if any) from.} 15 | } 16 | \description{ 17 | Remove row heights from a worksheet 18 | } 19 | \examples{ 20 | ## Create a new workbook 21 | wb <- loadWorkbook(file = system.file("extdata", "loadExample.xlsx", package = "openxlsx")) 22 | 23 | ## remove any custom row heights in rows 1 to 10 24 | removeRowHeights(wb, 1, rows = 1:10) 25 | \dontrun{ 26 | saveWorkbook(wb, "removeRowHeightsExample.xlsx", overwrite = TRUE) 27 | } 28 | } 29 | \seealso{ 30 | \code{\link[=setRowHeights]{setRowHeights()}} 31 | } 32 | \author{ 33 | Alexander Walker 34 | } 35 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | --- 8 | 9 | **Describe the bug** 10 | A clear and concise description of what the bug is. 11 | 12 | **To Reproduce** 13 | A [minimal reproducible example](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) of either an R script to reproduce the issue or otherwise precise steps to reproduce the behavior: 14 | 1. Go to '...' 15 | 2. Click on '....' 16 | 3. Scroll down to '....' 17 | 4. See error 18 | 19 | **Expected behavior** 20 | A clear and concise description of what you expected to happen. 21 | 22 | **Screenshots** 23 | If applicable, add screenshots to help explain your problem. 24 | 25 | **Example files** 26 | If applicable, add example files to help explain your problem (`openxlsx` and/or `Excel` created files) 27 | 28 | **Additional context** 29 | Add any other context about the problem here. 30 | -------------------------------------------------------------------------------- /tests/testthat/test-cloneWorksheet.R: -------------------------------------------------------------------------------- 1 | 2 | 3 | context("clone Worksheet") 4 | 5 | 6 | test_that("clone Worksheet with data", { 7 | wb <- createWorkbook() 8 | addWorksheet(wb, "Sheet 1") 9 | writeData(wb, "Sheet 1", 1) 10 | cloneWorksheet(wb, "Sheet 2", clonedSheet = "Sheet 1") 11 | 12 | 13 | file_name <- system.file("extdata", "cloneWorksheetExample.xlsx", package = "openxlsx") 14 | refwb <- loadWorkbook(file = file_name) 15 | 16 | expect_equal(sheets(wb), sheets(refwb)) 17 | expect_equal(worksheetOrder(wb), worksheetOrder(refwb)) 18 | }) 19 | 20 | test_that("clone empty Worksheet", { 21 | wb <- createWorkbook() 22 | addWorksheet(wb, "Sheet 1") 23 | 24 | cloneWorksheet(wb, "Sheet 2", clonedSheet = "Sheet 1") 25 | 26 | 27 | file_name <- system.file("extdata", "cloneEmptyWorksheetExample.xlsx", package = "openxlsx") 28 | refwb <- loadWorkbook(file = file_name) 29 | 30 | expect_equal(sheets(wb), sheets(refwb)) 31 | expect_equal(worksheetOrder(wb), worksheetOrder(refwb)) 32 | }) 33 | -------------------------------------------------------------------------------- /man/sheets.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/wrappers.R 3 | \name{sheets} 4 | \alias{sheets} 5 | \title{Returns names of worksheets.} 6 | \usage{ 7 | sheets(wb) 8 | } 9 | \arguments{ 10 | \item{wb}{A workbook object} 11 | } 12 | \value{ 13 | Name of worksheet(s) for a given index 14 | } 15 | \description{ 16 | DEPRECATED. Use names(). 17 | } 18 | \details{ 19 | DEPRECATED. Use \code{\link[=names]{names()}} 20 | } 21 | \examples{ 22 | 23 | ## Create a new workbook 24 | wb <- createWorkbook() 25 | 26 | ## Add some worksheets 27 | addWorksheet(wb, "Worksheet Name") 28 | addWorksheet(wb, "This is worksheet 2") 29 | addWorksheet(wb, "The third worksheet") 30 | 31 | ## Return names of sheets, can not be used for assignment. 32 | names(wb) 33 | # openXL(wb) 34 | 35 | names(wb) <- c("A", "B", "C") 36 | names(wb) 37 | # openXL(wb) 38 | } 39 | \seealso{ 40 | \code{\link[=names]{names()}} to rename a worksheet in a Workbook 41 | } 42 | \author{ 43 | Alexander Walker 44 | } 45 | -------------------------------------------------------------------------------- /man/sheetVisible.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/wrappers.R 3 | \name{sheetVisible} 4 | \alias{sheetVisible} 5 | \alias{sheetVisible<-} 6 | \title{Get worksheet visible state.} 7 | \usage{ 8 | sheetVisible(wb) 9 | 10 | sheetVisible(wb) <- value 11 | } 12 | \arguments{ 13 | \item{wb}{A workbook object} 14 | 15 | \item{value}{a logical vector the same length as sheetVisible(wb)} 16 | } 17 | \value{ 18 | Character vector of worksheet names. 19 | 20 | TRUE if sheet is visible, FALSE if sheet is hidden 21 | } 22 | \description{ 23 | DEPRECATED - Use function 'sheetVisibility() 24 | } 25 | \examples{ 26 | 27 | wb <- createWorkbook() 28 | addWorksheet(wb, sheetName = "S1", visible = FALSE) 29 | addWorksheet(wb, sheetName = "S2", visible = TRUE) 30 | addWorksheet(wb, sheetName = "S3", visible = FALSE) 31 | 32 | sheetVisible(wb) 33 | sheetVisible(wb)[1] <- TRUE ## show sheet 1 34 | sheetVisible(wb)[2] <- FALSE ## hide sheet 2 35 | } 36 | \author{ 37 | Alexander Walker 38 | } 39 | -------------------------------------------------------------------------------- /man/removeFilter.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/wrappers.R 3 | \name{removeFilter} 4 | \alias{removeFilter} 5 | \title{Remove a worksheet filter} 6 | \usage{ 7 | removeFilter(wb, sheet) 8 | } 9 | \arguments{ 10 | \item{wb}{A workbook object} 11 | 12 | \item{sheet}{A vector of names or indices of worksheets} 13 | } 14 | \description{ 15 | Removes filters from addFilter() and writeData() 16 | } 17 | \examples{ 18 | wb <- createWorkbook() 19 | addWorksheet(wb, "Sheet 1") 20 | addWorksheet(wb, "Sheet 2") 21 | addWorksheet(wb, "Sheet 3") 22 | 23 | writeData(wb, 1, iris) 24 | addFilter(wb, 1, row = 1, cols = 1:ncol(iris)) 25 | 26 | ## Equivalently 27 | writeData(wb, 2, x = iris, withFilter = TRUE) 28 | 29 | ## Similarly 30 | writeDataTable(wb, 3, iris) 31 | 32 | ## remove filters 33 | removeFilter(wb, 1:2) ## remove filters 34 | removeFilter(wb, 3) ## Does not affect tables! 35 | \dontrun{ 36 | saveWorkbook(wb, file = "removeFilterExample.xlsx", overwrite = TRUE) 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /.lintr: -------------------------------------------------------------------------------- 1 | linters: linters_with_defaults( 2 | line_length_linter = NULL, # we have many long lines 3 | cyclocomp_linter = NULL, # 4 | commented_code_linter = NULL, # 5 | trailing_whitespace_linter = NULL, # have a few cases 6 | commas_linter = NULL, # 7 | brace_linter = NULL, # 8 | object_name_linter = NULL, # more camel case 9 | infix_spaces_linter = NULL, # 10 | function_left_parentheses_linter = NULL, # 11 | spaces_inside_linter = NULL, # 12 | spaces_left_parentheses_linter = NULL, # 13 | object_length_linter = NULL, # 14 | assignment_linter = NULL, # just one case 15 | vector_logic_linter = NULL, # many 16 | indentation_linter = NULL, # many 17 | quotes_linter = NULL, 18 | T_and_F_symbol_linter = NULL, 19 | seq_linter = NULL, 20 | trailing_blank_lines_linter = NULL, 21 | paren_body_linter = NULL, 22 | semicolon_linter = NULL 23 | ) 24 | -------------------------------------------------------------------------------- /man/pageBreak.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/wrappers.R 3 | \name{pageBreak} 4 | \alias{pageBreak} 5 | \title{add a page break to a worksheet} 6 | \usage{ 7 | pageBreak(wb, sheet, i, type = "row") 8 | } 9 | \arguments{ 10 | \item{wb}{A workbook object} 11 | 12 | \item{sheet}{A name or index of a worksheet} 13 | 14 | \item{i}{row or column number to insert page break.} 15 | 16 | \item{type}{One of "row" or "column" for a row break or column break.} 17 | } 18 | \description{ 19 | insert page breaks into a worksheet 20 | } 21 | \examples{ 22 | wb <- createWorkbook() 23 | addWorksheet(wb, "Sheet 1") 24 | writeData(wb, sheet = 1, x = iris) 25 | 26 | pageBreak(wb, sheet = 1, i = 10, type = "row") 27 | pageBreak(wb, sheet = 1, i = 20, type = "row") 28 | pageBreak(wb, sheet = 1, i = 2, type = "column") 29 | \dontrun{ 30 | saveWorkbook(wb, "pageBreakExample.xlsx", TRUE) 31 | } 32 | ## In Excel: View tab -> Page Break Preview 33 | } 34 | \seealso{ 35 | \code{\link[=addWorksheet]{addWorksheet()}} 36 | } 37 | -------------------------------------------------------------------------------- /tests/testthat/test-protect-workbook.R: -------------------------------------------------------------------------------- 1 | 2 | 3 | context("Protection") 4 | 5 | 6 | test_that("Protect Workbook", { 7 | wb <- createWorkbook() 8 | addWorksheet(wb, "s1") 9 | 10 | wb$protectWorkbook(password = "abcdefghij") 11 | 12 | expect_true(wb$workbook$workbookProtection == "") 13 | 14 | wb$protectWorkbook(protect = FALSE, password = "abcdefghij", lockStructure = TRUE, lockWindows = TRUE) 15 | expect_true(wb$workbook$workbookProtection == "") 16 | }) 17 | 18 | test_that("Reading protected Workbook", { 19 | tmp_file <- file.path(tempdir(), "xlsx_read_protectedwb.xlsx") 20 | 21 | wb <- createWorkbook() 22 | addWorksheet(wb, "s1") 23 | protectWorkbook(wb, password = "abcdefghij") 24 | saveWorkbook(wb, tmp_file, overwrite = TRUE) 25 | 26 | wb2 <- loadWorkbook(file = tmp_file) 27 | # Check that the order of the sub-elements is preserved 28 | n1 <- names(wb2$workbook) 29 | n2 <- names(wb$workbook)[names(wb$workbook) != "apps"] 30 | expect_equal(n1, n2) 31 | 32 | unlink(tmp_file, recursive = TRUE, force = TRUE) 33 | }) 34 | -------------------------------------------------------------------------------- /man/deleteDataColumn.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/wrappers.R 3 | \name{deleteDataColumn} 4 | \alias{deleteDataColumn} 5 | \title{Deletes a whole column from a workbook} 6 | \usage{ 7 | deleteDataColumn(wb, sheet, col) 8 | } 9 | \arguments{ 10 | \item{wb}{A workbook object} 11 | 12 | \item{sheet}{A name or index of a worksheet} 13 | 14 | \item{col}{A column to delete} 15 | } 16 | \description{ 17 | Deletes the whole column from a workbook, shifting the remaining columns to the left 18 | } 19 | \examples{ 20 | ## write some data 21 | wb <- createWorkbook() 22 | addWorksheet(wb, "tester") 23 | 24 | for (i in seq(5)) { 25 | mat <- data.frame(x = rep(paste0(int2col(i), i), 10)) 26 | writeData(wb, sheet = 1, startRow = 1, startCol = i, mat) 27 | writeFormula(wb, sheet = 1, startRow = 12, startCol = i, 28 | x = sprintf("=COUNTA(\%s2:\%s11)", int2col(i), int2col(i))) 29 | } 30 | deleteDataColumn(wb, 1, col = 3) 31 | \dontrun{ 32 | saveWorkbook(wb, "deleteDataColumnExample.xlsx", overwrite = TRUE) 33 | } 34 | } 35 | \author{ 36 | David Zimmermann 37 | } 38 | -------------------------------------------------------------------------------- /man/sheetVisibility.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/wrappers.R 3 | \name{sheetVisibility} 4 | \alias{sheetVisibility} 5 | \alias{sheetVisibility<-} 6 | \title{Get/set worksheet visible state} 7 | \usage{ 8 | sheetVisibility(wb) 9 | 10 | sheetVisibility(wb) <- value 11 | } 12 | \arguments{ 13 | \item{wb}{A workbook object} 14 | 15 | \item{value}{a logical/character vector the same length as sheetVisibility(wb)} 16 | } 17 | \value{ 18 | Character vector of worksheet names. 19 | 20 | Vector of "hidden", "visible", "veryHidden" 21 | } 22 | \description{ 23 | Get and set worksheet visible state 24 | } 25 | \examples{ 26 | 27 | wb <- createWorkbook() 28 | addWorksheet(wb, sheetName = "S1", visible = FALSE) 29 | addWorksheet(wb, sheetName = "S2", visible = TRUE) 30 | addWorksheet(wb, sheetName = "S3", visible = FALSE) 31 | 32 | sheetVisibility(wb) 33 | sheetVisibility(wb)[1] <- TRUE ## show sheet 1 34 | sheetVisibility(wb)[2] <- FALSE ## hide sheet 2 35 | sheetVisibility(wb)[3] <- "hidden" ## hide sheet 3 36 | sheetVisibility(wb)[3] <- "veryHidden" ## hide sheet 3 from UI 37 | } 38 | -------------------------------------------------------------------------------- /man/replaceStyle.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/wrappers.R 3 | \name{replaceStyle} 4 | \alias{replaceStyle} 5 | \title{Replace an existing cell style} 6 | \usage{ 7 | replaceStyle(wb, index, newStyle) 8 | } 9 | \arguments{ 10 | \item{wb}{A workbook object} 11 | 12 | \item{index}{Index of style object to replace} 13 | 14 | \item{newStyle}{A style to replace the existing style as position index} 15 | } 16 | \description{ 17 | Replace an existing cell style 18 | 19 | Replace a style object 20 | } 21 | \examples{ 22 | 23 | ## load a workbook 24 | wb <- loadWorkbook(file = system.file("extdata", "loadExample.xlsx", package = "openxlsx")) 25 | 26 | ## create a new style and replace style 2 27 | 28 | newStyle <- createStyle(fgFill = "#00FF00") 29 | 30 | ## replace style 2 31 | getStyles(wb)[1:3] ## prints styles 32 | replaceStyle(wb, 2, newStyle = newStyle) 33 | 34 | ## Save workbook 35 | \dontrun{ 36 | saveWorkbook(wb, "replaceStyleExample.xlsx", overwrite = TRUE) 37 | } 38 | } 39 | \seealso{ 40 | \code{\link[=getStyles]{getStyles()}} 41 | } 42 | \author{ 43 | Alexander Walker 44 | } 45 | -------------------------------------------------------------------------------- /man/setFooter.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/wrappers.R 3 | \name{setFooter} 4 | \alias{setFooter} 5 | \title{Set footer for all worksheets} 6 | \usage{ 7 | setFooter(wb, text, position = "center") 8 | } 9 | \arguments{ 10 | \item{wb}{A workbook object} 11 | 12 | \item{text}{footer text. A character vector of length 1.} 13 | 14 | \item{position}{Position of text in footer. One of "left", "center" or "right"} 15 | } 16 | \description{ 17 | DEPRECATED 18 | } 19 | \examples{ 20 | \dontrun{ 21 | wb <- createWorkbook("Edgar Anderson") 22 | addWorksheet(wb, "S1") 23 | writeDataTable(wb, "S1", x = iris[1:30, ], xy = c("C", 5)) 24 | 25 | ## set all headers 26 | setHeader(wb, "This is a header", position = "center") 27 | setHeader(wb, "To the left", position = "left") 28 | setHeader(wb, "On the right", position = "right") 29 | 30 | ## set all footers 31 | setFooter(wb, "Center Footer Here", position = "center") 32 | setFooter(wb, "Bottom left", position = "left") 33 | setFooter(wb, Sys.Date(), position = "right") 34 | 35 | saveWorkbook(wb, "headerFooterExample.xlsx", overwrite = TRUE) 36 | } 37 | } 38 | \author{ 39 | Alexander Walker 40 | } 41 | -------------------------------------------------------------------------------- /man/setHeader.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/wrappers.R 3 | \name{setHeader} 4 | \alias{setHeader} 5 | \title{Set header for all worksheets} 6 | \usage{ 7 | setHeader(wb, text, position = "center") 8 | } 9 | \arguments{ 10 | \item{wb}{A workbook object} 11 | 12 | \item{text}{header text. A character vector of length 1.} 13 | 14 | \item{position}{Position of text in header. One of "left", "center" or "right"} 15 | } 16 | \description{ 17 | DEPRECATED 18 | } 19 | \examples{ 20 | \dontrun{ 21 | wb <- createWorkbook("Edgar Anderson") 22 | addWorksheet(wb, "S1") 23 | writeDataTable(wb, "S1", x = iris[1:30, ], xy = c("C", 5)) 24 | 25 | ## set all headers 26 | setHeader(wb, "This is a header", position = "center") 27 | setHeader(wb, "To the left", position = "left") 28 | setHeader(wb, "On the right", position = "right") 29 | 30 | ## set all footers 31 | setFooter(wb, "Center Footer Here", position = "center") 32 | setFooter(wb, "Bottom left", position = "left") 33 | setFooter(wb, Sys.Date(), position = "right") 34 | 35 | saveWorkbook(wb, "headerHeaderExample.xlsx", overwrite = TRUE) 36 | } 37 | } 38 | \author{ 39 | Alexander Walker 40 | } 41 | -------------------------------------------------------------------------------- /man/getDateOrigin.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/wrappers.R 3 | \name{getDateOrigin} 4 | \alias{getDateOrigin} 5 | \title{Get the date origin an xlsx file is using} 6 | \usage{ 7 | getDateOrigin(xlsxFile) 8 | } 9 | \arguments{ 10 | \item{xlsxFile}{An xlsx or xlsm file.} 11 | } 12 | \value{ 13 | One of "1900-01-01" or "1904-01-01". 14 | } 15 | \description{ 16 | Return the date origin used internally by an xlsx or xlsm file 17 | } 18 | \details{ 19 | Excel stores dates as the number of days from either 1904-01-01 or 1900-01-01. This function 20 | checks the date origin being used in an Excel file and returns is so it can be used in \code{\link[=convertToDate]{convertToDate()}} 21 | } 22 | \examples{ 23 | 24 | ## create a file with some dates 25 | \dontrun{ 26 | write.xlsx(as.Date("2015-01-10") - (0:4), file = "getDateOriginExample.xlsx") 27 | m <- read.xlsx("getDateOriginExample.xlsx") 28 | 29 | ## convert to dates 30 | do <- getDateOrigin(system.file("extdata", "readTest.xlsx", package = "openxlsx")) 31 | convertToDate(m[[1]], do) 32 | } 33 | } 34 | \seealso{ 35 | \code{\link[=convertToDate]{convertToDate()}} 36 | } 37 | \author{ 38 | Alexander Walker 39 | } 40 | -------------------------------------------------------------------------------- /man/modifyBaseFont.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/wrappers.R 3 | \name{modifyBaseFont} 4 | \alias{modifyBaseFont} 5 | \title{Modify the default font} 6 | \usage{ 7 | modifyBaseFont(wb, fontSize = 11, fontColour = "black", fontName = "Calibri") 8 | } 9 | \arguments{ 10 | \item{wb}{A workbook object} 11 | 12 | \item{fontSize}{font size} 13 | 14 | \item{fontColour}{font colour} 15 | 16 | \item{fontName}{Name of a font} 17 | } 18 | \description{ 19 | Modify the default font for this workbook 20 | } 21 | \details{ 22 | The font name is not validated in anyway. Excel replaces unknown font names 23 | with Arial. Base font is black, size 11, Calibri. 24 | } 25 | \examples{ 26 | ## create a workbook 27 | wb <- createWorkbook() 28 | addWorksheet(wb, "S1") 29 | ## modify base font to size 10 Arial Narrow in red 30 | modifyBaseFont(wb, fontSize = 10, fontColour = "#FF0000", fontName = "Arial Narrow") 31 | 32 | writeData(wb, "S1", iris) 33 | writeDataTable(wb, "S1", x = iris, startCol = 10) ## font colour does not affect tables 34 | \dontrun{ 35 | saveWorkbook(wb, "modifyBaseFontExample.xlsx", overwrite = TRUE) 36 | } 37 | } 38 | \author{ 39 | Alexander Walker 40 | } 41 | -------------------------------------------------------------------------------- /tests/testthat/test-activeSheet.R: -------------------------------------------------------------------------------- 1 | 2 | context("active Sheet ") 3 | 4 | 5 | test_that("get and set active sheet of a workbook", { 6 | 7 | tempFile1 <- temp_xlsx("temp1") 8 | tempFile2 <- temp_xlsx("temp2") 9 | tempFile3 <- temp_xlsx("temp3") 10 | wbook <- createWorkbook() 11 | addWorksheet(wbook, sheetName = "S1") 12 | addWorksheet(wbook, sheetName = "S2") 13 | addWorksheet(wbook, sheetName = "S3") 14 | 15 | 16 | saveWorkbook(wbook,tempFile1) 17 | # default value is the first sheet active 18 | expect_equal(activeSheet(wbook),1) 19 | expect_equal(activeSheet(wbook),loadWorkbook(tempFile1)$ActiveSheet) 20 | 21 | activeSheet(wbook) <- 1 ## active sheet S1 22 | saveWorkbook(wbook,tempFile2) 23 | expect_equal(activeSheet(wbook),1) 24 | expect_equal(activeSheet(wbook),loadWorkbook(tempFile2)$ActiveSheet) 25 | activeSheet(wbook) <- "S2" ## active sheet S2 26 | saveWorkbook(wbook,tempFile3) 27 | expect_equal(activeSheet(wbook),2) 28 | expect_equal(activeSheet(wbook),loadWorkbook(tempFile3)$ActiveSheet) 29 | 30 | unlink(tempFile1, recursive = TRUE, force = TRUE) 31 | unlink(tempFile2, recursive = TRUE, force = TRUE) 32 | unlink(tempFile3, recursive = TRUE, force = TRUE) 33 | }) 34 | -------------------------------------------------------------------------------- /tests/testthat/test-Worksheet_naming.R: -------------------------------------------------------------------------------- 1 | 2 | context("Worksheet naming") 3 | 4 | test_that("Worksheet names", { 5 | 6 | ### test for names without special character 7 | wb <- createWorkbook() 8 | sheetname <- "test" 9 | addWorksheet(wb, sheetname) 10 | 11 | expect_equal(sheetname,names(wb)) 12 | 13 | ### test for names with & 14 | 15 | wb <- createWorkbook() 16 | sheetname <- "S&P 500" 17 | addWorksheet(wb, sheetname) 18 | 19 | expect_equal(sheetname,names(wb)) 20 | expect_equal("S&P 500",wb$sheet_names) 21 | ### test for names with < 22 | 23 | wb <- createWorkbook() 24 | sheetname <- "<24 h" 25 | addWorksheet(wb, sheetname) 26 | 27 | expect_equal(sheetname,names(wb)) 28 | expect_equal("<24 h",wb$sheet_names) 29 | ### test for names with > 30 | 31 | wb <- createWorkbook() 32 | sheetname <- ">24 h" 33 | addWorksheet(wb, sheetname) 34 | 35 | expect_equal(sheetname,names(wb)) 36 | expect_equal(">24 h",wb$sheet_names) 37 | 38 | ### test for names with " 39 | 40 | wb <- createWorkbook() 41 | sheetname <- 'test "A"' 42 | addWorksheet(wb, sheetname) 43 | 44 | expect_equal(sheetname,names(wb)) 45 | expect_equal("test "A"",wb$sheet_names) 46 | }) 47 | -------------------------------------------------------------------------------- /man/renameWorksheet.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/wrappers.R 3 | \name{renameWorksheet} 4 | \alias{renameWorksheet} 5 | \title{Rename a worksheet} 6 | \usage{ 7 | renameWorksheet(wb, sheet, newName) 8 | } 9 | \arguments{ 10 | \item{wb}{A Workbook object containing a worksheet} 11 | 12 | \item{sheet}{The name or index of the worksheet to rename} 13 | 14 | \item{newName}{The new name of the worksheet. No longer than 31 chars.} 15 | } 16 | \description{ 17 | Rename a worksheet 18 | } 19 | \details{ 20 | DEPRECATED. Use \code{\link[=names]{names()}} 21 | } 22 | \examples{ 23 | 24 | ## Create a new workbook 25 | wb <- createWorkbook("CREATOR") 26 | 27 | ## Add 3 worksheets 28 | addWorksheet(wb, "Worksheet Name") 29 | addWorksheet(wb, "This is worksheet 2") 30 | addWorksheet(wb, "Not the best name") 31 | 32 | #' ## rename all worksheets 33 | names(wb) <- c("A", "B", "C") 34 | 35 | 36 | ## Rename worksheet 1 & 3 37 | renameWorksheet(wb, 1, "New name for sheet 1") 38 | names(wb)[[1]] <- "New name for sheet 1" 39 | names(wb)[[3]] <- "A better name" 40 | 41 | ## Save workbook 42 | \dontrun{ 43 | saveWorkbook(wb, "renameWorksheetExample.xlsx", overwrite = TRUE) 44 | } 45 | } 46 | \author{ 47 | Alexander Walker 48 | } 49 | -------------------------------------------------------------------------------- /man/deleteData.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/wrappers.R 3 | \name{deleteData} 4 | \alias{deleteData} 5 | \title{Delete cell data} 6 | \usage{ 7 | deleteData(wb, sheet, cols, rows, gridExpand = FALSE) 8 | } 9 | \arguments{ 10 | \item{wb}{A workbook object} 11 | 12 | \item{sheet}{A name or index of a worksheet} 13 | 14 | \item{cols}{columns to delete data from.} 15 | 16 | \item{rows}{Rows to delete data from.} 17 | 18 | \item{gridExpand}{If \code{TRUE}, all data in rectangle min(rows):max(rows) X min(cols):max(cols) 19 | will be removed.} 20 | } 21 | \description{ 22 | Delete contents and styling from a cell. 23 | } 24 | \examples{ 25 | ## write some data 26 | wb <- createWorkbook() 27 | addWorksheet(wb, "Worksheet 1") 28 | x <- data.frame(matrix(runif(200), ncol = 10)) 29 | writeData(wb, sheet = 1, x = x, startCol = 2, startRow = 3, colNames = FALSE) 30 | 31 | ## delete some data 32 | deleteData(wb, sheet = 1, cols = 3:5, rows = 5:7, gridExpand = TRUE) 33 | deleteData(wb, sheet = 1, cols = 7:9, rows = 5:7, gridExpand = TRUE) 34 | deleteData(wb, sheet = 1, cols = LETTERS, rows = 18, gridExpand = TRUE) 35 | \dontrun{ 36 | saveWorkbook(wb, "deleteDataExample.xlsx", overwrite = TRUE) 37 | } 38 | } 39 | \author{ 40 | Alexander Walker 41 | } 42 | -------------------------------------------------------------------------------- /man/setWindowSize.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/setWindowSize.R 3 | \name{setWindowSize} 4 | \alias{setWindowSize} 5 | \alias{getWindowSize} 6 | \title{Set and Get Window Size for xlsx file} 7 | \usage{ 8 | setWindowSize( 9 | wb, 10 | xWindow = NULL, 11 | yWindow = NULL, 12 | windowWidth = NULL, 13 | windowHeight = NULL 14 | ) 15 | 16 | getWindowSize(wb) 17 | } 18 | \arguments{ 19 | \item{wb}{A Workbook object} 20 | 21 | \item{xWindow}{the horizontal coordinate of the top left corner of the window} 22 | 23 | \item{yWindow}{the vertical coordinate of the top left corner of the window} 24 | 25 | \item{windowWidth}{the width of the window} 26 | 27 | \item{windowHeight}{the height of the window 28 | 29 | Set the size and position of the window when you open the xlsx file. The units are in twips. See 30 | \href{https://learn.microsoft.com/en-us/dotnet/api/documentformat.openxml.spreadsheet.workbookview?view=openxml-2.8.1}{Microsoft's documentation for the xlsx standard}} 31 | } 32 | \description{ 33 | Set and Get Window Size for xlsx file 34 | } 35 | \examples{ 36 | ## Create Workbook object and add worksheets 37 | wb <- createWorkbook() 38 | addWorksheet(wb, "S1") 39 | getWindowSize(wb) 40 | setWindowSize(wb, windowWidth = 10000) 41 | } 42 | -------------------------------------------------------------------------------- /man/addFilter.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/wrappers.R 3 | \name{addFilter} 4 | \alias{addFilter} 5 | \title{Add column filters} 6 | \usage{ 7 | addFilter(wb, sheet, rows, cols) 8 | } 9 | \arguments{ 10 | \item{wb}{A workbook object} 11 | 12 | \item{sheet}{A name or index of a worksheet} 13 | 14 | \item{rows}{A row number.} 15 | 16 | \item{cols}{columns to add filter to.} 17 | } 18 | \description{ 19 | Add excel column filters to a worksheet 20 | } 21 | \details{ 22 | adds filters to worksheet columns, same as filter parameters in writeData. 23 | writeDataTable automatically adds filters to first row of a table. 24 | NOTE Can only have a single filter per worksheet unless using tables. 25 | } 26 | \examples{ 27 | wb <- createWorkbook() 28 | addWorksheet(wb, "Sheet 1") 29 | addWorksheet(wb, "Sheet 2") 30 | addWorksheet(wb, "Sheet 3") 31 | 32 | writeData(wb, 1, iris) 33 | addFilter(wb, 1, row = 1, cols = 1:ncol(iris)) 34 | 35 | ## Equivalently 36 | writeData(wb, 2, x = iris, withFilter = TRUE) 37 | 38 | ## Similarly 39 | writeDataTable(wb, 3, iris) 40 | \dontrun{ 41 | saveWorkbook(wb, file = "addFilterExample.xlsx", overwrite = TRUE) 42 | } 43 | } 44 | \seealso{ 45 | \code{\link[=writeData]{writeData()}} 46 | 47 | \code{\link[=addFilter]{addFilter()}} 48 | } 49 | -------------------------------------------------------------------------------- /man/loadWorkbook.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/loadWorkbook.R 3 | \name{loadWorkbook} 4 | \alias{loadWorkbook} 5 | \title{Load an existing .xlsx file} 6 | \usage{ 7 | loadWorkbook(file, xlsxFile = NULL, isUnzipped = FALSE, na.convert = TRUE) 8 | } 9 | \arguments{ 10 | \item{file}{A path to an existing .xlsx or .xlsm file} 11 | 12 | \item{xlsxFile}{alias for file} 13 | 14 | \item{isUnzipped}{Set to TRUE if the xlsx file is already unzipped} 15 | 16 | \item{na.convert}{Should empty/blank cells be converted to \code{NA_character_}. Defaults to TRUE.} 17 | } 18 | \value{ 19 | Workbook object. 20 | } 21 | \description{ 22 | loadWorkbook returns a workbook object conserving styles and 23 | formatting of the original .xlsx file. 24 | } 25 | \examples{ 26 | ## load existing workbook from package folder 27 | wb <- loadWorkbook(file = system.file("extdata", "loadExample.xlsx", package = "openxlsx")) 28 | names(wb) # list worksheets 29 | wb ## view object 30 | ## Add a worksheet 31 | addWorksheet(wb, "A new worksheet") 32 | 33 | ## Save workbook 34 | \dontrun{ 35 | saveWorkbook(wb, "loadExample.xlsx", overwrite = TRUE) 36 | } 37 | 38 | } 39 | \seealso{ 40 | \code{\link[=removeWorksheet]{removeWorksheet()}} 41 | } 42 | \author{ 43 | Alexander Walker, Philipp Schauberger 44 | } 45 | -------------------------------------------------------------------------------- /man/createWorkbook.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/wrappers.R 3 | \name{createWorkbook} 4 | \alias{createWorkbook} 5 | \title{Create a new Workbook object} 6 | \usage{ 7 | createWorkbook( 8 | creator = ifelse(.Platform$OS.type == "windows", Sys.getenv("USERNAME"), 9 | Sys.getenv("USER")), 10 | title = NULL, 11 | subject = NULL, 12 | category = NULL 13 | ) 14 | } 15 | \arguments{ 16 | \item{creator}{Creator of the workbook (your name). Defaults to login username} 17 | 18 | \item{title}{Workbook properties title} 19 | 20 | \item{subject}{Workbook properties subject} 21 | 22 | \item{category}{Workbook properties category} 23 | } 24 | \value{ 25 | Workbook object 26 | } 27 | \description{ 28 | Create a new Workbook object 29 | } 30 | \examples{ 31 | ## Create a new workbook 32 | wb <- createWorkbook() 33 | 34 | ## Save workbook to working directory 35 | \dontrun{ 36 | saveWorkbook(wb, file = "createWorkbookExample.xlsx", overwrite = TRUE) 37 | } 38 | 39 | ## Set Workbook properties 40 | wb <- createWorkbook( 41 | creator = "Me", 42 | title = "title here", 43 | subject = "this & that", 44 | category = "something" 45 | ) 46 | } 47 | \seealso{ 48 | \code{\link[=loadWorkbook]{loadWorkbook()}} 49 | 50 | \code{\link[=saveWorkbook]{saveWorkbook()}} 51 | } 52 | \author{ 53 | Alexander Walker 54 | } 55 | -------------------------------------------------------------------------------- /man/saveWorkbook.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/wrappers.R 3 | \name{saveWorkbook} 4 | \alias{saveWorkbook} 5 | \title{save Workbook to file} 6 | \usage{ 7 | saveWorkbook(wb, file, overwrite = FALSE, returnValue = FALSE) 8 | } 9 | \arguments{ 10 | \item{wb}{A Workbook object to write to file} 11 | 12 | \item{file}{A character string naming an xlsx file} 13 | 14 | \item{overwrite}{If \code{TRUE}, overwrite any existing file.} 15 | 16 | \item{returnValue}{If \code{TRUE}, returns \code{TRUE} in case of a success, else \code{FALSE}. 17 | If flag is \code{FALSE}, then no return value is returned.} 18 | } 19 | \description{ 20 | save a Workbook object to file 21 | } 22 | \examples{ 23 | ## Create a new workbook and add a worksheet 24 | wb <- createWorkbook("Creator of workbook") 25 | addWorksheet(wb, sheetName = "My first worksheet") 26 | 27 | ## Save workbook to working directory 28 | \dontrun{ 29 | saveWorkbook(wb, file = "saveWorkbookExample.xlsx", overwrite = TRUE) 30 | } 31 | } 32 | \seealso{ 33 | \code{\link[=createWorkbook]{createWorkbook()}} 34 | 35 | \code{\link[=addWorksheet]{addWorksheet()}} 36 | 37 | \code{\link[=loadWorkbook]{loadWorkbook()}} 38 | 39 | \code{\link[=writeData]{writeData()}} 40 | 41 | \code{\link[=writeDataTable]{writeDataTable()}} 42 | } 43 | \author{ 44 | Alexander Walker, Philipp Schauberger 45 | } 46 | -------------------------------------------------------------------------------- /man/getNamedRegions.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/wrappers.R 3 | \name{getNamedRegions} 4 | \alias{getNamedRegions} 5 | \title{Get named regions} 6 | \usage{ 7 | getNamedRegions(x) 8 | } 9 | \arguments{ 10 | \item{x}{An xlsx file or Workbook object} 11 | } 12 | \description{ 13 | Return a vector of named regions in a xlsx file or 14 | Workbook object 15 | } 16 | \examples{ 17 | ## create named regions 18 | wb <- createWorkbook() 19 | addWorksheet(wb, "Sheet 1") 20 | 21 | ## specify region 22 | writeData(wb, sheet = 1, x = iris, startCol = 1, startRow = 1) 23 | createNamedRegion( 24 | wb = wb, 25 | sheet = 1, 26 | name = "iris", 27 | rows = 1:(nrow(iris) + 1), 28 | cols = 1:ncol(iris) 29 | ) 30 | 31 | 32 | ## using writeData 'name' argument to create a named region 33 | writeData(wb, sheet = 1, x = iris, name = "iris2", startCol = 10) 34 | \dontrun{ 35 | out_file <- tempfile(fileext = ".xlsx") 36 | saveWorkbook(wb, out_file, overwrite = TRUE) 37 | 38 | ## see named regions 39 | getNamedRegions(wb) ## From Workbook object 40 | getNamedRegions(out_file) ## From xlsx file 41 | 42 | ## read named regions 43 | df <- read.xlsx(wb, namedRegion = "iris") 44 | head(df) 45 | 46 | df <- read.xlsx(out_file, namedRegion = "iris2") 47 | head(df) 48 | } 49 | 50 | } 51 | \seealso{ 52 | \code{\link[=createNamedRegion]{createNamedRegion()}} 53 | } 54 | -------------------------------------------------------------------------------- /man/openxlsx_options.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/openxlsx.R 3 | \docType{data} 4 | \name{openxlsx_options} 5 | \alias{openxlsx_options} 6 | \alias{op.openxlsx} 7 | \alias{openxlsx_getOp} 8 | \alias{openxlsx_setOp} 9 | \title{openxlsx Options} 10 | \format{ 11 | An object of class \code{list} of length 34. 12 | } 13 | \usage{ 14 | op.openxlsx 15 | 16 | openxlsx_getOp(x, default = NULL) 17 | 18 | openxlsx_setOp(x, value) 19 | } 20 | \arguments{ 21 | \item{x}{An option name (\code{"openxlsx."} prefix optional)} 22 | 23 | \item{default}{A default value if \code{NULL}} 24 | 25 | \item{value}{The new value for the option (optional if x is a named list)} 26 | } 27 | \description{ 28 | See and get the openxlsx options 29 | } 30 | \details{ 31 | \code{openxlsx_getOp()} retrieves the \code{"openxlsx"} options found in 32 | \code{op.openxlsx}. If none are set (currently \code{NULL}) retrieves the 33 | default option from \code{op.openxlsx}. This will also check that the 34 | intended option is a standard option (listed in \code{op.openxlsx}) and 35 | will provide a warning otherwise. 36 | 37 | \code{openxlsx_setOp()} is a safer way to set an option as it will first 38 | check that the option is a standard option (as above) before setting. 39 | } 40 | \examples{ 41 | openxlsx_getOp("borders") 42 | op.openxlsx[["openxlsx.borders"]] 43 | 44 | } 45 | \keyword{datasets} 46 | -------------------------------------------------------------------------------- /tests/testthat/test-read_write_logicals.R: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | context("Readind and Writing Logicals") 5 | 6 | 7 | 8 | test_that("TRUE, FALSE, NA", { 9 | curr_wd <- getwd() 10 | fileName <- file.path(tempdir(), "T_F_NA.xlsx") 11 | 12 | x <- iris 13 | x$Species <- as.character(x$Species) 14 | x$all_t <- TRUE 15 | x$all_f <- FALSE 16 | x$tf <- sample(c(TRUE, FALSE), size = 150, replace = TRUE) 17 | x$t_na <- sample(c(TRUE, NA), size = 150, replace = TRUE) 18 | x$f_na <- sample(c(FALSE, NA), size = 150, replace = TRUE) 19 | x$tf_na <- sample(c(TRUE, FALSE, NA), size = 150, replace = TRUE) 20 | 21 | wb <- write.xlsx(x, file = fileName, colNames = TRUE) 22 | 23 | y <- read.xlsx(fileName, sheet = 1) 24 | expect_equal(x, y) 25 | 26 | ## T becomes false TRUE and NA exist in a columns 27 | expect_equal(x$t_na, y$t_na) 28 | expect_equal(x$f_na, y$f_na) 29 | 30 | expect_equal(is.na(x$f_na), is.na(y$f_na)) 31 | expect_equal(is.na(x$tf_na), is.na(y$tf_na)) 32 | 33 | ## From Workbook 34 | y <- read.xlsx(wb, sheet = 1) 35 | expect_equal(x, y) 36 | 37 | 38 | ## T becomes false TRUE and NA exist in a columns 39 | expect_equal(x$t_na, y$t_na) 40 | expect_equal(x$f_na, y$f_na) 41 | 42 | expect_equal(is.na(x$f_na), is.na(y$f_na)) 43 | expect_equal(is.na(x$tf_na), is.na(y$tf_na)) 44 | 45 | expect_equal(object = getwd(), curr_wd) 46 | unlink(fileName, recursive = TRUE, force = TRUE) 47 | }) 48 | -------------------------------------------------------------------------------- /tests/testthat/test-page_setup.R: -------------------------------------------------------------------------------- 1 | 2 | 3 | context("Page setup") 4 | 5 | 6 | test_that("Page setup", { 7 | wb <- createWorkbook() 8 | addWorksheet(wb, "s1") 9 | addWorksheet(wb, "s2") 10 | 11 | 12 | pageSetup(wb, 13 | sheet = "s1", orientation = "landscape", scale = 100, left = 0.1, 14 | right = 0.1, top = .75, bottom = .75, header = 0.1, footer = 0.1, 15 | fitToWidth = TRUE, fitToHeight = TRUE, paperSize = 1, 16 | summaryRow = "below", summaryCol = "right" 17 | ) 18 | 19 | 20 | pageSetup(wb, 21 | sheet = 2, orientation = "landscape", scale = 100, left = 0.1, 22 | right = 0.1, top = .75, bottom = .75, header = 0.1, footer = 0.1, 23 | fitToWidth = TRUE, fitToHeight = TRUE, paperSize = 1, 24 | summaryRow = "below", summaryCol = "right" 25 | ) 26 | 27 | expect_equal(wb$worksheets[[1]]$pageSetup, wb$worksheets[[2]]$pageSetup) 28 | 29 | v <- gsub(" ", "", wb$worksheets[[1]]$pageSetup, fixed = TRUE) 30 | expect_true(grepl('paperSize="1"', v)) 31 | expect_true(grepl('orientation="landscape"', v)) 32 | expect_true(grepl('fitToWidth="1"', v)) 33 | expect_true(grepl('fitToHeight="1"', v)) 34 | 35 | pr <- wb$worksheets[[1]]$sheetPr 36 | 37 | # SheetPr will be a character vector of length 2; the first entry will 38 | # be for PageSetupPr, inserted by `fitToWidth`/`fitToHeight`. 39 | expect_true(grepl('', pr[2], fixed = TRUE)) 40 | }) 41 | -------------------------------------------------------------------------------- /tests/testthat/test-setColWidths.R: -------------------------------------------------------------------------------- 1 | 2 | context("Setting column widths") 3 | 4 | test_that("Resetting col widths", { 5 | # Write some data to a workbook object. 6 | wb <- createWorkbook() 7 | addWorksheet(wb, "iris") 8 | writeData(wb, "iris", iris) 9 | 10 | # Set column widths and perform the pre-save operation to prepare col xml 11 | # (typically called by `saveWorkbook()`). 12 | setColWidths(wb, "iris", cols = 1:2, 12) 13 | wb$setColWidths(1) 14 | 15 | # Set column widths again for a different range inclusive of the previous one, 16 | # perform the pre-save operation to prepare col xml, and test for an error 17 | # (reported in https://github.com/ycphs/openxlsx/issues/493). 18 | setColWidths(wb, "iris", cols = 1:5, 15) 19 | expect_error(wb$setColWidths(1), NA) 20 | 21 | # Test that the resulting col xml meets expectations. 22 | expected_col_xml <- c( 23 | "1" = "", 24 | "2" = "", 25 | "3" = "", 26 | "4" = "", 27 | "5" = "" 28 | ) 29 | expect_equal( 30 | wb$worksheets[[1]]$cols, 31 | expected_col_xml 32 | ) 33 | }) 34 | -------------------------------------------------------------------------------- /.github/workflows/pkgdown.yaml: -------------------------------------------------------------------------------- 1 | # Workflow derived from https://github.com/r-lib/actions/tree/v2/examples 2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help 3 | on: 4 | push: 5 | branches: [main, master] 6 | pull_request: 7 | branches: [main, master] 8 | release: 9 | types: [published] 10 | workflow_dispatch: 11 | 12 | name: pkgdown 13 | 14 | jobs: 15 | pkgdown: 16 | runs-on: ubuntu-latest 17 | # Only restrict concurrency for non-PR jobs 18 | concurrency: 19 | group: pkgdown-${{ github.event_name != 'pull_request' || github.run_id }} 20 | env: 21 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 22 | steps: 23 | - uses: actions/checkout@v2 24 | 25 | - uses: r-lib/actions/setup-pandoc@v2 26 | 27 | - uses: r-lib/actions/setup-r@v2 28 | with: 29 | use-public-rspm: true 30 | 31 | - uses: r-lib/actions/setup-r-dependencies@v2 32 | with: 33 | extra-packages: any::pkgdown, local::. 34 | needs: website 35 | 36 | - name: Build site 37 | run: pkgdown::build_site_github_pages(new_process = FALSE, install = FALSE) 38 | shell: Rscript {0} 39 | 40 | - name: Deploy to GitHub pages 🚀 41 | if: github.event_name != 'pull_request' 42 | uses: JamesIves/github-pages-deploy-action@4.1.4 43 | with: 44 | clean: false 45 | branch: gh-pages 46 | folder: docs -------------------------------------------------------------------------------- /man/writeComment.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/CommentClass.R 3 | \name{writeComment} 4 | \alias{writeComment} 5 | \title{write a cell comment} 6 | \usage{ 7 | writeComment(wb, sheet, col, row, comment, xy = NULL) 8 | } 9 | \arguments{ 10 | \item{wb}{A workbook object} 11 | 12 | \item{sheet}{A vector of names or indices of worksheets} 13 | 14 | \item{col}{Column a column number of letter} 15 | 16 | \item{row}{A row number.} 17 | 18 | \item{comment}{A Comment object. See \code{\link[=createComment]{createComment()}}.} 19 | 20 | \item{xy}{An alternative to specifying \code{col} and 21 | \code{row} individually. A vector of the form 22 | \code{c(col, row)}.} 23 | } 24 | \description{ 25 | Write a Comment object to a worksheet 26 | } 27 | \examples{ 28 | wb <- createWorkbook() 29 | addWorksheet(wb, "Sheet 1") 30 | 31 | c1 <- createComment(comment = "this is comment") 32 | writeComment(wb, 1, col = "B", row = 10, comment = c1) 33 | 34 | s1 <- createStyle(fontSize = 12, fontColour = "red", textDecoration = c("BOLD")) 35 | s2 <- createStyle(fontSize = 9, fontColour = "black") 36 | 37 | c2 <- createComment(comment = c("This Part Bold red\n\n", "This part black"), style = c(s1, s2)) 38 | c2 39 | 40 | writeComment(wb, 1, col = 6, row = 3, comment = c2) 41 | \dontrun{ 42 | saveWorkbook(wb, file = "writeCommentExample.xlsx", overwrite = TRUE) 43 | } 44 | } 45 | \seealso{ 46 | \code{\link[=createComment]{createComment()}} 47 | } 48 | -------------------------------------------------------------------------------- /tests/testthat/test-read_xlsx_correct_sheet.R: -------------------------------------------------------------------------------- 1 | 2 | 3 | context("Read xlsx") 4 | 5 | 6 | test_that("read.xlsx correct sheet", { 7 | fl <- system.file("extdata", "readTest.xlsx", package = "openxlsx") 8 | sheet_names <- getSheetNames(file = fl) 9 | 10 | expected_sheet_names <- c( 11 | "Sheet1", "Sheet2", "Sheet 3", 12 | "Sheet 4", "Sheet 5", "Sheet 6", 13 | "1", "11", "111", "1111", "11111", "111111" 14 | ) 15 | 16 | 17 | expect_equal(object = sheet_names, expected = expected_sheet_names) 18 | 19 | expect_equal(read.xlsx(xlsxFile = fl, sheet = 7), data.frame(x = 1)) 20 | expect_equal(read.xlsx(xlsxFile = fl, sheet = 8), data.frame(x = 11)) 21 | expect_equal(read.xlsx(xlsxFile = fl, sheet = 9), data.frame(x = 111)) 22 | expect_equal(read.xlsx(xlsxFile = fl, sheet = 10), data.frame(x = 1111)) 23 | expect_equal(read.xlsx(xlsxFile = fl, sheet = 11), data.frame(x = 11111)) 24 | expect_equal(read.xlsx(xlsxFile = fl, sheet = 12), data.frame(x = 111111)) 25 | 26 | expect_equal(read.xlsx(xlsxFile = fl, sheet = "1"), data.frame(x = 1)) 27 | expect_equal(read.xlsx(xlsxFile = fl, sheet = "11"), data.frame(x = 11)) 28 | expect_equal(read.xlsx(xlsxFile = fl, sheet = "111"), data.frame(x = 111)) 29 | expect_equal(read.xlsx(xlsxFile = fl, sheet = "1111"), data.frame(x = 1111)) 30 | expect_equal(read.xlsx(xlsxFile = fl, sheet = "11111"), data.frame(x = 11111)) 31 | expect_equal(read.xlsx(xlsxFile = fl, sheet = "111111"), data.frame(x = 111111)) 32 | }) 33 | -------------------------------------------------------------------------------- /man/openXL.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/openXL.R 3 | \name{openXL} 4 | \alias{openXL} 5 | \title{Open a Microsoft Excel file (xls/xlsx) or an openxlsx Workbook} 6 | \usage{ 7 | openXL(file=NULL) 8 | } 9 | \arguments{ 10 | \item{file}{path to the Excel (xls/xlsx) file or Workbook object.} 11 | } 12 | \description{ 13 | This function tries to open a Microsoft Excel 14 | (xls/xlsx) file or an openxlsx Workbook with the proper 15 | application, in a portable manner. 16 | 17 | In Windows (c) and Mac (c), it uses system default handlers, 18 | given the file type. 19 | 20 | In Linux it searches (via \code{which}) for available xls/xlsx 21 | reader applications (unless \code{options('openxlsx.excelApp')} 22 | is set to the app bin path), and if it finds anything, sets 23 | \code{options('openxlsx.excelApp')} to the program choosen by 24 | the user via a menu (if many are present, otherwise it will 25 | set the only available). Currently searched for apps are 26 | Libreoffice/Openoffice (\code{soffice} bin), Gnumeric 27 | (\code{gnumeric}) and Calligra Sheets (\code{calligrasheets}). 28 | } 29 | \examples{ 30 | # file example 31 | example(writeData) 32 | # openXL("writeDataExample.xlsx") 33 | 34 | # (not yet saved) Workbook example 35 | wb <- createWorkbook() 36 | x <- mtcars[1:6, ] 37 | addWorksheet(wb, "Cars") 38 | writeData(wb, "Cars", x, startCol = 2, startRow = 3, rowNames = TRUE) 39 | # openXL(wb) 40 | } 41 | \author{ 42 | Luca Braglia 43 | } 44 | -------------------------------------------------------------------------------- /man/conditionalFormat.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/wrappers.R 3 | \name{conditionalFormat} 4 | \alias{conditionalFormat} 5 | \title{Add conditional formatting to cells} 6 | \usage{ 7 | conditionalFormat( 8 | wb, 9 | sheet, 10 | cols, 11 | rows, 12 | rule = NULL, 13 | style = NULL, 14 | type = "expression" 15 | ) 16 | } 17 | \arguments{ 18 | \item{wb}{A workbook object} 19 | 20 | \item{sheet}{A name or index of a worksheet} 21 | 22 | \item{cols}{Columns to apply conditional formatting to} 23 | 24 | \item{rows}{Rows to apply conditional formatting to} 25 | 26 | \item{rule}{The condition under which to apply the formatting or a vector of colours. See examples.} 27 | 28 | \item{style}{A style to apply to those cells that satisfy the rule. A Style object returned from createStyle()} 29 | 30 | \item{type}{Either 'expression', 'colorscale' or 'databar'. If 'expression' the formatting is determined 31 | by a formula. If colorScale cells are coloured based on cell value. See examples.} 32 | } 33 | \description{ 34 | DEPRECATED! USE \code{\link[=conditionalFormatting]{conditionalFormatting()}} 35 | } 36 | \details{ 37 | DEPRECATED! USE \code{\link[=conditionalFormatting]{conditionalFormatting()}} 38 | 39 | Valid operators are "<", "<=", ">", ">=", "==", "!=". See Examples. 40 | Default style given by: createStyle(fontColour = "#9C0006", bgFill = "#FFC7CE") 41 | } 42 | \seealso{ 43 | \code{\link[=createStyle]{createStyle()}} 44 | } 45 | \author{ 46 | Alexander Walker 47 | } 48 | -------------------------------------------------------------------------------- /man/freezePane.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/wrappers.R 3 | \name{freezePane} 4 | \alias{freezePane} 5 | \title{Freeze a worksheet pane} 6 | \usage{ 7 | freezePane( 8 | wb, 9 | sheet, 10 | firstActiveRow = NULL, 11 | firstActiveCol = NULL, 12 | firstRow = FALSE, 13 | firstCol = FALSE 14 | ) 15 | } 16 | \arguments{ 17 | \item{wb}{A workbook object} 18 | 19 | \item{sheet}{A name or index of a worksheet} 20 | 21 | \item{firstActiveRow}{Top row of active region} 22 | 23 | \item{firstActiveCol}{Furthest left column of active region} 24 | 25 | \item{firstRow}{If \code{TRUE}, freezes the first row (equivalent to firstActiveRow = 2)} 26 | 27 | \item{firstCol}{If \code{TRUE}, freezes the first column (equivalent to firstActiveCol = 2)} 28 | } 29 | \description{ 30 | Freeze a worksheet pane 31 | } 32 | \examples{ 33 | ## Create a new workbook 34 | wb <- createWorkbook("Kenshin") 35 | 36 | ## Add some worksheets 37 | addWorksheet(wb, "Sheet 1") 38 | addWorksheet(wb, "Sheet 2") 39 | addWorksheet(wb, "Sheet 3") 40 | addWorksheet(wb, "Sheet 4") 41 | 42 | ## Freeze Panes 43 | freezePane(wb, "Sheet 1", firstActiveRow = 5, firstActiveCol = 3) 44 | freezePane(wb, "Sheet 2", firstCol = TRUE) ## shortcut to firstActiveCol = 2 45 | freezePane(wb, 3, firstRow = TRUE) ## shortcut to firstActiveRow = 2 46 | freezePane(wb, 4, firstActiveRow = 1, firstActiveCol = "D") 47 | 48 | ## Save workbook 49 | \dontrun{ 50 | saveWorkbook(wb, "freezePaneExample.xlsx", overwrite = TRUE) 51 | } 52 | } 53 | \author{ 54 | Alexander Walker 55 | } 56 | -------------------------------------------------------------------------------- /man/groupColumns.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/wrappers.R 3 | \name{groupColumns} 4 | \alias{groupColumns} 5 | \title{Group columns} 6 | \usage{ 7 | groupColumns(wb, sheet, cols, hidden = FALSE, level = -1) 8 | } 9 | \arguments{ 10 | \item{wb}{A workbook object.} 11 | 12 | \item{sheet}{A name or index of a worksheet.} 13 | 14 | \item{cols}{Indices of cols to group. Can be either a vector of indices to 15 | group at the same level or a (named) list of numeric vectors of 16 | indices to create multiple groupings at once. The names of the 17 | entries determine the grouping level. If no names are given, 18 | the \code{level} parameter is used as default.} 19 | 20 | \item{hidden}{Logical vector. If TRUE the grouped columns are hidden. Defaults to FALSE.} 21 | 22 | \item{level}{Grouping level (higher value indicates multiple nestings) for the 23 | group. A vector to assign different grouping levels to the indices. 24 | A value of -1 indicates that the grouping level should be derived 25 | from the existing grouping (one level added)} 26 | } 27 | \description{ 28 | Group a selection of columns 29 | } 30 | \details{ 31 | Group columns together, with the option to hide them. 32 | 33 | NOTE: \code{\link[=setColWidths]{setColWidths()}} has a conflicting \code{hidden} parameter; changing one will update the other. 34 | } 35 | \seealso{ 36 | \code{\link[=ungroupColumns]{ungroupColumns()}} to ungroup columns. \code{\link[=groupRows]{groupRows()}} for grouping rows. 37 | } 38 | \author{ 39 | Joshua Sturm, Reinhold Kainhofer 40 | } 41 | -------------------------------------------------------------------------------- /tests/testthat/test-build_workbook.R: -------------------------------------------------------------------------------- 1 | test_that("buildWorkbook() accepts tableName [187]", { 2 | x <- data.frame(a = 1, b = 2) 3 | 4 | # default name 5 | wb <- buildWorkbook(x, asTable = TRUE) 6 | expect_equal(attr(wb$tables, "tableName"), "Table3") 7 | 8 | # define 1/2 table name 9 | wb <- buildWorkbook(x, asTable = TRUE, tableName = "table_x") 10 | expect_equal(attr(wb$tables, "tableName"), "table_x") 11 | 12 | # define 2/2 table names 13 | wb <- buildWorkbook(list(x, x), asTable = TRUE, tableName = c("table_x", "table_y")) 14 | expect_equal(attr(wb$tables, "tableName"), c("table_x", "table_y")) 15 | 16 | # try to define 1/2 table names 17 | expect_error(buildWorkbook(list(x, x), asTable = TRUE, tableName = "table_x")) 18 | }) 19 | 20 | test_that("row.name and col.name are deprecated", { 21 | x <- data.frame(a = 1) 22 | 23 | expect_warning( 24 | buildWorkbook(x, file = temp_xlsx(), row.names = TRUE, overwrite = TRUE), 25 | "Please use 'rowNames' instead of 'row.names'" 26 | ) 27 | 28 | expect_warning( 29 | buildWorkbook(x, file = temp_xlsx(), row.names = TRUE, overwrite = TRUE, asTable = TRUE), 30 | "Please use 'rowNames' instead of 'row.names'" 31 | ) 32 | 33 | expect_warning( 34 | buildWorkbook(x, file = temp_xlsx(), col.names = TRUE, overwrite = TRUE), 35 | "Please use 'colNames' instead of 'col.names'" 36 | ) 37 | 38 | expect_warning( 39 | buildWorkbook(x, file = temp_xlsx(), col.names = TRUE, overwrite = TRUE, asTable = TRUE), 40 | "Please use 'colNames' instead of 'col.names'" 41 | ) 42 | }) 43 | -------------------------------------------------------------------------------- /man/auto_heights.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/helperFunctions.R 3 | \name{auto_heights} 4 | \alias{auto_heights} 5 | \title{Compute optimal row heights} 6 | \usage{ 7 | auto_heights( 8 | wb, 9 | sheet, 10 | selected, 11 | fontsize = NULL, 12 | factor = 1, 13 | base_height = 15, 14 | extra_height = 12 15 | ) 16 | } 17 | \arguments{ 18 | \item{wb}{workbook} 19 | 20 | \item{sheet}{worksheet} 21 | 22 | \item{selected}{selected rows} 23 | 24 | \item{fontsize}{font size, optional (get base font size by default)} 25 | 26 | \item{factor}{factor to manually adjust font width, e.g., for bold fonts, 27 | optional} 28 | 29 | \item{base_height}{basic row height, optional} 30 | 31 | \item{extra_height}{additional row height per new line of text, optional} 32 | } 33 | \value{ 34 | list of indices of columns with fixed widths and optimal row heights 35 | } 36 | \description{ 37 | Compute optimal row heights for cell with fixed with and 38 | enabled automatic row heights parameter 39 | } 40 | \examples{ 41 | ## Create new workbook 42 | wb <- createWorkbook() 43 | addWorksheet(wb, "Sheet") 44 | sheet <- 1 45 | 46 | ## Write dummy data 47 | long_string <- "ABC ABC ABC ABC ABC ABC ABC ABC ABC ABC ABC" 48 | writeData(wb, sheet, c("A", long_string, "CCC"), startCol = 2, startRow = 3) 49 | writeData(wb, sheet, c(4, 5), startCol = 4, startRow = 3) 50 | 51 | ## Set column widths and get optimal row heights 52 | setColWidths(wb, sheet, c(1,2,3,4), c(10,20,10,20)) 53 | auto_heights(wb, sheet, 1:5) 54 | 55 | } 56 | \author{ 57 | David Breuer 58 | } 59 | -------------------------------------------------------------------------------- /tests/testthat/test-styles.R: -------------------------------------------------------------------------------- 1 | 2 | context("Styles") 3 | 4 | test_that("setStyle", { 5 | 6 | tmp_file <- temp_xlsx() 7 | 8 | # lorem ipsum 9 | txt <- paste0( 10 | "Lorem ipsum dolor sit amet, consectetur adipiscing elit, ", 11 | "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. ", 12 | "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris", 13 | "nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in ", 14 | "reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla", 15 | "pariatur. Excepteur sint occaecat cupidatat non proident, sunt in ", 16 | "culpa qui officia deserunt mollit anim id est laborum." 17 | ) 18 | 19 | ## create workbook 20 | wb <- createWorkbook() 21 | addWorksheet(wb, "Test") 22 | writeData(wb, "Test", txt) 23 | 24 | ## create a style 25 | s <- createStyle( 26 | fontSize = 12, 27 | fontColour = "black", 28 | valign="center", 29 | wrapText = TRUE, 30 | halign = "justify" 31 | ) 32 | addStyle(wb, "Test", s, 1, 1) 33 | setColWidths(wb, "Test", 1, 50) 34 | setRowHeights(wb, "Test", 1, 150) 35 | 36 | ## save workbook 37 | saveWorkbook(wb, tmp_file) 38 | 39 | ## load it again 40 | wb2 <- loadWorkbook(tmp_file) 41 | s2 <- getStyles(wb2)[[1]] 42 | 43 | ## test that the style survived the round trip 44 | expect_equal(s2$fontSize, c(val="12")) 45 | expect_equal(s2$fontColour, c(rgb="FF000000")) 46 | expect_equal(s2$valign, "center") 47 | expect_equal(s2$wrapText, TRUE) 48 | expect_equal(s2$halign, "justify") 49 | 50 | }) 51 | -------------------------------------------------------------------------------- /man/removeTable.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/wrappers.R 3 | \name{removeTable} 4 | \alias{removeTable} 5 | \title{Remove an Excel table in a workbook} 6 | \usage{ 7 | removeTable(wb, sheet, table) 8 | } 9 | \arguments{ 10 | \item{wb}{A workbook object} 11 | 12 | \item{sheet}{A name or index of a worksheet} 13 | 14 | \item{table}{Name of table to remove. See \code{\link[=getTables]{getTables()}}} 15 | } 16 | \value{ 17 | character vector of table names on the specified sheet 18 | } 19 | \description{ 20 | List Excel tables in a workbook 21 | } 22 | \examples{ 23 | 24 | wb <- createWorkbook() 25 | addWorksheet(wb, sheetName = "Sheet 1") 26 | addWorksheet(wb, sheetName = "Sheet 2") 27 | writeDataTable(wb, sheet = "Sheet 1", x = iris, tableName = "iris") 28 | writeDataTable(wb, sheet = 1, x = mtcars, tableName = "mtcars", startCol = 10) 29 | 30 | 31 | removeWorksheet(wb, sheet = 1) ## delete worksheet removes table objects 32 | 33 | writeDataTable(wb, sheet = 1, x = iris, tableName = "iris") 34 | writeDataTable(wb, sheet = 1, x = mtcars, tableName = "mtcars", startCol = 10) 35 | 36 | ## removeTable() deletes table object and all data 37 | getTables(wb, sheet = 1) 38 | removeTable(wb = wb, sheet = 1, table = "iris") 39 | writeDataTable(wb, sheet = 1, x = iris, tableName = "iris", startCol = 1) 40 | 41 | getTables(wb, sheet = 1) 42 | removeTable(wb = wb, sheet = 1, table = "iris") 43 | writeDataTable(wb, sheet = 1, x = iris, tableName = "iris", startCol = 1) 44 | \dontrun{ 45 | saveWorkbook(wb = wb, file = "removeTableExample.xlsx", overwrite = TRUE) 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /man/worksheetOrder.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/wrappers.R 3 | \name{worksheetOrder} 4 | \alias{worksheetOrder} 5 | \alias{worksheetOrder<-} 6 | \title{Order of worksheets in xlsx file} 7 | \usage{ 8 | worksheetOrder(wb) 9 | 10 | worksheetOrder(wb) <- value 11 | } 12 | \arguments{ 13 | \item{wb}{A workbook object} 14 | 15 | \item{value}{Vector specifying order to write worksheets to file} 16 | } 17 | \description{ 18 | Get/set order of worksheets in a Workbook object 19 | } 20 | \details{ 21 | This function does not reorder the worksheets within the workbook object, it simply 22 | shuffles the order when writing to file. 23 | } 24 | \examples{ 25 | ## setup a workbook with 3 worksheets 26 | wb <- createWorkbook() 27 | addWorksheet(wb = wb, sheetName = "Sheet 1", gridLines = FALSE) 28 | writeDataTable(wb = wb, sheet = 1, x = iris) 29 | 30 | addWorksheet(wb = wb, sheetName = "mtcars (Sheet 2)", gridLines = FALSE) 31 | writeData(wb = wb, sheet = 2, x = mtcars) 32 | 33 | addWorksheet(wb = wb, sheetName = "Sheet 3", gridLines = FALSE) 34 | writeData(wb = wb, sheet = 3, x = Formaldehyde) 35 | 36 | worksheetOrder(wb) 37 | names(wb) 38 | worksheetOrder(wb) <- c(1, 3, 2) # switch position of sheets 2 & 3 39 | writeData(wb, 2, 'This is still the "mtcars" worksheet', startCol = 15) 40 | worksheetOrder(wb) 41 | names(wb) ## ordering within workbook is not changed 42 | \dontrun{ 43 | saveWorkbook(wb, "worksheetOrderExample.xlsx", overwrite = TRUE) 44 | } 45 | worksheetOrder(wb) <- c(3, 2, 1) 46 | \dontrun{ 47 | saveWorkbook(wb, "worksheetOrderExample2.xlsx", overwrite = TRUE) 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /man/createComment.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/CommentClass.R 3 | \name{createComment} 4 | \alias{createComment} 5 | \title{create a Comment object} 6 | \usage{ 7 | createComment( 8 | comment, 9 | author = Sys.getenv("USERNAME"), 10 | style = NULL, 11 | visible = TRUE, 12 | width = 2, 13 | height = 4 14 | ) 15 | } 16 | \arguments{ 17 | \item{comment}{Comment text. Character vector.} 18 | 19 | \item{author}{Author of comment. Character vector of length 1} 20 | 21 | \item{style}{A Style object or list of style objects the same length as comment vector. See \code{\link[=createStyle]{createStyle()}}.} 22 | 23 | \item{visible}{TRUE or FALSE. Is comment visible.} 24 | 25 | \item{width, height}{Width and height of textbook (in number of cells); 26 | doubles are rounded with \code{base::round()}} 27 | } 28 | \description{ 29 | Create a cell Comment object to pass to writeComment() 30 | } 31 | \examples{ 32 | wb <- createWorkbook() 33 | addWorksheet(wb, "Sheet 1") 34 | 35 | c1 <- createComment(comment = "this is comment") 36 | writeComment(wb, 1, col = "B", row = 10, comment = c1) 37 | 38 | s1 <- createStyle(fontSize = 12, fontColour = "red", textDecoration = c("BOLD")) 39 | s2 <- createStyle(fontSize = 9, fontColour = "black") 40 | 41 | c2 <- createComment(comment = c("This Part Bold red\n\n", "This part black"), style = c(s1, s2)) 42 | c2 43 | 44 | writeComment(wb, 1, col = 6, row = 3, comment = c2) 45 | \dontrun{ 46 | saveWorkbook(wb, file = "createCommentExample.xlsx", overwrite = TRUE) 47 | } 48 | } 49 | \seealso{ 50 | \code{\link[=writeComment]{writeComment()}} 51 | } 52 | -------------------------------------------------------------------------------- /man/protectWorkbook.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/wrappers.R 3 | \name{protectWorkbook} 4 | \alias{protectWorkbook} 5 | \title{Protect a workbook from modifications} 6 | \usage{ 7 | protectWorkbook( 8 | wb, 9 | protect = TRUE, 10 | password = NULL, 11 | lockStructure = FALSE, 12 | lockWindows = FALSE, 13 | type = 1L 14 | ) 15 | } 16 | \arguments{ 17 | \item{wb}{A workbook object} 18 | 19 | \item{protect}{Whether to protect or unprotect the sheet (default=TRUE)} 20 | 21 | \item{password}{(optional) password required to unprotect the workbook} 22 | 23 | \item{lockStructure}{Whether the workbook structure should be locked} 24 | 25 | \item{lockWindows}{Whether the window position of the spreadsheet should be locked} 26 | 27 | \item{type}{Lock type, default 1. From the xml documentation: 1 - Document is password protected. 2 - Document is recommended to be opened as read-only. 4 - Document is enforced to be opened as read-only. 8 - Document is locked for annotation.} 28 | } 29 | \description{ 30 | Protect or unprotect a workbook from modifications by the user in the graphical user interface. Replaces an existing protection. 31 | } 32 | \examples{ 33 | wb <- createWorkbook() 34 | addWorksheet(wb, "S1") 35 | protectWorkbook(wb, protect = TRUE, password = "Password", lockStructure = TRUE) 36 | \dontrun{ 37 | saveWorkbook(wb, "WorkBook_Protection.xlsx", overwrite = TRUE) 38 | } 39 | # Remove the protection 40 | protectWorkbook(wb, protect = FALSE) 41 | \dontrun{ 42 | saveWorkbook(wb, "WorkBook_Protection_unprotected.xlsx", overwrite = TRUE) 43 | } 44 | } 45 | \author{ 46 | Reinhold Kainhofer 47 | } 48 | -------------------------------------------------------------------------------- /.github/workflows/R-CMD-check.yaml: -------------------------------------------------------------------------------- 1 | # Workflow derived from https://github.com/r-lib/actions/tree/v2/examples 2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help 3 | on: 4 | push: 5 | branches: [main, master, development] 6 | pull_request: 7 | branches: [main, master, development] 8 | 9 | name: R-CMD-check 10 | 11 | permissions: read-all 12 | 13 | jobs: 14 | R-CMD-check: 15 | runs-on: ${{ matrix.config.os }} 16 | 17 | name: ${{ matrix.config.os }} (${{ matrix.config.r }}) 18 | 19 | strategy: 20 | fail-fast: false 21 | matrix: 22 | config: 23 | - {os: macos-latest, r: 'release'} 24 | - {os: windows-latest, r: 'release'} 25 | - {os: ubuntu-latest, r: 'devel', http-user-agent: 'release'} 26 | - {os: ubuntu-latest, r: 'release'} 27 | - {os: ubuntu-latest, r: 'oldrel-1'} 28 | 29 | env: 30 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 31 | R_KEEP_PKG_SOURCE: yes 32 | 33 | steps: 34 | - uses: actions/checkout@v4 35 | 36 | - uses: r-lib/actions/setup-pandoc@v2 37 | 38 | - uses: r-lib/actions/setup-r@v2 39 | with: 40 | r-version: ${{ matrix.config.r }} 41 | http-user-agent: ${{ matrix.config.http-user-agent }} 42 | use-public-rspm: true 43 | 44 | - uses: r-lib/actions/setup-r-dependencies@v2 45 | with: 46 | extra-packages: any::rcmdcheck 47 | needs: check 48 | 49 | - uses: r-lib/actions/check-r-package@v2 50 | with: 51 | upload-snapshots: true 52 | build_args: 'c("--no-manual","--compact-vignettes=gs+qpdf")' -------------------------------------------------------------------------------- /R/chartsheet_class.R: -------------------------------------------------------------------------------- 1 | 2 | 3 | #' @include class_definitions.R 4 | 5 | 6 | ChartSheet$methods(initialize = function(tabSelected = FALSE, 7 | tabColour = character(0), 8 | zoom = 100) { 9 | if (length(tabColour) > 0) { 10 | tabColour <- sprintf("%s", tabColour) 11 | } else { 12 | tabColour <- character(0) 13 | } 14 | if (zoom < 10) { 15 | zoom <- 10 16 | } else if (zoom > 400) { 17 | zoom <- 400 18 | } 19 | 20 | sheetPr <<- tabColour 21 | sheetViews <<- sprintf('', as.integer(zoom), as.integer(tabSelected)) 22 | pageMargins <<- '' 23 | drawing <<- '' 24 | hyperlinks <<- character(0) 25 | 26 | return(invisible(0)) 27 | }) 28 | 29 | 30 | 31 | 32 | 33 | ChartSheet$methods(get_prior_sheet_data = function() { 34 | xml <- '>' 35 | 36 | if (length(sheetPr) > 0) { 37 | xml <- paste(xml, sheetPr, collapse = "") 38 | } 39 | 40 | if (length(sheetViews) > 0) { 41 | xml <- paste(xml, sheetViews, collapse = "") 42 | } 43 | 44 | if (length(pageMargins) > 0) { 45 | xml <- paste(xml, pageMargins, collapse = "") 46 | } 47 | 48 | if (length(drawing) > 0) { 49 | xml <- paste(xml, drawing, collapse = "") 50 | } 51 | 52 | xml <- paste(xml, "") 53 | 54 | return(xml) 55 | }) 56 | -------------------------------------------------------------------------------- /R/utils.R: -------------------------------------------------------------------------------- 1 | #' If NULL then ... 2 | #' 3 | #' Replace NULL 4 | #' 5 | #' @param x A value to check 6 | #' @param y A value to substitute if x is null 7 | #' @examples 8 | #' \dontrun{ 9 | #' x <- NULL 10 | #' x <- x %||% "none" 11 | #' x <- x %||% NA 12 | #' } 13 | #' 14 | #' @name if_null_then 15 | `%||%` <- function(x, y) if (is.null(x)) y else x 16 | 17 | is_not_class <- function(x, class) { 18 | !(inherits(x, class) | is.null(x)) 19 | } 20 | 21 | is_true_false <- function(x) { 22 | is.logical(x) && length(x) == 1L && !is.na(x) 23 | } 24 | 25 | pair_rc <- function(r, c) { 26 | # Assumes that there can't be more than 10M columns 27 | # Excel allows 16,384 28 | # Google Sheets allows 18,278 29 | r+c*1e-7 30 | } 31 | 32 | do_call_params <- function(fun, params, ..., .map = FALSE) { 33 | fun <- match.fun(fun) 34 | call_params <- c(list(...), params[names(params) %in% names(formals(fun))]) 35 | call_params <- lapply(call_params, function(x) if (is.object(x)) list(x) else x) 36 | 37 | call_fun <- if (.map) { 38 | function(...) mapply(fun, ..., MoreArgs = NULL, SIMPLIFY = FALSE, USE.NAMES = FALSE) 39 | } else { 40 | fun 41 | } 42 | 43 | do.call(call_fun, call_params) 44 | } 45 | 46 | # sets temporary options 47 | # option() returns the original values 48 | get_set_options <- function() { 49 | options( 50 | # increase scipen to avoid writing in scientific 51 | scipen = 200, 52 | OutDec = ".", 53 | digits = 22 54 | ) 55 | } 56 | 57 | 58 | #' helper function to create tempory directory for testing purpose 59 | #' @param name for the temp file 60 | #' @export 61 | temp_xlsx <- function(name = "temp_xlsx") { 62 | tempfile(pattern = paste0(name, "_"), fileext = ".xlsx") 63 | } 64 | -------------------------------------------------------------------------------- /man/mergeCells.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/wrappers.R 3 | \name{mergeCells} 4 | \alias{mergeCells} 5 | \title{Merge cells within a worksheet} 6 | \usage{ 7 | mergeCells(wb, sheet, cols, rows) 8 | } 9 | \arguments{ 10 | \item{wb}{A workbook object} 11 | 12 | \item{sheet}{A name or index of a worksheet} 13 | 14 | \item{cols}{Columns to merge} 15 | 16 | \item{rows}{corresponding rows to merge} 17 | } 18 | \description{ 19 | Merge cells within a worksheet 20 | } 21 | \details{ 22 | As merged region must be rectangular, only min and max of cols and rows are used. 23 | } 24 | \examples{ 25 | ## Create a new workbook 26 | wb <- createWorkbook() 27 | 28 | ## Add a worksheet 29 | addWorksheet(wb, "Sheet 1") 30 | addWorksheet(wb, "Sheet 2") 31 | 32 | ## Merge cells: Row 2 column C to F (3:6) 33 | mergeCells(wb, "Sheet 1", cols = 2, rows = 3:6) 34 | 35 | ## Merge cells:Rows 10 to 20 columns A to J (1:10) 36 | mergeCells(wb, 1, cols = 1:10, rows = 10:20) 37 | 38 | ## Intersecting merges 39 | mergeCells(wb, 2, cols = 1:10, rows = 1) 40 | mergeCells(wb, 2, cols = 5:10, rows = 2) 41 | mergeCells(wb, 2, cols = c(1, 10), rows = 12) ## equivalent to 1:10 as only min/max are used 42 | # mergeCells(wb, 2, cols = 1, rows = c(1,10)) # Throws error because intersects existing merge 43 | 44 | ## remove merged cells 45 | removeCellMerge(wb, 2, cols = 1, rows = 1) # removes any intersecting merges 46 | mergeCells(wb, 2, cols = 1, rows = 1:10) # Now this works 47 | 48 | ## Save workbook 49 | \dontrun{ 50 | saveWorkbook(wb, "mergeCellsExample.xlsx", overwrite = TRUE) 51 | } 52 | } 53 | \seealso{ 54 | \code{\link[=removeCellMerge]{removeCellMerge()}} 55 | } 56 | \author{ 57 | Alexander Walker 58 | } 59 | -------------------------------------------------------------------------------- /tests/testthat/test-date_time_conversion.R: -------------------------------------------------------------------------------- 1 | 2 | context("Date/Time Conversions") 3 | 4 | test_that("as_POSIXct_utc", { 5 | exp <- "2022-03-02 19:27:35" 6 | got <- as_POSIXct_utc("2022-03-02 19:27:35") 7 | expect_equal(exp, as.character(got)) 8 | }) 9 | 10 | test_that("convert to date", { 11 | dates <- as.Date("2015-02-07") + -10:10 12 | origin <- 25569L 13 | n <- as.integer(dates) + origin 14 | 15 | expect_equal(convertToDate(n), dates) 16 | 17 | earlyDate <- as.Date("1900-01-03") 18 | serialDate <- 3 19 | expect_equal(convertToDate(serialDate), earlyDate) 20 | 21 | }) 22 | 23 | 24 | test_that("convert to datetime", { 25 | x <- 43037 + 2 / 1440 26 | expect_equal(object = convertToDateTime(x, tx = Sys.timezone()), expected = as.POSIXct("2017-10-29 00:02:00", tz = Sys.timezone())) 27 | 28 | x <- 43037 + 2 / 1440 + 1 / 86400 29 | expect_equal(object = convertToDateTime(x, tx = Sys.timezone()), expected = as.POSIXct("2017-10-29 00:02:01", tz = Sys.timezone())) 30 | 31 | x <- 43037 + 2.50 / 1440 32 | expect_equal(object = convertToDateTime(x, tx = Sys.timezone()), expected = as.POSIXct("2017-10-29 00:02:30", tz = Sys.timezone())) 33 | 34 | x <- 43037 + 2 / 1440 + 12.12 / 86400 35 | x_datetime <- convertToDateTime(x, tx = "UTC") 36 | attr(x_datetime, "tzone") <- "UTC" 37 | }) 38 | 39 | 40 | test_that("read.xlsx detectDates", { 41 | 42 | xlsxFile <- system.file("extdata", "gh_issue_288.xlsx", package = "openxlsx") 43 | 44 | ref_dat <- data.frame(Date = c(as.Date(c("2021-10-20", "2021-11-03")))) 45 | ref_num <- data.frame(Date = c(44489.4, 44503.0)) 46 | 47 | tst_dat <- read.xlsx(xlsxFile, detectDates = TRUE) 48 | tst_num <- read.xlsx(xlsxFile, detectDates = FALSE) 49 | 50 | expect_equal(ref_dat, tst_dat) 51 | expect_equal(ref_num, tst_num) 52 | 53 | }) 54 | -------------------------------------------------------------------------------- /tests/testthat/test-remove_worksheets.R: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | context("Removing worksheets.") 6 | 7 | test_that("Deleting worksheets", { 8 | tempFile <- temp_xlsx() 9 | genWS <- function(wb, sheetName) { 10 | addWorksheet(wb, sheetName) 11 | writeDataTable(wb, sheetName, data.frame("X" = sprintf("This is sheet: %s", sheetName)), colNames = FALSE) 12 | } 13 | 14 | wb <- createWorkbook() 15 | genWS(wb, "Sheet 1") 16 | genWS(wb, "Sheet 2") 17 | genWS(wb, "Sheet 3") 18 | 19 | expect_equal(names(wb), c("Sheet 1", "Sheet 2", "Sheet 3")) 20 | 21 | removeWorksheet(wb, sheet = 1) 22 | expect_equal(names(wb), c("Sheet 2", "Sheet 3")) 23 | 24 | 25 | removeWorksheet(wb, sheet = 1) 26 | expect_equal(names(wb), c("Sheet 3")) 27 | 28 | 29 | ## add to end 30 | genWS(wb, "Sheet 1") 31 | genWS(wb, "Sheet 2") 32 | expect_equal(names(wb), c("Sheet 3", "Sheet 1", "Sheet 2")) 33 | 34 | saveWorkbook(wb, tempFile, overwrite = TRUE) 35 | 36 | ## re-load & re-order worksheets 37 | 38 | wb <- loadWorkbook(tempFile) 39 | expect_equal(names(wb), c("Sheet 3", "Sheet 1", "Sheet 2")) 40 | 41 | writeData(wb, sheet = "Sheet 2", x = iris[1:10, 1:4], startRow = 5) 42 | expect_equal(iris[1:10, 1:4], read.xlsx(wb, "Sheet 2", startRow = 5)) 43 | 44 | 45 | writeData(wb, sheet = 1, x = iris[1:20, 1:4], startRow = 5) 46 | expect_equal(iris[1:20, 1:4], read.xlsx(wb, "Sheet 3", startRow = 5)) 47 | 48 | 49 | removeWorksheet(wb, sheet = 1) 50 | expect_equal("This is sheet: Sheet 1", read.xlsx(wb, 1, startRow = 1)[[1]]) 51 | 52 | removeWorksheet(wb, sheet = 2) 53 | expect_equal("This is sheet: Sheet 1", read.xlsx(wb, 1, startRow = 1)[[1]]) 54 | 55 | removeWorksheet(wb, sheet = 1) 56 | expect_equal(names(wb), character(0)) 57 | 58 | 59 | 60 | unlink(tempFile, recursive = TRUE, force = TRUE) 61 | rm(wb) 62 | }) 63 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | # All available hooks: https://pre-commit.com/hooks.html 2 | # R specific hooks: https://github.com/lorenzwalthert/precommit 3 | repos: 4 | - repo: https://github.com/lorenzwalthert/precommit 5 | rev: v0.1.3.9014 6 | hooks: 7 | - id: style-files 8 | args: [--style_pkg=styler, --style_fun=tidyverse_style] 9 | - id: roxygenize 10 | # codemeta must be above use-tidy-description when both are used 11 | # - id: codemeta-description-updated 12 | - id: use-tidy-description 13 | - id: spell-check 14 | exclude: > 15 | (?x)^( 16 | data/.*| 17 | (.*/|)\.Rprofile| 18 | (.*/|)\.Renviron| 19 | (.*/|)\.gitignore| 20 | (.*/|)NAMESPACE| 21 | (.*/|)WORDLIST| 22 | (.*/|)\.travis.yml| 23 | (.*/|)appveyor.yml| 24 | (.*/|)\.Rbuildignore| 25 | (.*/|)\.pre-commit-.*| 26 | .*\.[rR]| 27 | .*\.Rproj| 28 | .*\.py| 29 | .*\.feather| 30 | .*\.rds| 31 | .*\.Rds| 32 | .*\.sh| 33 | .*\.RData 34 | )$ 35 | - id: lintr 36 | - id: readme-rmd-rendered 37 | - id: parsable-R 38 | - id: no-browser-statement 39 | - id: deps-in-desc 40 | - repo: https://github.com/pre-commit/pre-commit-hooks 41 | rev: v4.0.1 42 | hooks: 43 | - id: check-added-large-files 44 | args: ['--maxkb=200'] 45 | - id: end-of-file-fixer 46 | exclude: '\.Rd' 47 | - repo: local 48 | hooks: 49 | - id: forbid-to-commit 50 | name: Don't commit common R artifacts 51 | entry: Cannot commit .Rhistory, .RData, .Rds or .rds. 52 | language: fail 53 | files: '\.Rhistory|\.RData|\.Rds|\.rds$' 54 | # `exclude: ` to allow committing specific files. 55 | -------------------------------------------------------------------------------- /tests/testthat/test-fill_merged_cells.R: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | context("Fill Merged Cells") 7 | 8 | 9 | 10 | test_that("fill merged cells", { 11 | wb <- createWorkbook() 12 | addWorksheet(wb, sheetName = "sheet1") 13 | writeData(wb = wb, sheet = 1, x = data.frame("A" = 1, "B" = 2)) 14 | writeData(wb = wb, sheet = 1, x = 2, startRow = 2, startCol = 2) 15 | writeData(wb = wb, sheet = 1, x = 3, startRow = 2, startCol = 3) 16 | writeData(wb = wb, sheet = 1, x = 4, startRow = 2, startCol = 4) 17 | writeData(wb = wb, sheet = 1, x = t(matrix(1:4, 4, 4)), startRow = 3, startCol = 1, colNames = FALSE) 18 | 19 | mergeCells(wb = wb, sheet = 1, cols = 2:4, rows = 1) 20 | mergeCells(wb = wb, sheet = 1, cols = 2:4, rows = 3) 21 | mergeCells(wb = wb, sheet = 1, cols = 2:4, rows = 4) 22 | mergeCells(wb = wb, sheet = 1, cols = 2:4, rows = 5) 23 | 24 | tmp_file <- temp_xlsx() 25 | saveWorkbook(wb = wb, file = tmp_file, overwrite = TRUE) 26 | 27 | expect_equal(names(read.xlsx(tmp_file, fillMergedCells = FALSE)), c("A", "B", "X3", "X4")) 28 | expect_equal(names(read.xlsx(tmp_file, fillMergedCells = TRUE)), c("A", "B", "B", "B")) 29 | 30 | r1 <- data.frame("A" = rep(1, 5), "B" = rep(2, 5), "X3" = rep(3,5), "X4" = rep(4, 5)) 31 | r2 <- data.frame("A" = rep(1, 5), "B" = rep(2, 5), "B1" = c(3,2,2,2,3), "B2" = c(4,2,2,2,4)) 32 | names(r2) <- c("A", "B", "B", "B") 33 | 34 | r2_1 <- r2[1:5, 1:3] 35 | names(r2_1) <- c("A", "B", "B") 36 | 37 | expect_equal(read.xlsx(tmp_file, fillMergedCells = FALSE), r1) 38 | expect_equal(read.xlsx(tmp_file, fillMergedCells = TRUE), r2) 39 | 40 | expect_equal( read.xlsx(tmp_file, cols = 1:3, fillMergedCells = TRUE), r2_1) 41 | expect_equal( read.xlsx(tmp_file, rows = 1:3, fillMergedCells = TRUE), r2[1:2, ]) 42 | expect_equal( read.xlsx(tmp_file, cols = 1:3, rows = 1:4, fillMergedCells = TRUE), r2_1[1:3,]) 43 | 44 | }) 45 | -------------------------------------------------------------------------------- /tests/testthat/test-loading_workbook_tables.R: -------------------------------------------------------------------------------- 1 | 2 | 3 | context("Load Workbook Object Tables") 4 | 5 | 6 | test_that("Tables loaded correctly", { 7 | wb <- loadWorkbook(system.file("extdata", "loadExample.xlsx", package = "openxlsx")) 8 | 9 | expect_equal(unname(attr(wb$tables, "tableName")), c("Table2", "Table3")) 10 | expect_equal(names(attr(wb$tables, "tableName")), c("A1:E51", "A1:K30")) 11 | expect_equal(attr(wb$tables, "sheet"), c(1, 3)) 12 | 13 | expect_equal(wb$worksheets[[1]]$tableParts, "", check.attributes = FALSE) 14 | expect_equal(unname(attr(wb$worksheets[[1]]$tableParts, "tableName")), "Table2") 15 | expect_equal(names(attr(wb$worksheets[[1]]$tableParts, "tableName")), "A1:E51") 16 | 17 | expect_equal(wb$worksheets[[3]]$tableParts, "", check.attributes = FALSE) 18 | expect_equal(unname(attr(wb$worksheets[[3]]$tableParts, "tableName")), "Table3") 19 | expect_equal(names(attr(wb$worksheets[[3]]$tableParts, "tableName")), "A1:K30") 20 | 21 | 22 | ## now remove a table 23 | expect_equal(unname(getTables(wb, 1)), "Table2", check.attributes = FALSE) 24 | expect_equal(unname(getTables(wb, 3)), "Table3", check.attributes = FALSE) 25 | 26 | removeTable(wb, sheet = 1, table = "Table2") 27 | 28 | expect_equal(getTables(wb, sheet = 1), character(0), check.attributes = FALSE) 29 | expect_equal(length(wb$worksheets[[1]]$tableParts), 0) 30 | expect_equal(wb$worksheets[[1]]$tableParts, character(0), check.attributes = FALSE) 31 | 32 | expect_equal(wb$worksheets[[3]]$tableParts, "", check.attributes = FALSE) 33 | expect_equal(unname(attr(wb$worksheets[[3]]$tableParts, "tableName")), "Table3") 34 | expect_equal(names(attr(wb$worksheets[[3]]$tableParts, "tableName")), "A1:K30") 35 | 36 | 37 | expect_error(removeTable(wb, sheet = 1, table = "Table2"), regexp = "table 'Table2' does not exist") 38 | }) 39 | -------------------------------------------------------------------------------- /tests/testthat/test-options.R: -------------------------------------------------------------------------------- 1 | 2 | test_that("option names are appropriate", { 3 | bad <- grep("^openxlsx[.].*", names(op.openxlsx), value = TRUE, invert = TRUE) 4 | expect_equal(bad, character(0)) 5 | }) 6 | 7 | test_that("changing options", { 8 | op <- options() 9 | 10 | # Set via options() 11 | options(openxlsx.borders = "whatever") 12 | expect_equal(openxlsx_getOp("borders"), getOption("openxlsx.borders")) 13 | expect_equal(openxlsx_getOp("borders"), "whatever") 14 | 15 | # Set via openxlsx_setOp() 16 | openxlsx_setOp("borders", "new_whatever") 17 | expect_equal(openxlsx_getOp("borders"), getOption("openxlsx.borders")) 18 | expect_equal(openxlsx_getOp("borders"), "new_whatever") 19 | 20 | # with openxlsx. prefix 21 | openxlsx_setOp("openxlsx.borders", "new_new_whatever") 22 | expect_equal(openxlsx_getOp("openxlsx.borders"), getOption("openxlsx.borders")) 23 | expect_equal(openxlsx_getOp("openxlsx.borders"), "new_new_whatever") 24 | 25 | options(openxlsx.tableStyle = "Cool format") 26 | expect_equal(openxlsx_getOp("tableStyle"), openxlsx_getOp("openxlsx.tableStyle")) 27 | 28 | # Setting to NULL will return default 29 | options(openxlsx.borders = NULL) 30 | expect_equal(openxlsx_getOp("borders"), op.openxlsx[["openxlsx.borders"]]) 31 | 32 | # Bad options names will trigger warning but still be produced 33 | options(openxlsx.likelyNotARealOption = TRUE) 34 | expect_warning( 35 | expect_true(openxlsx_getOp("likelyNotARealOption")), 36 | "not a standard openxlsx option" 37 | ) 38 | 39 | # Multiple Ops returns error 40 | expect_error(openxlsx_getOp(c("withFilter", "borders")), "length 1") 41 | 42 | openxlsx_resetOp() 43 | options(op) 44 | }) 45 | 46 | test_that("openxlsx_setOp() works with list [#215]", { 47 | op <- options() 48 | expect_error(openxlsx_setOp(list(withFilter = TRUE, keepNA = TRUE)), NA) 49 | openxlsx_resetOp() 50 | options(op) 51 | }) 52 | -------------------------------------------------------------------------------- /inst/extdata/build_font_size_lookup.R: -------------------------------------------------------------------------------- 1 | # nolint start 2 | 3 | options("scipen" = 10000) 4 | 5 | ## loop through all fonts 6 | fontDir <- "C:\\Users\\Alex\\Desktop\\font_workbooks" 7 | files <- list.files(fontDir, patter = "\\.xlsx$", full.names = TRUE) 8 | files <- files[!grepl("-bold.xlsx", files)] 9 | 10 | files2 <- list.files(fontDir, patter = "\\.xlsx$", full.names = FALSE) 11 | files2 <- files2[!grepl("-bold.xlsx", files2)] 12 | 13 | font <- tolower(gsub(" ", ".", gsub("\\.xlsx", "", files2))) 14 | 15 | 16 | strs <- "openxlsxFontSizeLookupTable <- \ndata.frame(" 17 | allWidths <- rep(8.43, 29) 18 | names(allWidths) <- 1:29 19 | for(i in seq_along(files)){ 20 | 21 | f <- font[[i]] 22 | widths <- round(as.numeric(read.xlsx(files[[i]])[2,]), 6) 23 | strs <- c(strs, sprintf('"%s"= c(%s),\n', f, paste(widths, collapse = ", "))) 24 | 25 | } 26 | 27 | strs[length(strs)] <- gsub(",\n", ")", strs[length(strs)]) 28 | 29 | 30 | ## bold ones 31 | 32 | ## loop through all fonts 33 | fontDir <- "C:\\Users\\Alex\\Desktop\\font_workbooks" 34 | files <- list.files(fontDir, patter = "\\.xlsx$", full.names = TRUE) 35 | files <- files[grepl("-bold.xlsx", files)] 36 | 37 | files2 <- list.files(fontDir, patter = "\\.xlsx$", full.names = FALSE) 38 | files2 <- files2[grepl("-bold.xlsx", files2)] 39 | 40 | font <- tolower(gsub(" ", ".", gsub("\\-bold.xlsx", "", files2))) 41 | 42 | 43 | strsBold <- "openxlsxFontSizeLookupTableBold <- \ndata.frame(" 44 | allWidths <- rep(8.43, 29) 45 | names(allWidths) <- 1:29 46 | for(i in seq_along(files)){ 47 | 48 | f <- font[[i]] 49 | widths <- round(as.numeric(read.xlsx(files[[i]])[2,]), 6) 50 | strsBold <- c(strsBold, sprintf('"%s"= c(%s),\n', f, paste(widths, collapse = ", "))) 51 | 52 | } 53 | 54 | strsBold[length(strsBold)] <- gsub(",\n", ")", strsBold[length(strsBold)]) 55 | 56 | 57 | allStrs <- c(strs, "\n\n\n", strsBold) 58 | cat(allStrs) 59 | 60 | 61 | 62 | 63 | 64 | # nolint end 65 | -------------------------------------------------------------------------------- /tests/testthat/test-saveWorkbook.R: -------------------------------------------------------------------------------- 1 | 2 | context("save workbook") 3 | 4 | 5 | test_that("test return values for saveWorkbook", { 6 | 7 | tempFile <- temp_xlsx() 8 | wb<-createWorkbook() 9 | addWorksheet(wb,"name") 10 | expect_true( saveWorkbook(wb,tempFile,returnValue = TRUE)) 11 | 12 | expect_error( saveWorkbook(wb,tempFile,returnValue = TRUE)) 13 | 14 | 15 | expect_invisible( saveWorkbook(wb,tempFile,returnValue = FALSE ,overwrite = TRUE)) 16 | unlink(tempFile, recursive = TRUE, force = TRUE) 17 | 18 | } 19 | ) 20 | 21 | # regression test for a typo 22 | test_that("regression test for #248", { 23 | 24 | # Basic data frame 25 | df <- data.frame(number = 1:3, percent = 4:6/100) 26 | tempFile <- temp_xlsx() 27 | 28 | # no formatting 29 | expect_silent(write.xlsx(df, tempFile, borders = "columns", overwrite = TRUE)) 30 | 31 | # Change column class to percentage 32 | class(df$percent) <- "percentage" 33 | expect_silent(write.xlsx(df, tempFile, borders = "columns", overwrite = TRUE)) 34 | }) 35 | 36 | 37 | # test for hyperrefs 38 | test_that("creating hyperlinks", { 39 | 40 | # prepare a file 41 | tempFile <- temp_xlsx() 42 | wb <- createWorkbook() 43 | sheet <- "test" 44 | addWorksheet(wb, sheet) 45 | img <- "D:/somepath/somepicture.png" 46 | 47 | # warning: col and row provided, but not required 48 | expect_warning( 49 | linkString <- makeHyperlinkString(col = 1, row = 4, 50 | text = "test.png", file = img)) 51 | 52 | linkString2 <- makeHyperlinkString(text = "test.png", file = img) 53 | 54 | # col and row not needed 55 | expect_equal(linkString, linkString2) 56 | 57 | # write file without errors 58 | writeFormula(wb, sheet, x = linkString, startCol = 1, startRow = 1) 59 | expect_silent(saveWorkbook(wb, tempFile, overwrite = TRUE)) 60 | 61 | # TODO: add a check that the written xlsx file contains linkString 62 | 63 | }) 64 | -------------------------------------------------------------------------------- /man/addStyle.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/wrappers.R 3 | \name{addStyle} 4 | \alias{addStyle} 5 | \title{Add a style to a set of cells} 6 | \usage{ 7 | addStyle(wb, sheet, style, rows, cols, gridExpand = FALSE, stack = FALSE) 8 | } 9 | \arguments{ 10 | \item{wb}{A Workbook object containing a worksheet.} 11 | 12 | \item{sheet}{A worksheet to apply the style to.} 13 | 14 | \item{style}{A style object returned from createStyle()} 15 | 16 | \item{rows}{Rows to apply style to.} 17 | 18 | \item{cols}{columns to apply style to.} 19 | 20 | \item{gridExpand}{If \code{TRUE}, style will be applied to all combinations of rows and cols.} 21 | 22 | \item{stack}{If \code{TRUE} the new style is merged with any existing cell styles. If FALSE, any 23 | existing style is replaced by the new style.} 24 | } 25 | \description{ 26 | Function adds a style to a specified set of cells. 27 | } 28 | \examples{ 29 | ## See package vignette for more examples. 30 | 31 | ## Create a new workbook 32 | wb <- createWorkbook("My name here") 33 | 34 | ## Add a worksheets 35 | addWorksheet(wb, "Expenditure", gridLines = FALSE) 36 | 37 | ## write data to worksheet 1 38 | writeData(wb, sheet = 1, USPersonalExpenditure, rowNames = TRUE) 39 | 40 | ## create and add a style to the column headers 41 | headerStyle <- createStyle( 42 | fontSize = 14, fontColour = "#FFFFFF", halign = "center", 43 | fgFill = "#4F81BD", border = "TopBottom", borderColour = "#4F81BD" 44 | ) 45 | 46 | ## style for body 47 | bodyStyle <- createStyle(border = "TopBottom", borderColour = "#4F81BD") 48 | addStyle(wb, sheet = 1, bodyStyle, rows = 2:6, cols = 1:6, gridExpand = TRUE) 49 | setColWidths(wb, 1, cols = 1, widths = 21) ## set column width for row names column 50 | \dontrun{ 51 | saveWorkbook(wb, "addStyleExample.xlsx", overwrite = TRUE) 52 | } 53 | } 54 | \seealso{ 55 | \code{\link[=createStyle]{createStyle()}} 56 | 57 | expand.grid 58 | } 59 | \author{ 60 | Alexander Walker 61 | } 62 | -------------------------------------------------------------------------------- /tests/testthat/test-read_sources.R: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | context("Read Sources") 7 | 8 | 9 | 10 | test_that("read.xlsx from different sources", { 11 | skip_if_offline() 12 | 13 | ## URL 14 | xlsxFile <- "https://github.com/ycphs/openxlsx/raw/master/inst/extdata/readTest.xlsx" 15 | df_url <- read.xlsx(xlsxFile) 16 | 17 | ## File 18 | xlsxFile <- system.file("extdata", "readTest.xlsx", package = "openxlsx") 19 | df_file <- read.xlsx(xlsxFile) 20 | 21 | expect_true(all.equal(df_url, df_file), label = "Read from URL") 22 | 23 | 24 | ## Non-existing URL 25 | xlsxFile <- "https://github.com/ycphs/openxlsx/raw/master/inst/extdata/readTest2.xlsx" 26 | expect_error(suppressWarnings(read.xlsx(xlsxFile))) 27 | 28 | 29 | ## Non-existing File 30 | xlsxFile <- file.path(dirname(system.file("extdata", "readTest.xlsx", package = "openxlsx")), "readTest00.xlsx") 31 | expect_error(read.xlsx(xlsxFile), regexp = "File does not exist.") 32 | }) 33 | 34 | 35 | 36 | 37 | test_that("loadWorkbook from different sources", { 38 | skip_if_offline() 39 | 40 | ## URL 41 | xlsxFile <- "https://github.com/ycphs/openxlsx/raw/master/inst/extdata/readTest.xlsx" 42 | wb_url <- loadWorkbook(xlsxFile) 43 | 44 | ## File 45 | xlsxFile <- system.file("extdata", "readTest.xlsx", package = "openxlsx") 46 | wb_file <- loadWorkbook(xlsxFile) 47 | 48 | ## check 49 | expect_true(all.equal.Workbook(wb_url, wb_file), "Loading from URL vs local not equal") 50 | }) 51 | 52 | 53 | 54 | test_that("getDateOrigin from different sources", { 55 | skip_if_offline() 56 | 57 | ## URL 58 | xlsxFile <- "https://github.com/ycphs/openxlsx/raw/master/inst/extdata/readTest.xlsx" 59 | origin_url <- getDateOrigin(xlsxFile) 60 | 61 | ## File 62 | xlsxFile <- system.file("extdata", "readTest.xlsx", package = "openxlsx") 63 | origin_file <- getDateOrigin(xlsxFile) 64 | 65 | ## check 66 | expect_equal(origin_url, origin_file) 67 | expect_equal(origin_url, "1900-01-01") 68 | }) 69 | -------------------------------------------------------------------------------- /tests/testthat/test-Workbook_properties.R: -------------------------------------------------------------------------------- 1 | 2 | context("Workbook properties") 3 | 4 | test_that("Workbook properties", { 5 | 6 | ## check creator 7 | wb <- createWorkbook(creator = "Alex", title = "title here", subject = "this & that", category = "some category") 8 | 9 | expect_true(grepl("Alex", wb$core)) 10 | expect_true(grepl("title here", wb$core)) 11 | expect_true(grepl("this & that", wb$core)) 12 | expect_true(grepl("some category", wb$core)) 13 | 14 | fl <- tempfile(fileext = ".xlsx") 15 | wb <- write.xlsx( 16 | x = iris, file = fl, 17 | creator = "Alex 2", 18 | title = "title here 2", 19 | subject = "this & that 2", 20 | category = "some category 2" 21 | ) 22 | 23 | expect_true(grepl("Alex 2", wb$core)) 24 | expect_true(grepl("title here 2", wb$core)) 25 | expect_true(grepl("this & that 2", wb$core)) 26 | expect_true(grepl("some category 2", wb$core)) 27 | 28 | ## maintain on load 29 | wb_loaded <- loadWorkbook(fl) 30 | expect_equal(object = wb_loaded$core, expected = paste0(wb$core, collapse = "")) 31 | 32 | 33 | wb <- createWorkbook(creator = "Philipp", title = "title here", subject = "this & that", category = "some category") 34 | addCreator(wb, "test") 35 | expect_true(grepl("Philipp;test", wb$core)) 36 | 37 | expect_equal(getCreators(wb), c("Philipp", "test")) 38 | setLastModifiedBy(wb, "Philipp 2") 39 | expect_true(grepl("Philipp 2", wb$core)) 40 | }) 41 | 42 | 43 | test_that("Workbook can print with 0 sheets [240]", { 44 | 45 | compare_text <- "A Workbook object.\n \nWorksheets:\n No worksheets attached\n" 46 | printed_text <- capture_output(x <- createWorkbook()$show()) 47 | expect_null(x) 48 | expect_equal(compare_text, printed_text) 49 | 50 | }) 51 | -------------------------------------------------------------------------------- /man/NamedRegion.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/wrappers.R 3 | \name{createNamedRegion} 4 | \alias{createNamedRegion} 5 | \alias{deleteNamedRegion} 6 | \title{Create / delete a named region.} 7 | \usage{ 8 | createNamedRegion(wb, sheet, cols, rows, name, overwrite = FALSE) 9 | 10 | deleteNamedRegion(wb, name) 11 | } 12 | \arguments{ 13 | \item{wb}{A workbook object} 14 | 15 | \item{sheet}{A name or index of a worksheet} 16 | 17 | \item{cols}{Numeric vector specifying columns to include in region} 18 | 19 | \item{rows}{Numeric vector specifying rows to include in region} 20 | 21 | \item{name}{Name for region. A character vector of length 1. Note region names must be case-insensitive unique.} 22 | 23 | \item{overwrite}{Boolean. Overwrite if exists ? Default to FALSE} 24 | } 25 | \description{ 26 | Create / delete a named region 27 | } 28 | \details{ 29 | Region is given by: min(cols):max(cols) X min(rows):max(rows) 30 | } 31 | \examples{ 32 | ## create named regions 33 | wb <- createWorkbook() 34 | addWorksheet(wb, "Sheet 1") 35 | 36 | ## specify region 37 | writeData(wb, sheet = 1, x = iris, startCol = 1, startRow = 1) 38 | createNamedRegion( 39 | wb = wb, 40 | sheet = 1, 41 | name = "iris", 42 | rows = 1:(nrow(iris) + 1), 43 | cols = 1:ncol(iris) 44 | ) 45 | 46 | 47 | ## using writeData 'name' argument 48 | writeData(wb, sheet = 1, x = iris, name = "iris2", startCol = 10) 49 | 50 | out_file <- tempfile(fileext = ".xlsx") 51 | \dontrun{ 52 | saveWorkbook(wb, out_file, overwrite = TRUE) 53 | 54 | ## see named regions 55 | getNamedRegions(wb) ## From Workbook object 56 | getNamedRegions(out_file) ## From xlsx file 57 | 58 | ## delete one 59 | deleteNamedRegion(wb = wb, name = "iris2") 60 | getNamedRegions(wb) 61 | 62 | ## read named regions 63 | df <- read.xlsx(wb, namedRegion = "iris") 64 | head(df) 65 | 66 | df <- read.xlsx(out_file, namedRegion = "iris2") 67 | head(df) 68 | } 69 | 70 | } 71 | \seealso{ 72 | \code{\link[=getNamedRegions]{getNamedRegions()}} 73 | } 74 | \author{ 75 | Alexander Walker 76 | } 77 | -------------------------------------------------------------------------------- /man/setRowHeights.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/wrappers.R 3 | \name{setRowHeights} 4 | \alias{setRowHeights} 5 | \title{Set worksheet row heights} 6 | \usage{ 7 | setRowHeights( 8 | wb, 9 | sheet, 10 | rows, 11 | heights, 12 | fontsize = NULL, 13 | factor = 1, 14 | base_height = 15, 15 | extra_height = 12, 16 | wrap = TRUE 17 | ) 18 | } 19 | \arguments{ 20 | \item{wb}{workbook object} 21 | 22 | \item{sheet}{name or index of a worksheet} 23 | 24 | \item{rows}{indices of rows to set height} 25 | 26 | \item{heights}{heights to set rows to specified in Excel column height units} 27 | 28 | \item{fontsize}{font size, optional (get base font size by default)} 29 | 30 | \item{factor}{factor to manually adjust font width, e.g., for bold fonts, 31 | optional} 32 | 33 | \item{base_height}{basic row height, optional} 34 | 35 | \item{extra_height}{additional row height per new line of text, optional} 36 | 37 | \item{wrap}{wrap text of entries which exceed the column width, optional} 38 | } 39 | \description{ 40 | Set worksheet row heights 41 | } 42 | \examples{ 43 | ## Create a new workbook 44 | wb <- createWorkbook() 45 | 46 | ## Add a worksheet 47 | addWorksheet(wb, "Sheet") 48 | sheet <- 1 49 | 50 | ## Write dummy data 51 | writeData(wb, sheet, "fixed w/fixed h", startCol = 1, startRow = 1) 52 | writeData(wb, sheet, "fixed w/auto h ABC ABC ABC ABC ABC ABC ABC ABC ABC ABC ABC", 53 | startCol = 2, startRow = 2) 54 | writeData(wb, sheet, "variable w/fixed h", startCol = 3, startRow = 3) 55 | 56 | ## Set column widths and row heights 57 | setColWidths(wb, sheet, cols = c(1, 2, 3, 4), widths = c(10, 20, "auto", 20)) 58 | setRowHeights(wb, sheet, rows = c(1, 2, 8, 4, 6), heights = c(30, "auto", 15, 15, 30)) 59 | 60 | ## Overwrite row 1 height 61 | setRowHeights(wb, sheet, rows = 1, heights = 40) 62 | 63 | ## Save workbook 64 | \dontrun{ 65 | saveWorkbook(wb, "setRowHeightsExample.xlsx", overwrite = TRUE) 66 | } 67 | } 68 | \seealso{ 69 | \code{\link[=removeRowHeights]{removeRowHeights()}} 70 | } 71 | \author{ 72 | Alexander Walker 73 | } 74 | -------------------------------------------------------------------------------- /tests/testthat/test-worksheet_renaming.R: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | context("Renaming worksheets.") 7 | 8 | 9 | 10 | test_that("Can rename worksheets under all conditions", { 11 | tempFile <- file.path(tempdir(), "renaming.xlsx") 12 | wb <- createWorkbook() 13 | addWorksheet(wb, "sheet 1") 14 | addWorksheet(wb, "sheet 2") 15 | addWorksheet(wb, "sheet 3") 16 | addWorksheet(wb, "sheet 4") 17 | addWorksheet(wb, "sheet 5") 18 | 19 | renameWorksheet(wb, sheet = 2, "THis is SHEET 2") 20 | expect_equal(names(wb), c("sheet 1", "THis is SHEET 2", "sheet 3", "sheet 4", "sheet 5")) 21 | 22 | 23 | renameWorksheet(wb, sheet = "THis is SHEET 2", "THis is STILL SHEET 2") 24 | expect_equal(names(wb), c("sheet 1", "THis is STILL SHEET 2", "sheet 3", "sheet 4", "sheet 5")) 25 | 26 | 27 | renameWorksheet(wb, sheet = 5, "THis is SHEET 5") 28 | expect_equal(names(wb), c("sheet 1", "THis is STILL SHEET 2", "sheet 3", "sheet 4", "THis is SHEET 5")) 29 | 30 | renameWorksheet(wb, sheet = 5, "THis is STILL SHEET 5") 31 | expect_equal(names(wb), c("sheet 1", "THis is STILL SHEET 2", "sheet 3", "sheet 4", "THis is STILL SHEET 5")) 32 | 33 | 34 | renameWorksheet(wb, sheet = 2, "Sheet 2") 35 | expect_equal(names(wb), c("sheet 1", "Sheet 2", "sheet 3", "sheet 4", "THis is STILL SHEET 5")) 36 | 37 | renameWorksheet(wb, sheet = 5, "Sheet 5") 38 | expect_equal(names(wb), c("sheet 1", "Sheet 2", "sheet 3", "sheet 4", "Sheet 5")) 39 | 40 | 41 | ## re-ordering 42 | worksheetOrder(wb) <- c(4, 3, 2, 5, 1) 43 | saveWorkbook(wb, tempFile, overwrite = TRUE) 44 | 45 | wb <- loadWorkbook(file = tempFile) 46 | renameWorksheet(wb, sheet = 2, "THIS is SHEET 3") 47 | 48 | wb <- loadWorkbook(tempFile) 49 | renameWorksheet(wb, sheet = "Sheet 5", "THIS is NOW SHEET 5") 50 | 51 | expect_equal(names(wb), c("sheet 4", "sheet 3", "Sheet 2", "THIS is NOW SHEET 5", "sheet 1")) 52 | 53 | names(wb)[[1]] <- "THIS IS NOW SHEET 4" 54 | expect_equal(names(wb), c("THIS IS NOW SHEET 4", "sheet 3", "Sheet 2", "THIS is NOW SHEET 5", "sheet 1")) 55 | 56 | 57 | unlink(tempFile, recursive = TRUE, force = TRUE) 58 | }) 59 | -------------------------------------------------------------------------------- /man/setColWidths.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/wrappers.R 3 | \name{setColWidths} 4 | \alias{setColWidths} 5 | \title{Set worksheet column widths} 6 | \usage{ 7 | setColWidths( 8 | wb, 9 | sheet, 10 | cols, 11 | widths = 8.43, 12 | hidden = rep(FALSE, length(cols)), 13 | ignoreMergedCells = FALSE 14 | ) 15 | } 16 | \arguments{ 17 | \item{wb}{A workbook object} 18 | 19 | \item{sheet}{A name or index of a worksheet} 20 | 21 | \item{cols}{Indices of cols to set width} 22 | 23 | \item{widths}{widths to set cols to specified in Excel column width units or "auto" for automatic sizing. The widths argument is 24 | recycled to the length of cols.} 25 | 26 | \item{hidden}{Logical vector. If TRUE the column is hidden.} 27 | 28 | \item{ignoreMergedCells}{Ignore any cells that have been merged with other cells in the calculation of "auto" column widths.} 29 | } 30 | \description{ 31 | Set worksheet column widths to specific width or "auto". 32 | } 33 | \details{ 34 | The global min and max column width for "auto" columns is set by (default values show): 35 | \itemize{ 36 | \item{options("openxlsx.minWidth" = 3)} 37 | \item{options("openxlsx.maxWidth" = 250)} ## This is the maximum width allowed in Excel 38 | } 39 | 40 | NOTE: The calculation of column widths can be slow for large worksheets. 41 | 42 | NOTE: The \code{hidden} parameter may conflict with the one set in \code{groupColumns}; changing one will update the other. 43 | } 44 | \examples{ 45 | ## Create a new workbook 46 | wb <- createWorkbook() 47 | 48 | ## Add a worksheet 49 | addWorksheet(wb, "Sheet 1") 50 | 51 | 52 | ## set col widths 53 | setColWidths(wb, 1, cols = c(1, 4, 6, 7, 9), widths = c(16, 15, 12, 18, 33)) 54 | 55 | ## auto columns 56 | addWorksheet(wb, "Sheet 2") 57 | writeData(wb, sheet = 2, x = iris) 58 | setColWidths(wb, sheet = 2, cols = 1:5, widths = "auto") 59 | 60 | ## Save workbook 61 | \dontrun{ 62 | saveWorkbook(wb, "setColWidthsExample.xlsx", overwrite = TRUE) 63 | } 64 | 65 | } 66 | \seealso{ 67 | \code{\link[=removeColWidths]{removeColWidths()}} 68 | } 69 | \author{ 70 | Alexander Walker 71 | } 72 | -------------------------------------------------------------------------------- /man/insertImage.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/wrappers.R 3 | \name{insertImage} 4 | \alias{insertImage} 5 | \title{Insert an image into a worksheet} 6 | \usage{ 7 | insertImage( 8 | wb, 9 | sheet, 10 | file, 11 | width = 6, 12 | height = 3, 13 | startRow = 1, 14 | startCol = 1, 15 | units = "in", 16 | dpi = 300, 17 | address 18 | ) 19 | } 20 | \arguments{ 21 | \item{wb}{A workbook object} 22 | 23 | \item{sheet}{A name or index of a worksheet} 24 | 25 | \item{file}{An image file. Valid file types are: jpeg, png, bmp} 26 | 27 | \item{width}{Width of figure.} 28 | 29 | \item{height}{Height of figure.} 30 | 31 | \item{startRow}{Row coordinate of upper left corner of the image} 32 | 33 | \item{startCol}{Column coordinate of upper left corner of the image} 34 | 35 | \item{units}{Units of width and height. Can be "in", "cm" or "px"} 36 | 37 | \item{dpi}{Image resolution used for conversion between units.} 38 | 39 | \item{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.} 40 | } 41 | \description{ 42 | Insert an image into a worksheet 43 | } 44 | \examples{ 45 | ## Create a new workbook 46 | wb <- createWorkbook("Ayanami") 47 | 48 | ## Add some worksheets 49 | addWorksheet(wb, "Sheet 1") 50 | addWorksheet(wb, "Sheet 2") 51 | addWorksheet(wb, "Sheet 3") 52 | addWorksheet(wb, "Sheet 4") 53 | 54 | ## Insert images 55 | img <- system.file("extdata", "einstein.jpg", package = "openxlsx") 56 | insertImage(wb, "Sheet 1", img, startRow = 5, startCol = 3, width = 6, height = 5) 57 | insertImage(wb, 2, img, startRow = 2, startCol = 2) 58 | insertImage(wb, 3, img, width = 15, height = 12, startRow = 3, startCol = "G", units = "cm") 59 | insertImage(wb, 4, img, address = "https://github.com/ycphs/openxlsx") 60 | 61 | ## Save workbook 62 | \dontrun{ 63 | saveWorkbook(wb, "insertImageExample.xlsx", overwrite = TRUE) 64 | } 65 | } 66 | \seealso{ 67 | \code{\link[=insertPlot]{insertPlot()}} 68 | } 69 | \author{ 70 | Alexander Walker 71 | } 72 | -------------------------------------------------------------------------------- /tests/testthat/test-writeData.R: -------------------------------------------------------------------------------- 1 | test_that("writeData() forces evaluation of x (#264)", { 2 | wbfile <- temp_xlsx() 3 | op <- options(stringsAsFactors = FALSE) 4 | 5 | x <- format(123.4) 6 | df <- data.frame(d = format(123.4)) 7 | df2 <- data.frame(e = x) 8 | 9 | wb <- createWorkbook() 10 | addWorksheet(wb, "sheet") 11 | writeData(wb, "sheet", startCol = 1, data.frame(a = format(123.4))) 12 | writeData(wb, "sheet", startCol = 2, data.frame(b = as.character(123.4))) 13 | writeData(wb, "sheet", startCol = 3, data.frame(c = "123.4")) 14 | writeData(wb, "sheet", startCol = 4, df) 15 | writeData(wb, "sheet", startCol = 5, df2) 16 | 17 | saveWorkbook(wb, wbfile) 18 | out <- read.xlsx(wbfile) 19 | 20 | # Possibly overkill 21 | 22 | with(out, { 23 | expect_identical(a, b) 24 | expect_identical(a, c) 25 | expect_identical(a, d) 26 | expect_identical(a, e) 27 | expect_identical(b, c) 28 | expect_identical(b, d) 29 | expect_identical(b, e) 30 | expect_identical(c, d) 31 | expect_identical(c, e) 32 | expect_identical(d, e) 33 | }) 34 | 35 | options(op) 36 | file.remove(wbfile) 37 | }) 38 | 39 | 40 | test_that("as.character.formula() works [312]", { 41 | form <- y ~ x1 * x2 + x3 42 | expect_identical( 43 | as.character.default(form), 44 | openxlsx:::as.character.formula(form) 45 | ) 46 | 47 | skip_if_not_installed("formula.tools") 48 | # "tests specifically for as.character.formula conflict" 49 | 50 | foo <- function() { 51 | wb <- openxlsx::buildWorkbook( 52 | data.frame( 53 | x = structure("A2 + B2", class = c("character", "formula")), 54 | stringsAsFactors = FALSE 55 | ) 56 | ) 57 | as.list(wb$worksheets[[1]]$sheet_data) 58 | } 59 | 60 | before <- foo() 61 | # don't required the "require" function for deps check 62 | match.fun("require")("formula.tools", character.only = TRUE) 63 | middle <- foo() 64 | detach("package:formula.tools", character.only = TRUE, force = TRUE) 65 | end <- foo() 66 | 67 | expect_identical(before, middle, ignore.environment = TRUE) 68 | expect_identical(before, end, ignore.environment = TRUE) 69 | }) 70 | -------------------------------------------------------------------------------- /inst/WORDLIST: -------------------------------------------------------------------------------- 1 | Arial 2 | Breuer 3 | CMD 4 | Calibri 5 | Calligra 6 | Colour 7 | Customizable 8 | DL 9 | DateTime 10 | FFC 11 | Formating 12 | Generalised 13 | Gnumeric 14 | Italicise 15 | JIS 16 | LONGDATE 17 | LastModifiedBy 18 | Libreoffice 19 | NilValue 20 | ORCID 21 | Openoffice 22 | POSIXct 23 | POSIXt 24 | RStudio 25 | Rcpp 26 | SuperA 27 | SuperB 28 | TableStyleLight 29 | Ungroup 30 | Unmerges 31 | XLConnect 32 | addCreator 33 | addFilter 34 | addWorksheet 35 | apache 36 | asTable 37 | beginsWith 38 | bgFill 39 | bmp 40 | bool 41 | bottomN 42 | changeLastModifiedBy 43 | choosen 44 | codecov 45 | colWidths 46 | colorScale 47 | colorscale 48 | colour 49 | colourScale 50 | coloured 51 | colours 52 | conditionalFormatting 53 | coxph 54 | cpp 55 | createStyle 56 | createWorkbook 57 | databar 58 | dateFormat 59 | datetime 60 | datetimeFormat 61 | datetimes 62 | detectDates 63 | dev 64 | df 65 | eg 66 | endsWith 67 | english 68 | fanfold 69 | firstActiveCol 70 | firstActiveRow 71 | fitToHeight 72 | fitToWidth 73 | fomulas 74 | fontColour 75 | fontName 76 | fontSize 77 | freezePane 78 | getCreators 79 | greaterThan 80 | greaterThanOrEqual 81 | gridlines 82 | hdpi 83 | hh 84 | insertImage 85 | jpeg 86 | lessThan 87 | lessThanOrEqual 88 | libre 89 | loadWorkbook 90 | mailto 91 | maxWidth 92 | minWidth 93 | na 94 | nestings 95 | notBetween 96 | notBlanks 97 | notContains 98 | notEqual 99 | numFmt 100 | openXL 101 | pageSetup 102 | paperSize 103 | pivotTables 104 | png 105 | pre 106 | px 107 | recognise 108 | roxygen 109 | sapply 110 | sep 111 | sheetPr 112 | sheetVisibility 113 | sheetVisible 114 | sheetnames 115 | showvalue 116 | ss 117 | stackable 118 | startCol 119 | startRow 120 | startcol 121 | stylings 122 | tableStyle 123 | tableStyles 124 | tempory 125 | textLength 126 | tidyverse 127 | topN 128 | twips 129 | ugroup 130 | ungroup 131 | unprotect 132 | validateSheet 133 | vbaProject 134 | vdpi 135 | veryHidden 136 | wb 137 | withFilter 138 | worksheetOrder 139 | wrapText 140 | writeComment 141 | writeData 142 | writeDataTable 143 | writeFormula 144 | xls 145 | xlsm 146 | xlsx 147 | xy 148 | yyyy 149 | zipflags 150 | zph 151 | -------------------------------------------------------------------------------- /man/insertPlot.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/wrappers.R 3 | \name{insertPlot} 4 | \alias{insertPlot} 5 | \title{Insert the current plot into a worksheet} 6 | \usage{ 7 | insertPlot( 8 | wb, 9 | sheet, 10 | width = 6, 11 | height = 4, 12 | xy = NULL, 13 | startRow = 1, 14 | startCol = 1, 15 | fileType = "png", 16 | units = "in", 17 | dpi = 300 18 | ) 19 | } 20 | \arguments{ 21 | \item{wb}{A workbook object} 22 | 23 | \item{sheet}{A name or index of a worksheet} 24 | 25 | \item{width}{Width of figure. Defaults to 6in.} 26 | 27 | \item{height}{Height of figure . Defaults to 4in.} 28 | 29 | \item{xy}{Alternate way to specify startRow and startCol. A vector of length 2 of form (startcol, startRow)} 30 | 31 | \item{startRow}{Row coordinate of upper left corner of figure.\code{ xy[[2]]} when xy is given.} 32 | 33 | \item{startCol}{Column coordinate of upper left corner of figure. \code{xy[[1]]} when xy is given.} 34 | 35 | \item{fileType}{File type of image} 36 | 37 | \item{units}{Units of width and height. Can be "in", "cm" or "px"} 38 | 39 | \item{dpi}{Image resolution} 40 | } 41 | \description{ 42 | The current plot is saved to a temporary image file using dev.copy. 43 | This file is then written to the workbook using insertImage. 44 | } 45 | \examples{ 46 | \dontrun{ 47 | ## Create a new workbook 48 | wb <- createWorkbook() 49 | 50 | ## Add a worksheet 51 | addWorksheet(wb, "Sheet 1", gridLines = FALSE) 52 | 53 | ## create plot objects 54 | require(ggplot2) 55 | p1 <- qplot(mpg, 56 | data = mtcars, geom = "density", 57 | fill = as.factor(gear), alpha = I(.5), main = "Distribution of Gas Mileage" 58 | ) 59 | p2 <- qplot(age, circumference, 60 | data = Orange, geom = c("point", "line"), colour = Tree 61 | ) 62 | 63 | ## Insert currently displayed plot to sheet 1, row 1, column 1 64 | print(p1) # plot needs to be showing 65 | insertPlot(wb, 1, width = 5, height = 3.5, fileType = "png", units = "in") 66 | 67 | ## Insert plot 2 68 | print(p2) 69 | insertPlot(wb, 1, xy = c("J", 2), width = 16, height = 10, fileType = "png", units = "cm") 70 | 71 | ## Save workbook 72 | saveWorkbook(wb, "insertPlotExample.xlsx", overwrite = TRUE) 73 | } 74 | } 75 | \seealso{ 76 | \code{\link[=insertImage]{insertImage()}} 77 | } 78 | \author{ 79 | Alexander Walker 80 | } 81 | -------------------------------------------------------------------------------- /R/setWindowSize.R: -------------------------------------------------------------------------------- 1 | #' Set and Get Window Size for xlsx file 2 | #' 3 | #' @param wb A Workbook object 4 | #' @param xWindow the horizontal coordinate of the top left corner of the window 5 | #' @param yWindow the vertical coordinate of the top left corner of the window 6 | #' @param windowWidth the width of the window 7 | #' @param windowHeight the height of the window 8 | #' 9 | #' Set the size and position of the window when you open the xlsx file. The units are in twips. See 10 | #' [Microsoft's documentation for the xlsx standard](https://learn.microsoft.com/en-us/dotnet/api/documentformat.openxml.spreadsheet.workbookview?view=openxml-2.8.1) 11 | #' 12 | #' @export 13 | #' 14 | #' @examples 15 | #' ## Create Workbook object and add worksheets 16 | #' wb <- createWorkbook() 17 | #' addWorksheet(wb, "S1") 18 | #' getWindowSize(wb) 19 | #' setWindowSize(wb, windowWidth = 10000) 20 | setWindowSize <- function(wb, xWindow = NULL, yWindow = NULL, windowWidth = NULL, windowHeight= NULL) { 21 | 22 | bookViews <- wb$workbook$bookViews 23 | 24 | if(!is.null(xWindow)) { 25 | if(as.integer(xWindow) >= 0L) { 26 | bookViews <- sub("xWindow=\"\\d+", paste0("xWindow=\"", xWindow), bookViews) 27 | } else { 28 | stop("xWindow must be >= 0") 29 | } 30 | } 31 | 32 | if(!is.null(yWindow)) { 33 | if(as.integer(yWindow) >= 0L) { 34 | bookViews <- sub("yWindow=\"\\d+", paste0("yWindow=\"", yWindow), bookViews) 35 | } else { 36 | stop("yWindow must be >= 0") 37 | } 38 | } 39 | 40 | if(!is.null(windowWidth)) { 41 | if(as.integer(windowWidth) >= 100L) { 42 | bookViews <- sub("windowWidth=\"\\d+", paste0("windowWidth=\"", windowWidth), bookViews) 43 | } else { 44 | stop("windowWidth must be >= 100") 45 | } 46 | } 47 | 48 | if(!is.null(windowHeight)) { 49 | if(as.integer(windowHeight) >= 100L) { 50 | bookViews <- sub("windowHeight=\"\\d+", paste0("windowHeight=\"", windowHeight), bookViews) 51 | } else { 52 | stop("windowHeight must be >= 100") 53 | } 54 | } 55 | 56 | wb$workbook$bookViews <- bookViews 57 | } 58 | 59 | #' @rdname setWindowSize 60 | #' @export 61 | 62 | getWindowSize <- function(wb) { 63 | bookViews <- wb$workbook$bookViews 64 | 65 | c(getAttrs(bookViews, "xWindow"), 66 | getAttrs(bookViews, "yWindow"), 67 | getAttrs(bookViews, "windowWidth"), 68 | getAttrs(bookViews, "windowHeight")) 69 | 70 | } 71 | -------------------------------------------------------------------------------- /tests/testthat/test-setWindowSize.R: -------------------------------------------------------------------------------- 1 | test_that("can read default sizes from new workbook", { 2 | wb <- createWorkbook() 3 | 4 | expect_equal(getWindowSize(wb), 5 | list(xWindow = "0", yWindow = "0", windowWidth = "13125", windowHeight = "6105")) 6 | }) 7 | 8 | test_that("can change sizes in new workbook", { 9 | wb <- createWorkbook() 10 | setWindowSize(wb, xWindow = 100, yWindow = 200, windowWidth = 20000, windowHeight = 15000) 11 | 12 | expect_equal(getWindowSize(wb), 13 | list(xWindow = "100", yWindow = "200", windowWidth = "20000", windowHeight = "15000")) 14 | }) 15 | 16 | test_that("can change only a few parameters", { 17 | wb <- createWorkbook() 18 | setWindowSize(wb, yWindow = 300, windowWidth = 12000) # others are the default 19 | 20 | expect_equal(getWindowSize(wb), 21 | list(xWindow = "0", yWindow = "300", windowWidth = "12000", windowHeight = "6105")) 22 | }) 23 | 24 | test_that("window size and position must be coercible to integers and non negative", { 25 | wb <- createWorkbook() 26 | expect_error(setWindowSize(wb, xWindow = -300)) 27 | expect_error(setWindowSize(wb, yWindow = -300)) 28 | expect_error(setWindowSize(wb, windowWidth = -300)) 29 | expect_error(setWindowSize(wb, windowHeight = -300)) 30 | expect_error(expect_warning(setWindowSize(wb, xWindow = "string"))) 31 | expect_error(expect_warning(setWindowSize(wb, yWindow = "string"))) 32 | expect_error(expect_warning(setWindowSize(wb, windowWidth = "string"))) 33 | expect_error(expect_warning(setWindowSize(wb, windowHeight = "string"))) 34 | 35 | setWindowSize(wb, xWindow = "500") 36 | expect_equal(getWindowSize(wb)$xWindow, "500") 37 | }) 38 | 39 | test_that("saving and loading preserve window sizes", { 40 | wb <- createWorkbook() 41 | setWindowSize(wb, xWindow = 400, yWindow = 500, windowWidth = 1000, windowHeight = 5000) 42 | addWorksheet(wb, "sheet1") 43 | tempfile <- tempfile() 44 | saveWorkbook(wb, tempfile) 45 | wb2 <- loadWorkbook(tempfile) 46 | 47 | expect_equal(getWindowSize(wb2), 48 | list(xWindow = "400", yWindow = "500", windowWidth = "1000", windowHeight = "5000")) 49 | 50 | setWindowSize(wb2, xWindow = 700, yWindow = 900, windowWidth = 900, windowHeight = 4000) 51 | 52 | tempfile2 <- tempfile() 53 | saveWorkbook(wb2, tempfile2) 54 | wb3 <- loadWorkbook(tempfile2) 55 | 56 | expect_equal(getWindowSize(wb3), 57 | list(xWindow = "700", yWindow = "900", windowWidth = "900", windowHeight = "4000")) 58 | }) 59 | 60 | -------------------------------------------------------------------------------- /man/groupRows.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/wrappers.R 3 | \name{groupRows} 4 | \alias{groupRows} 5 | \title{Group Rows} 6 | \usage{ 7 | groupRows(wb, sheet, rows, hidden = FALSE, level = -1) 8 | } 9 | \arguments{ 10 | \item{wb}{A workbook object} 11 | 12 | \item{sheet}{A name or index of a worksheet} 13 | 14 | \item{rows}{Indices of rows to group. Can be either a vector of indices to group at the same level or a (named) list of numeric vectors of indices to create multiple groupings at once. The names of the entries determine the grouping level. If no names are given, the parameter level is used as default.} 15 | 16 | \item{hidden}{Logical vector. If TRUE the grouped columns are hidden. Defaults to FALSE} 17 | 18 | \item{level}{Grouping level (higher value indicates multiple nestings) for the 19 | group. A vector to assign different grouping levels to the indices. 20 | A value of -1 indicates that the grouping level should be derived 21 | from the existing grouping (one level added)} 22 | } 23 | \description{ 24 | Group a selection of rows 25 | } 26 | \examples{ 27 | wb <- createWorkbook() 28 | addWorksheet(wb, 'Sheet1') 29 | addWorksheet(wb, 'Sheet2') 30 | 31 | writeData(wb, "Sheet1", iris) 32 | writeData(wb, "Sheet2", iris) 33 | 34 | ## create list of groups 35 | # lines used for grouping (here: species) 36 | grp <- list( 37 | seq(2, 51), 38 | seq(52, 101), 39 | seq(102, 151) 40 | ) 41 | # assign group levels 42 | names(grp) <- c("1","0","1") 43 | groupRows(wb, "Sheet1", rows = grp) 44 | 45 | # different grouping 46 | names(grp) <- c("1","2","3") 47 | groupRows(wb, "Sheet2", rows = grp) 48 | 49 | # alternatively, one can call groupRows multiple times 50 | addWorksheet(wb, 'Sheet3') 51 | writeData(wb, "Sheet3", iris) 52 | groupRows(wb, "Sheet3", 2:51, level = 1) 53 | groupRows(wb, "Sheet3", 102:151, level = 1) 54 | 55 | addWorksheet(wb, 'Sheet4') 56 | writeData(wb, "Sheet4", iris) 57 | groupRows(wb, "Sheet4", 2:51, level = 1) 58 | groupRows(wb, "Sheet4", 52:101, level = 2) 59 | groupRows(wb, "Sheet4", 102:151, level = 3) 60 | 61 | # Nested grouping can also be achieved without explicitly given the levels 62 | addWorksheet(wb, 'Sheet5') 63 | writeData(wb, "Sheet5", iris) 64 | groupRows(wb, "Sheet5", 2:151) 65 | groupRows(wb, "Sheet5", 52:151) 66 | groupRows(wb, "Sheet5", 102:151) 67 | 68 | 69 | } 70 | \seealso{ 71 | \code{\link[=ungroupRows]{ungroupRows()}} to ungroup rows. \code{\link[=groupColumns]{groupColumns()}} for grouping columns. 72 | } 73 | \author{ 74 | Joshua Sturm 75 | } 76 | -------------------------------------------------------------------------------- /tests/testthat/test-validate_table_name.R: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | test_that("Validate Table Names", { 5 | wb <- createWorkbook() 6 | addWorksheet(wb, "Sheet 1") 7 | 8 | ## case 9 | expect_equal(wb$validate_table_name("test"), "test") 10 | expect_equal(wb$validate_table_name("TEST"), "test") 11 | expect_equal(wb$validate_table_name("Test"), "test") 12 | 13 | ## length 14 | expect_error(wb$validate_table_name(paste(sample(LETTERS, size = 300, replace = TRUE), collapse = "")), regexp = "tableName must be less than 255 characters") 15 | 16 | ## look like cell ref 17 | expect_error(wb$validate_table_name("R1C2"), regexp = "tableName cannot be the same as a cell reference, such as R1C1", fixed = TRUE) 18 | expect_error(wb$validate_table_name("A1"), regexp = "tableName cannot be the same as a cell reference", fixed = TRUE) 19 | 20 | expect_error(wb$validate_table_name("R06821C9682"), regexp = "tableName cannot be the same as a cell reference, such as R1C1", fixed = TRUE) 21 | expect_error(wb$validate_table_name("ABD918751"), regexp = "tableName cannot be the same as a cell reference", fixed = TRUE) 22 | 23 | expect_error(wb$validate_table_name("A$100"), regexp = "'$' character cannot exist in a tableName", fixed = TRUE) 24 | expect_error(wb$validate_table_name("A12$100"), regexp = "'$' character cannot exist in a tableName", fixed = TRUE) 25 | 26 | tbl_nm <- "性別" 27 | expect_equal(wb$validate_table_name(tbl_nm), tbl_nm) 28 | }) 29 | 30 | 31 | 32 | 33 | 34 | test_that("Existing Table Names", { 35 | wb <- createWorkbook() 36 | addWorksheet(wb, "Sheet 1") 37 | 38 | ## Existing names - case in-sensitive 39 | 40 | writeDataTable(wb, sheet = 1, x = head(iris), tableName = "Table1") 41 | expect_error(wb$validate_table_name("Table1"), regexp = "Table with name 'table1' already exists", fixed = TRUE) 42 | expect_error(writeDataTable(wb, sheet = 1, x = head(iris), tableName = "Table1", startCol = 10), regexp = "Table with name 'table1' already exists", fixed = TRUE) 43 | 44 | expect_error(wb$validate_table_name("TABLE1"), regexp = "Table with name 'table1' already exists", fixed = TRUE) 45 | expect_error(writeDataTable(wb, sheet = 1, x = head(iris), tableName = "TABLE1", startCol = 20), regexp = "Table with name 'table1' already exists", fixed = TRUE) 46 | 47 | expect_error(wb$validate_table_name("table1"), regexp = "Table with name 'table1' already exists", fixed = TRUE) 48 | expect_error(writeDataTable(wb, sheet = 1, x = head(iris), tableName = "table1", startCol = 30), regexp = "Table with name 'table1' already exists", fixed = TRUE) 49 | }) 50 | -------------------------------------------------------------------------------- /.github/SUPPORT.md: -------------------------------------------------------------------------------- 1 | # Getting help with openxlsx 2 | 3 | Thanks for using openxlsx! 4 | Before filing an issue, there are a few places to explore and pieces to put together to make the process as smooth as possible. 5 | 6 | ## Make a reprex 7 | 8 | Start by making a minimal **repr**oducible **ex**ample using the [reprex](https://reprex.tidyverse.org/) package. 9 | If you haven't heard of or used reprex before, you're in for a treat! 10 | Seriously, reprex will make all of your R-question-asking endeavors easier (which is a pretty insane ROI for the five to ten minutes it'll take you to learn what it's all about). 11 | For additional reprex pointers, check out the [Get help!](https://www.tidyverse.org/help/) section of the tidyverse site. 12 | 13 | ## Where to ask? 14 | 15 | Armed with your reprex, the next step is to figure out [where to ask](https://www.tidyverse.org/help/#where-to-ask). 16 | 17 | * If it's a question: start with [community.rstudio.com](https://community.rstudio.com/), and/or StackOverflow. There are more people there to answer questions. 18 | 19 | * If it's a bug: you're in the right place, [file an issue](https://github.com/ycphs/openxlsx/issues/new). 20 | 21 | * If you're not sure: let the community help you figure it out! 22 | If your problem _is_ a bug or a feature request, you can easily return here and report it. 23 | 24 | Before opening a new issue, be sure to [search issues and pull requests](https://github.com/ycphs/openxlsx/issues) to make sure the bug hasn't been reported and/or already fixed in the development version. 25 | By default, the search will be pre-populated with `is:issue is:open`. 26 | You can [edit the qualifiers](https://help.github.com/articles/searching-issues-and-pull-requests/) (e.g. `is:pr`, `is:closed`) as needed. 27 | For example, you'd simply remove `is:open` to search _all_ issues in the repo, open or closed. 28 | 29 | ## What happens next? 30 | 31 | To be as efficient as possible, development of tidyverse packages tends to be very bursty, so you shouldn't worry if you don't get an immediate response. 32 | Typically we don't look at a repo until a sufficient quantity of issues accumulates, then there’s a burst of intense activity as we focus our efforts. 33 | That makes development more efficient because it avoids expensive context switching between problems, at the cost of taking longer to get back to you. 34 | This process makes a good reprex particularly important because it might be multiple months between your initial report and when we start working on it. 35 | If we can’t reproduce the bug, we can’t fix it! 36 | -------------------------------------------------------------------------------- /R/writexlsx.R: -------------------------------------------------------------------------------- 1 | 2 | 3 | #' @name write.xlsx 4 | #' @title write data to an xlsx file 5 | #' @description write a data.frame or list of data.frames to an xlsx file 6 | #' @author Alexander Walker, Jordan Mark Barbone 7 | #' @inheritParams buildWorkbook 8 | #' @param file A file path to save the xlsx file 9 | #' @param overwrite Overwrite existing file (Defaults to `TRUE` as with `write.table`) 10 | #' @param ... Additional arguments passed to [buildWorkbook()]; see details 11 | #' 12 | #' @inheritSection buildWorkbook Optional Parameters 13 | #' 14 | #' @seealso [addWorksheet()] 15 | #' @seealso [writeData()] 16 | #' @seealso [createStyle()] for style parameters 17 | #' @seealso [buildWorkbook()] 18 | #' @return A workbook object 19 | #' @examples 20 | #' 21 | #' ## write to working directory 22 | #' options("openxlsx.borderColour" = "#4F80BD") ## set default border colour 23 | #' \dontrun{ 24 | #' write.xlsx(iris, file = "writeXLSX1.xlsx", colNames = TRUE, borders = "columns") 25 | #' write.xlsx(iris, file = "writeXLSX2.xlsx", colNames = TRUE, borders = "surrounding") 26 | #' } 27 | #' 28 | #' 29 | #' hs <- createStyle( 30 | #' textDecoration = "BOLD", fontColour = "#FFFFFF", fontSize = 12, 31 | #' fontName = "Arial Narrow", fgFill = "#4F80BD" 32 | #' ) 33 | #' \dontrun{ 34 | #' write.xlsx(iris, 35 | #' file = "writeXLSX3.xlsx", 36 | #' colNames = TRUE, borders = "rows", headerStyle = hs 37 | #' ) 38 | #' } 39 | #' 40 | #' ## Lists elements are written to individual worksheets, using list names as sheet names if available 41 | #' l <- list("IRIS" = iris, "MTCATS" = mtcars, matrix(runif(1000), ncol = 5)) 42 | #' \dontrun{ 43 | #' write.xlsx(l, "writeList1.xlsx", colWidths = c(NA, "auto", "auto")) 44 | #' } 45 | #' 46 | #' ## different sheets can be given different parameters 47 | #' \dontrun{ 48 | #' write.xlsx(l, "writeList2.xlsx", 49 | #' startCol = c(1, 2, 3), startRow = 2, 50 | #' asTable = c(TRUE, TRUE, FALSE), withFilter = c(TRUE, FALSE, FALSE) 51 | #' ) 52 | #' } 53 | #' 54 | #' # specify column widths for multiple sheets 55 | #' \dontrun{ 56 | #' write.xlsx(l, "writeList2.xlsx", colWidths = 20) 57 | #' write.xlsx(l, "writeList2.xlsx", colWidths = list(100, 200, 300)) 58 | #' write.xlsx(l, "writeList2.xlsx", colWidths = list(rep(10, 5), rep(8, 11), rep(5, 5))) 59 | #' } 60 | #' 61 | #' @export 62 | write.xlsx <- function(x, file, asTable = FALSE, overwrite = TRUE, ...) { 63 | if ("matrix" %in% class(x)){ 64 | x <- as.data.frame(x) 65 | } 66 | wb <- buildWorkbook(x, asTable = asTable, ...) 67 | saveWorkbook(wb, file = file, overwrite = overwrite) 68 | invisible(wb) 69 | } 70 | -------------------------------------------------------------------------------- /man/openxlsx.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/openxlsx.R 3 | \docType{package} 4 | \name{openxlsx} 5 | \alias{openxlsx-package} 6 | \alias{openxlsx} 7 | \title{xlsx reading, writing and editing.} 8 | \description{ 9 | openxlsx simplifies the the process of writing and styling Excel xlsx files from R 10 | and removes the dependency on Java. 11 | } 12 | \details{ 13 | The openxlsx package uses global options, most to simplify formatting. These 14 | are stored in the \code{op.openxlsx} object. 15 | 16 | \describe{ 17 | \item{openxlsx.bandedCols}{FALSE} 18 | \item{openxlsx.bandedRows}{TRUE} 19 | \item{openxlsx.borderColour}{"black"} 20 | \item{openxlsx.borders}{"none"} 21 | \item{openxlsx.borderStyle}{"thin"} 22 | \item{openxlsx.compressionLevel}{"9"} 23 | \item{openxlsx.creator}{""} 24 | \item{openxlsx.dateFormat}{"mm/dd/yyyy"} 25 | \item{openxlsx.datetimeFormat}{"yyyy-mm-dd hh:mm:ss"} 26 | \item{openxlsx.headerStyle}{NULL} 27 | \item{openxlsx.keepNA}{FALSE} 28 | \item{openxlsx.na.string}{NULL} 29 | \item{openxlsx.numFmt}{NULL} 30 | \item{openxlsx.orientation}{"portrait"} 31 | \item{openxlsx.paperSize}{9} 32 | \item{openxlsx.tabColour}{"TableStyleLight9"} 33 | \item{openxlsx.tableStyle}{"TableStyleLight9"} 34 | \item{openxlsx.withFilter}{NA Whether to write data with or without a 35 | filter. If NA will make filters with \code{writeDataTable} and will not for 36 | \code{writeData}} 37 | } 38 | 39 | See the Formatting vignette for examples. 40 | 41 | Additional options 42 | } 43 | \seealso{ 44 | \itemize{ 45 | \item{\code{vignette("Introduction", package = "openxlsx")}} 46 | \item{\code{vignette("formatting", package = "openxlsx")}} 47 | \item{\code{\link[=writeData]{writeData()}}} 48 | \item{\code{\link[=writeDataTable]{writeDataTable()}}} 49 | \item{\code{\link[=write.xlsx]{write.xlsx()}}} 50 | \item{\code{\link[=read.xlsx]{read.xlsx()}}} 51 | \item{\code{\link[=op.openxlsx]{op.openxlsx()}}} 52 | } 53 | for examples 54 | } 55 | \author{ 56 | \strong{Maintainer}: Jan Marvin Garbuszus \email{jan.garbuszus@ruhr-uni-bochum.de} [contributor] 57 | 58 | Authors: 59 | \itemize{ 60 | \item Philipp Schauberger \email{philipp@schauberger.co.at} 61 | \item Alexander Walker \email{Alexander.Walker1989@gmail.com} 62 | } 63 | 64 | Other contributors: 65 | \itemize{ 66 | \item Luca Braglia [contributor] 67 | \item Joshua Sturm [contributor] 68 | \item Jordan Mark Barbone \email{jmbarbone@gmail.com} (\href{https://orcid.org/0000-0001-9788-3628}{ORCID}) [contributor] 69 | \item David Zimmermann \email{david_j_zimmermann@hotmail.com} [contributor] 70 | \item Reinhold Kainhofer \email{reinhold@kainhofer.com} [contributor] 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /man/dataValidation.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/wrappers.R 3 | \name{dataValidation} 4 | \alias{dataValidation} 5 | \title{Add data validation to cells} 6 | \usage{ 7 | dataValidation( 8 | wb, 9 | sheet, 10 | cols, 11 | rows, 12 | type, 13 | operator, 14 | value, 15 | allowBlank = TRUE, 16 | showInputMsg = TRUE, 17 | showErrorMsg = TRUE 18 | ) 19 | } 20 | \arguments{ 21 | \item{wb}{A workbook object} 22 | 23 | \item{sheet}{A name or index of a worksheet} 24 | 25 | \item{cols}{Contiguous columns to apply conditional formatting to} 26 | 27 | \item{rows}{Contiguous rows to apply conditional formatting to} 28 | 29 | \item{type}{One of 'whole', 'decimal', 'date', 'time', 'textLength', 'list' (see examples)} 30 | 31 | \item{operator}{One of 'between', 'notBetween', 'equal', 32 | 'notEqual', 'greaterThan', 'lessThan', 'greaterThanOrEqual', 'lessThanOrEqual'} 33 | 34 | \item{value}{a vector of length 1 or 2 depending on operator (see examples)} 35 | 36 | \item{allowBlank}{logical} 37 | 38 | \item{showInputMsg}{logical} 39 | 40 | \item{showErrorMsg}{logical} 41 | } 42 | \description{ 43 | Add Excel data validation to cells 44 | } 45 | \examples{ 46 | wb <- createWorkbook() 47 | addWorksheet(wb, "Sheet 1") 48 | addWorksheet(wb, "Sheet 2") 49 | 50 | writeDataTable(wb, 1, x = iris[1:30, ]) 51 | 52 | dataValidation(wb, 1, 53 | col = 1:3, rows = 2:31, type = "whole", 54 | operator = "between", value = c(1, 9) 55 | ) 56 | 57 | dataValidation(wb, 1, 58 | col = 5, rows = 2:31, type = "textLength", 59 | operator = "between", value = c(4, 6) 60 | ) 61 | 62 | 63 | ## Date and Time cell validation 64 | df <- data.frame( 65 | "d" = as.Date("2016-01-01") + -5:5, 66 | "t" = as.POSIXct("2016-01-01") + -5:5 * 10000 67 | ) 68 | 69 | writeData(wb, 2, x = df) 70 | dataValidation(wb, 2, 71 | col = 1, rows = 2:12, type = "date", 72 | operator = "greaterThanOrEqual", value = as.Date("2016-01-01") 73 | ) 74 | 75 | dataValidation(wb, 2, 76 | col = 2, rows = 2:12, type = "time", 77 | operator = "between", value = df$t[c(4, 8)] 78 | ) 79 | \dontrun{ 80 | saveWorkbook(wb, "dataValidationExample.xlsx", overwrite = TRUE) 81 | } 82 | 83 | 84 | ###################################################################### 85 | ## If type == 'list' 86 | # operator argument is ignored. 87 | 88 | wb <- createWorkbook() 89 | addWorksheet(wb, "Sheet 1") 90 | addWorksheet(wb, "Sheet 2") 91 | 92 | writeDataTable(wb, sheet = 1, x = iris[1:30, ]) 93 | writeData(wb, sheet = 2, x = sample(iris$Sepal.Length, 10)) 94 | 95 | dataValidation(wb, 1, col = 1, rows = 2:31, type = "list", value = "'Sheet 2'!$A$1:$A$10") 96 | 97 | # openXL(wb) 98 | } 99 | -------------------------------------------------------------------------------- /.github/workflows/pr_commands.yaml: -------------------------------------------------------------------------------- 1 | # Workflow derived from https://github.com/r-lib/actions/tree/v2/examples 2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help 3 | on: 4 | issue_comment: 5 | types: [created] 6 | 7 | name: Commands 8 | 9 | jobs: 10 | document: 11 | if: ${{ github.event.issue.pull_request && (github.event.comment.author_association == 'MEMBER' || github.event.comment.author_association == 'OWNER') && startsWith(github.event.comment.body, '/document') }} 12 | name: document 13 | runs-on: ubuntu-latest 14 | env: 15 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 16 | steps: 17 | - uses: actions/checkout@v2 18 | 19 | - uses: r-lib/actions/pr-fetch@v2 20 | with: 21 | repo-token: ${{ secrets.GITHUB_TOKEN }} 22 | 23 | - uses: r-lib/actions/setup-r@v2 24 | with: 25 | use-public-rspm: true 26 | 27 | - uses: r-lib/actions/setup-r-dependencies@v2 28 | with: 29 | extra-packages: any::roxygen2 30 | needs: pr-document 31 | 32 | - name: Document 33 | run: roxygen2::roxygenise() 34 | shell: Rscript {0} 35 | 36 | - name: commit 37 | run: | 38 | git config --local user.name "$GITHUB_ACTOR" 39 | git config --local user.email "$GITHUB_ACTOR@users.noreply.github.com" 40 | git add man/\* NAMESPACE 41 | git commit -m 'Document' 42 | 43 | - uses: r-lib/actions/pr-push@v2 44 | with: 45 | repo-token: ${{ secrets.GITHUB_TOKEN }} 46 | 47 | style: 48 | if: ${{ github.event.issue.pull_request && (github.event.comment.author_association == 'MEMBER' || github.event.comment.author_association == 'OWNER') && startsWith(github.event.comment.body, '/style') }} 49 | name: style 50 | runs-on: ubuntu-latest 51 | env: 52 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 53 | steps: 54 | - uses: actions/checkout@v2 55 | 56 | - uses: r-lib/actions/pr-fetch@v2 57 | with: 58 | repo-token: ${{ secrets.GITHUB_TOKEN }} 59 | 60 | - uses: r-lib/actions/setup-r@v2 61 | 62 | - name: Install dependencies 63 | run: install.packages("styler") 64 | shell: Rscript {0} 65 | 66 | - name: Style 67 | run: styler::style_pkg() 68 | shell: Rscript {0} 69 | 70 | - name: commit 71 | run: | 72 | git config --local user.name "$GITHUB_ACTOR" 73 | git config --local user.email "$GITHUB_ACTOR@users.noreply.github.com" 74 | git add \*.R 75 | git commit -m 'Style' 76 | 77 | - uses: r-lib/actions/pr-push@v2 78 | with: 79 | repo-token: ${{ secrets.GITHUB_TOKEN }} -------------------------------------------------------------------------------- /R/asserts.R: -------------------------------------------------------------------------------- 1 | # Assertions for parameter validates 2 | # These should be used at the beginning of functions to stop execution early 3 | 4 | assert_class <- function(x, class, or_null = FALSE) { 5 | sx <- as.character(substitute(x)) 6 | ok <- inherits(x, class) 7 | 8 | if (or_null) { 9 | ok <- ok | is.null(x) 10 | class <- c(class, "null") 11 | } 12 | 13 | if (!ok) { 14 | msg <- sprintf("%s must be of class %s", sx, paste(class, collapse = " or ")) 15 | stop(msg, call. = FALSE) 16 | } 17 | } 18 | 19 | assert_length <- function(x, n) { 20 | stopifnot(is.integer(n)) 21 | if (length(x) != n) { 22 | msg <- sprintf("%s must be of length %iL", substitute(x), n) 23 | stop(msg, call. = FALSE) 24 | } 25 | } 26 | 27 | assert_true_false1 <- function(x) { 28 | if (!is_true_false(x)) { 29 | stop(substitute(x), " must be TRUE or FALSE", call. = FALSE) 30 | } 31 | } 32 | 33 | assert_true_false <- function(x) { 34 | ok <- is.logical(x) & !is.na(x) 35 | if (!ok) { 36 | stop(substitute(x), " must be a logical vector with NAs", call. = FALSE) 37 | } 38 | } 39 | 40 | assert_character1 <- function(x, scalar = FALSE) { 41 | ok <- is.character(x) && length(x) == 1L 42 | 43 | if (scalar) { 44 | ok <- ok & nchar(x) == 1L 45 | } 46 | 47 | if (!ok) { 48 | stop(substitute(x), " must be a character vector of length 1L", call. = FALSE) 49 | } 50 | } 51 | 52 | assert_unique <- function(x, case_sensitive = TRUE) { 53 | msg <- paste0(substitute(x), " must be a unique vector") 54 | 55 | if (!case_sensitive) { 56 | x <- tolower(x) 57 | msg <- paste0(msg, " (case sensitive)") 58 | } 59 | 60 | if (anyDuplicated(x) != 0L) { 61 | stop(msg, call. = FALSE) 62 | } 63 | } 64 | 65 | assert_numeric1 <- function(x, scalar = FALSE) { 66 | msg <- paste0(substitute(x), " must be a ") 67 | ok <- is.numeric(x) & length(x) == 1L 68 | 69 | if (scalar) { 70 | ok <- ok && nchar(x) == 1L 71 | msg <- paste0(msg, "single number") 72 | } else { 73 | msg <- paste0(msg, "numeric vector of length 1L") 74 | } 75 | 76 | if (!ok) { 77 | stop(msg, call. = FALSE) 78 | } 79 | } 80 | 81 | # validates --------------------------------------------------------------- 82 | 83 | validate_StyleName <- function(x) { 84 | m <- valid_StyleNames[match(tolower(x), valid_StyleNames_low)] 85 | if (anyNA(m)) { 86 | stop( 87 | "Invalid table style: ", 88 | paste0(sprintf("'%s'", x[is.na(m)]), collapse = ", "), 89 | call. = FALSE 90 | ) 91 | } 92 | m 93 | } 94 | 95 | valid_StyleNames <- c("none", paste0("TableStyleLight", 1:21), paste0("TableStyleMedium", 1:28), paste0("TableStyleDark", 1:11)) 96 | valid_StyleNames_low <- tolower(valid_StyleNames) 97 | -------------------------------------------------------------------------------- /.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to openxlsx 2 | 3 | This outlines how to propose a change to openxlsx. 4 | For more detailed info about contributing to this, and other tidyverse packages, please see the 5 | [**development contributing guide**](https://rstd.io/tidy-contrib). 6 | 7 | ## Fixing typos 8 | 9 | You can fix typos, spelling mistakes, or grammatical errors in the documentation directly using the GitHub web interface, as long as the changes are made in the _source_ file. 10 | This generally means you'll need to edit [roxygen2 comments](https://roxygen2.r-lib.org/articles/roxygen2.html) in an `.R`, not a `.Rd` file. 11 | You can find the `.R` file that generates the `.Rd` by reading the comment in the first line. 12 | 13 | ## Bigger changes 14 | 15 | If you want to make a bigger change, it's a good idea to first file an issue and make sure someone from the team agrees that it’s needed. 16 | If you’ve found a bug, please file an issue that illustrates the bug with a minimal 17 | [reprex](https://www.tidyverse.org/help/#reprex) (this will also help you write a unit test, if needed). 18 | 19 | ### Pull request process 20 | 21 | * Fork the package and clone onto your computer. If you haven't done this before, we recommend using `usethis::create_from_github("ycphs/openxlsx", fork = TRUE)`. 22 | 23 | * Install all development dependences with `devtools::install_dev_deps()`, and then make sure the package passes R CMD check by running `devtools::check()`. 24 | If R CMD check doesn't pass cleanly, it's a good idea to ask for help before continuing. 25 | * Create a Git branch for your pull request (PR). We recommend using `usethis::pr_init("brief-description-of-change")`. 26 | 27 | * Make your changes, commit to git, and then create a PR by running `usethis::pr_push()`, and following the prompts in your browser. 28 | The title of your PR should briefly describe the change. 29 | The body of your PR should contain `Fixes #issue-number`. 30 | 31 | * For user-facing changes, add a bullet to the top of `NEWS.md` (i.e. just below the first header). Follow the style described in . 32 | 33 | ### Code style 34 | 35 | * New code should follow the tidyverse [style guide](https://style.tidyverse.org). 36 | You can use the [styler](https://CRAN.R-project.org/package=styler) package to apply these styles, but please don't restyle code that has nothing to do with your PR. 37 | 38 | * We use [roxygen2](https://cran.r-project.org/package=roxygen2), with [Markdown syntax](https://cran.r-project.org/web/packages/roxygen2/vignettes/markdown.html), for documentation. 39 | 40 | * We use [testthat](https://cran.r-project.org/package=testthat) for unit tests. 41 | Contributions with test cases included are easier to accept. 42 | 43 | -------------------------------------------------------------------------------- /R/sheet_data_class.R: -------------------------------------------------------------------------------- 1 | 2 | 3 | #' @include class_definitions.R 4 | 5 | Sheet_Data$methods(initialize = function() { 6 | rows <<- integer(0) 7 | cols <<- integer(0) 8 | 9 | t <<- integer(0) 10 | v <<- character(0) 11 | f <<- character(0) 12 | 13 | style_id <<- character(0) 14 | 15 | data_count <<- 0L 16 | n_elements <<- 0L 17 | }) 18 | 19 | 20 | 21 | Sheet_Data$methods(delete = function(rows_in, cols_in, grid_expand) { 22 | cols_in <- convertFromExcelRef(cols_in) 23 | rows_in <- as.integer(rows_in) 24 | 25 | ## rows and cols need to be the same length 26 | if (grid_expand) { 27 | n <- length(rows_in) 28 | rows_in <- rep.int(rows_in, times = length(cols_in)) 29 | cols_in <- rep(cols_in, each = n) 30 | } 31 | 32 | if (length(rows_in) != length(cols_in)) { 33 | stop("Length of rows and cols must be equal.") 34 | } 35 | 36 | inds <- which(pair_rc(rows, cols) %in% pair_rc(rows_in, cols_in)) 37 | 38 | if (length(inds) > 0) { ## writing over existing data 39 | 40 | rows <<- rows[-inds] 41 | cols <<- cols[-inds] 42 | t <<- t[-inds] 43 | v <<- v[-inds] 44 | f <<- f[-inds] 45 | 46 | n_elements <<- as.integer(length(rows)) 47 | 48 | if (n_elements == 0) { 49 | data_count <<- 0L 50 | } 51 | } 52 | }) 53 | 54 | 55 | 56 | Sheet_Data$methods(write = function(rows_in, cols_in, t_in, v_in, f_in, any_functions = TRUE) { 57 | if (length(rows_in) == 0 | length(cols_in) == 0) { 58 | return(invisible(0)) 59 | } 60 | 61 | 62 | possible_overlap <- FALSE 63 | if (n_elements > 0) { 64 | possible_overlap <- (min(cols_in, na.rm = TRUE) <= max(cols, na.rm = TRUE)) & 65 | (max(cols_in, na.rm = TRUE) >= min(cols, na.rm = TRUE)) & 66 | (min(rows_in, na.rm = TRUE) <= max(rows, na.rm = TRUE)) & 67 | (max(rows_in, na.rm = TRUE) >= min(rows, na.rm = TRUE)) 68 | } 69 | 70 | n <- length(cols_in) 71 | cols_in <- rep.int(cols_in, times = length(rows_in)) 72 | rows_in <- rep(rows_in, each = n) 73 | 74 | if (any_functions) { 75 | if (any(!is.na(f_in))) { 76 | v_in[!is.na(f_in)] <- as.character(NA) 77 | t_in[!is.na(f_in)] <- 3L ## "str" 78 | } 79 | } 80 | 81 | inds <- integer(0) 82 | if (possible_overlap) { 83 | inds <- which(pair_rc(rows, cols) %in% pair_rc(rows_in, cols_in)) 84 | } 85 | 86 | if (length(inds) > 0) { 87 | rows <<- c(rows[-inds], rows_in) 88 | cols <<- c(cols[-inds], cols_in) 89 | t <<- c(t[-inds], t_in) 90 | v <<- c(v[-inds], v_in) 91 | f <<- c(f[-inds], f_in) 92 | } else { 93 | rows <<- c(rows, rows_in) 94 | cols <<- c(cols, cols_in) 95 | t <<- c(t, t_in) 96 | v <<- c(v, v_in) 97 | f <<- c(f, f_in) 98 | } 99 | 100 | n_elements <<- as.integer(length(rows)) 101 | data_count <<- data_count + 1L 102 | }) 103 | -------------------------------------------------------------------------------- /tests/testthat/test-encoding.R: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | context("Encoding Tests") 5 | 6 | 7 | 8 | test_that("Write read encoding equality", { 9 | tempFile <- temp_xlsx() 10 | 11 | wb <- createWorkbook() 12 | for (i in 1:4) { 13 | addWorksheet(wb, sprintf("Sheet %s", i)) 14 | } 15 | 16 | df <- data.frame("X" = c("测试", "一下"), stringsAsFactors = FALSE) 17 | writeDataTable(wb, sheet = 1, x = df) 18 | 19 | saveWorkbook(wb, tempFile, overwrite = TRUE) 20 | 21 | x <- read.xlsx(tempFile) 22 | expect_equal(x, df) 23 | 24 | x <- read.xlsx(wb) 25 | expect_equal(x, df) 26 | 27 | ## reload 28 | wb <- loadWorkbook(tempFile) 29 | 30 | x <- read.xlsx(wb) 31 | expect_equal(x, df) 32 | 33 | saveWorkbook(wb, tempFile, overwrite = TRUE) 34 | x <- read.xlsx(tempFile) 35 | expect_equal(x, df) 36 | 37 | unlink(tempFile, recursive = TRUE, force = TRUE) 38 | rm(wb) 39 | }) 40 | 41 | 42 | test_that("Support non-ASCII strings not in UTF-8 encodings", { 43 | non_ascii <- c("\u4f60\u597d", "\u4e2d\u6587", "\u6c49\u5b57", 44 | "\u5de5\u4f5c\u7c3f1", "\u6d4b\u8bd5\u540d\u5b571", 45 | "\u6d4b2", "\u5de52", "\u5de5\u4f5c3") 46 | # Ideally, we should test against native encodings. However, the testing machine's 47 | # locale encoding may not be able to represent the non-ascii letters, when 48 | # it's the case, we use the UTF-8 encoding as it is. 49 | if (identical( enc2utf8(enc2native(non_ascii)), non_ascii )) { 50 | non_ascii <- enc2native(non_ascii) 51 | } 52 | non_ascii_df <- data.frame( 53 | X = non_ascii, Y = seq_along(non_ascii), stringsAsFactors = FALSE 54 | ) 55 | colnames(non_ascii_df) <- non_ascii[3:4] 56 | file <- temp_xlsx() 57 | wb <- createWorkbook(creator = non_ascii[1]) 58 | ws <- addWorksheet(wb, non_ascii[2]) 59 | writeDataTable(wb, ws, non_ascii_df, tableName = non_ascii[3]) 60 | writeData(wb, ws, non_ascii_df, xy = list("D", 1), name = non_ascii[4]) 61 | writeComment(wb, ws, 1, 1, comment = createComment(non_ascii[5], non_ascii[6])) 62 | writeFormula(wb, ws, x = sprintf('"%s"&"%s"', non_ascii[1], non_ascii[2]), xy = list("G", 1)) 63 | createNamedRegion(wb, ws, 7, 1, name = non_ascii[7]) 64 | saveWorkbook(wb, file) 65 | 66 | wb2 <- loadWorkbook(file) 67 | expect_equal( 68 | getCreators(wb2), non_ascii[1] 69 | ) 70 | expect_equal( 71 | getSheetNames(file), non_ascii[2] 72 | ) 73 | expect_equivalent( 74 | getTables(wb2, ws), non_ascii[3] 75 | ) 76 | expect_equivalent( 77 | getNamedRegions(wb2), non_ascii[c(4, 7)] 78 | ) 79 | expect_equal( 80 | wb2$comments[[1]][[1]][c("comment", "author")], 81 | setNames(as.list(non_ascii[5:6]), c("comment", "author")) 82 | ) 83 | expect_equal( 84 | read.xlsx(file, ws, cols = 1:2), 85 | non_ascii_df 86 | ) 87 | expect_equal( 88 | read.xlsx(file, ws, cols = 4:5), 89 | non_ascii_df 90 | ) 91 | }) 92 | -------------------------------------------------------------------------------- /man/protectWorksheet.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/wrappers.R 3 | \name{protectWorksheet} 4 | \alias{protectWorksheet} 5 | \title{Protect a worksheet from modifications} 6 | \usage{ 7 | protectWorksheet( 8 | wb, 9 | sheet, 10 | protect = TRUE, 11 | password = NULL, 12 | lockSelectingLockedCells = NULL, 13 | lockSelectingUnlockedCells = NULL, 14 | lockFormattingCells = NULL, 15 | lockFormattingColumns = NULL, 16 | lockFormattingRows = NULL, 17 | lockInsertingColumns = NULL, 18 | lockInsertingRows = NULL, 19 | lockInsertingHyperlinks = NULL, 20 | lockDeletingColumns = NULL, 21 | lockDeletingRows = NULL, 22 | lockSorting = NULL, 23 | lockAutoFilter = NULL, 24 | lockPivotTables = NULL, 25 | lockObjects = NULL, 26 | lockScenarios = NULL 27 | ) 28 | } 29 | \arguments{ 30 | \item{wb}{A workbook object} 31 | 32 | \item{sheet}{A name or index of a worksheet} 33 | 34 | \item{protect}{Whether to protect or unprotect the sheet (default=TRUE)} 35 | 36 | \item{password}{(optional) password required to unprotect the worksheet} 37 | 38 | \item{lockSelectingLockedCells}{Whether selecting locked cells is locked} 39 | 40 | \item{lockSelectingUnlockedCells}{Whether selecting unlocked cells is locked} 41 | 42 | \item{lockFormattingCells}{Whether formatting cells is locked} 43 | 44 | \item{lockFormattingColumns}{Whether formatting columns is locked} 45 | 46 | \item{lockFormattingRows}{Whether formatting rows is locked} 47 | 48 | \item{lockInsertingColumns}{Whether inserting columns is locked} 49 | 50 | \item{lockInsertingRows}{Whether inserting rows is locked} 51 | 52 | \item{lockInsertingHyperlinks}{Whether inserting hyperlinks is locked} 53 | 54 | \item{lockDeletingColumns}{Whether deleting columns is locked} 55 | 56 | \item{lockDeletingRows}{Whether deleting rows is locked} 57 | 58 | \item{lockSorting}{Whether sorting is locked} 59 | 60 | \item{lockAutoFilter}{Whether auto-filter is locked} 61 | 62 | \item{lockPivotTables}{Whether pivot tables are locked} 63 | 64 | \item{lockObjects}{Whether objects are locked} 65 | 66 | \item{lockScenarios}{Whether scenarios are locked} 67 | } 68 | \description{ 69 | Protect or unprotect a worksheet from modifications by the user in the graphical user interface. Replaces an existing protection. 70 | } 71 | \examples{ 72 | wb <- createWorkbook() 73 | addWorksheet(wb, "S1") 74 | writeDataTable(wb, 1, x = iris[1:30, ]) 75 | # Formatting cells / columns is allowed , but inserting / deleting columns is protected: 76 | protectWorksheet(wb, "S1", 77 | protect = TRUE, 78 | lockFormattingCells = FALSE, lockFormattingColumns = FALSE, 79 | lockInsertingColumns = TRUE, lockDeletingColumns = TRUE 80 | ) 81 | 82 | # Remove the protection 83 | protectWorksheet(wb, "S1", protect = FALSE) 84 | \dontrun{ 85 | saveWorkbook(wb, "pageSetupExample.xlsx", overwrite = TRUE) 86 | } 87 | } 88 | \author{ 89 | Reinhold Kainhofer 90 | } 91 | -------------------------------------------------------------------------------- /man/readWorkbook.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/readWorkbook.R 3 | \name{readWorkbook} 4 | \alias{readWorkbook} 5 | \title{Read from an Excel file or Workbook object} 6 | \usage{ 7 | readWorkbook( 8 | xlsxFile, 9 | sheet = 1, 10 | startRow = 1, 11 | colNames = TRUE, 12 | rowNames = FALSE, 13 | detectDates = FALSE, 14 | skipEmptyRows = TRUE, 15 | skipEmptyCols = TRUE, 16 | rows = NULL, 17 | cols = NULL, 18 | check.names = FALSE, 19 | sep.names = ".", 20 | namedRegion = NULL, 21 | na.strings = "NA", 22 | fillMergedCells = FALSE 23 | ) 24 | } 25 | \arguments{ 26 | \item{xlsxFile}{An xlsx file, Workbook object or URL to xlsx file.} 27 | 28 | \item{sheet}{The name or index of the sheet to read data from.} 29 | 30 | \item{startRow}{first row to begin looking for data. Empty rows at the top of a file are always skipped, 31 | regardless of the value of startRow.} 32 | 33 | \item{colNames}{If \code{TRUE}, the first row of data will be used as column names.} 34 | 35 | \item{rowNames}{If \code{TRUE}, first column of data will be used as row names.} 36 | 37 | \item{detectDates}{If \code{TRUE}, attempt to recognise dates and perform conversion.} 38 | 39 | \item{skipEmptyRows}{If \code{TRUE}, empty rows are skipped else empty rows after the first row containing data 40 | will return a row of NAs.} 41 | 42 | \item{skipEmptyCols}{If \code{TRUE}, empty columns are skipped.} 43 | 44 | \item{rows}{A numeric vector specifying which rows in the Excel file to read. 45 | If NULL, all rows are read.} 46 | 47 | \item{cols}{A numeric vector specifying which columns in the Excel file to read. 48 | If NULL, all columns are read.} 49 | 50 | \item{check.names}{logical. If TRUE then the names of the variables in the data frame 51 | are checked to ensure that they are syntactically valid variable names} 52 | 53 | \item{sep.names}{One character which substitutes blanks in column names. By default, "."} 54 | 55 | \item{namedRegion}{A named region in the Workbook. If not NULL startRow, rows and cols parameters are ignored.} 56 | 57 | \item{na.strings}{A character vector of strings which are to be interpreted as NA. Blank cells will be returned as NA.} 58 | 59 | \item{fillMergedCells}{If TRUE, the value in a merged cell is given to all cells within the merge.} 60 | } 61 | \value{ 62 | data.frame 63 | } 64 | \description{ 65 | Read data from an Excel file or Workbook object into a data.frame 66 | } 67 | \details{ 68 | Creates a data.frame of all data in worksheet. 69 | } 70 | \examples{ 71 | xlsxFile <- system.file("extdata", "readTest.xlsx", package = "openxlsx") 72 | df1 <- readWorkbook(xlsxFile = xlsxFile, sheet = 1) 73 | 74 | xlsxFile <- system.file("extdata", "readTest.xlsx", package = "openxlsx") 75 | df1 <- readWorkbook(xlsxFile = xlsxFile, sheet = 1, rows = c(1, 3, 5), cols = 1:3) 76 | } 77 | \seealso{ 78 | \code{\link[=getNamedRegions]{getNamedRegions()}} 79 | 80 | \code{\link[=read.xlsx]{read.xlsx()}} 81 | } 82 | \author{ 83 | Alexander Walker 84 | } 85 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [openxlsx](https://ycphs.github.io/openxlsx/) 2 | ======== 3 | 4 | 5 | [![codecov](https://codecov.io/gh/ycphs/openxlsx/branch/master/graph/badge.svg)](https://app.codecov.io/gh/ycphs/openxlsx) 6 | [![CRAN_Status_Badge](https://www.r-pkg.org/badges/version/openxlsx)](https://cran.r-project.org/package=openxlsx) 7 | [![CRAN RStudio mirror downloads](https://cranlogs.r-pkg.org/badges/openxlsx)](https://cran.r-project.org/package=openxlsx) 8 | [![R-CMD-check](https://github.com/ycphs/openxlsx/actions/workflows/R-CMD-check.yaml/badge.svg?branch=master)](https://github.com/ycphs/openxlsx/actions/workflows/R-CMD-check.yaml) 9 | 10 | This [R](https://www.R-project.org/) package simplifies the creation of `.xlsx` 11 | files by providing a high level interface to writing, styling and editing 12 | worksheets. Through the use of [`Rcpp`](https://CRAN.R-project.org/package=Rcpp), 13 | read/write times are comparable to the [`xlsx`](https://CRAN.R-project.org/package=xlsx) 14 | and [`XLConnect`](https://CRAN.R-project.org/package=XLConnect) packages with 15 | the added benefit of removing the dependency on Java. 16 | 17 | **Note:** `openxlsx` is no longer under active development. The package is 18 | maintained, and CRAN warnings will be fixed, but non-critical issues will not be 19 | addressed unless accompanied by a pull request. Packages that depend on 20 | `openxlsx` do not need to take any action, but for new developments, users are 21 | encouraged to use alternatives like `readxl`, `writexl`, or `openxlsx2`. The 22 | first two packages provide support for reading and writing `.xlsx` files. The 23 | latter package is a modern reinterpretation of `openxlsx` and provides similar 24 | functions to modify worksheets. However, it is not a drop-in replacement, so you 25 | may want to consult resources like the 26 | [update vignette](https://janmarvin.github.io/openxlsx2/articles/Update-from-openxlsx.html). 27 | 28 | 29 | ## Installation 30 | 31 | ### Stable version 32 | 33 | Current stable version is available on [CRAN](https://CRAN.R-project.org/) via 34 | 35 | ```R 36 | install.packages("openxlsx", dependencies = TRUE) 37 | ``` 38 | 39 | ### Development version 40 | ```R 41 | install.packages(c("Rcpp", "remotes"), dependencies = TRUE) 42 | remotes::install_github("ycphs/openxlsx") 43 | ``` 44 | 45 | ## Example 46 | 47 | Explore the package with a simple example: 48 | 49 | ```R 50 | library(openxlsx) 51 | 52 | # Create a new workbook and add a sheet 53 | wb <- createWorkbook() 54 | addWorksheet(wb, "Sheet 1") 55 | 56 | # Write data to the sheet 57 | writeData(wb, "Sheet 1", mtcars) 58 | 59 | # Save the workbook 60 | saveWorkbook(wb, "my_mtcars.xlsx", overwrite = TRUE) 61 | ``` 62 | 63 | ## Bug/feature request 64 | Please let us know which version of `openxlsx` you are using when posting bug reports. 65 | ```R 66 | packageVersion("openxlsx") 67 | ``` 68 | 69 | ## News 70 | You can find the NEWS file [here](https://raw.githubusercontent.com/ycphs/openxlsx/master/NEWS.md). 71 | -------------------------------------------------------------------------------- /R/HyperlinkClass.R: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Hyperlink <- setRefClass("Hyperlink", 5 | fields = c( 6 | "ref", 7 | "target", 8 | "location", 9 | "display", 10 | "is_external" 11 | ), 12 | 13 | methods = list() 14 | ) 15 | 16 | 17 | Hyperlink$methods(initialize = function(ref, target, location, display = NULL, is_external = TRUE) { 18 | ref <<- ref 19 | target <<- target 20 | location <<- location 21 | display <<- display 22 | is_external <<- is_external 23 | }) 24 | 25 | Hyperlink$methods(to_xml = function(id) { 26 | loc <- sprintf('location="%s"', location) 27 | disp <- sprintf('display="%s"', display) 28 | rf <- sprintf('ref="%s"', ref) 29 | 30 | if (is_external) { 31 | rid <- sprintf('r:id="rId%s"', id) 32 | } else { 33 | rid <- NULL 34 | } 35 | 36 | paste("") 37 | }) 38 | 39 | Hyperlink$methods(to_target_xml = function(id) { 40 | if (is_external) { 41 | return(sprintf('', id, target)) 42 | } else { 43 | return(NULL) 44 | } 45 | }) 46 | 47 | 48 | 49 | xml_to_hyperlink <- function(xml) { 50 | 51 | # xml <- c('', 52 | # '', 53 | # '') 54 | 55 | if (length(xml) == 0) { 56 | return(xml) 57 | } 58 | 59 | targets <- names(xml) 60 | if (is.null(targets)) { 61 | targets <- rep(NA, length(xml)) 62 | } 63 | 64 | xml <- unname(xml) 65 | 66 | a <- unlist(lapply(xml, function(x) regmatches(x, gregexpr('[a-zA-Z]+=".*?"', x))), recursive = FALSE) 67 | names <- lapply(a, function(xml) regmatches(xml, regexpr('[a-zA-Z]+(?=\\=".*?")', xml, perl = TRUE))) 68 | vals <- lapply(a, function(xml) regmatches(xml, regexpr('(?<=").*?(?=")', xml, perl = TRUE))) 69 | vals <- lapply(vals, function(x) { 70 | Encoding(x) <- "UTF-8" 71 | x 72 | }) 73 | 74 | hyperlink_objects <- lapply(seq_along(xml), function(i) { 75 | tmp_vals <- vals[[i]] 76 | tmp_nms <- names[[i]] 77 | names(tmp_vals) <- tmp_nms 78 | 79 | ## ref 80 | ref <- tmp_vals[["ref"]] 81 | 82 | ## location 83 | if ("location" %in% tmp_nms) { 84 | location <- tmp_vals[["location"]] 85 | } else { 86 | location <- NULL 87 | } 88 | 89 | ## location 90 | if ("display" %in% tmp_nms) { 91 | display <- tmp_vals[["display"]] 92 | } else { 93 | display <- NULL 94 | } 95 | 96 | ## target/external 97 | if (is.na(targets[i])) { 98 | target <- NULL 99 | is_external <- FALSE 100 | } else { 101 | is_external <- TRUE 102 | target <- targets[i] 103 | } 104 | 105 | Hyperlink$new(ref = ref, target = target, location = location, display = display, is_external = is_external) 106 | }) 107 | 108 | return(hyperlink_objects) 109 | } 110 | -------------------------------------------------------------------------------- /man/makeHyperlinkString.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/helperFunctions.R 3 | \name{makeHyperlinkString} 4 | \alias{makeHyperlinkString} 5 | \title{create Excel hyperlink string} 6 | \usage{ 7 | makeHyperlinkString(sheet, row = 1, col = 1, text = NULL, file = NULL) 8 | } 9 | \arguments{ 10 | \item{sheet}{Name of a worksheet} 11 | 12 | \item{row}{integer row number for hyperlink to link to} 13 | 14 | \item{col}{column number of letter for hyperlink to link to} 15 | 16 | \item{text}{display text} 17 | 18 | \item{file}{Excel file name to point to. If NULL hyperlink is internal.} 19 | } 20 | \description{ 21 | Wrapper to create internal hyperlink string to pass to writeFormula(). Either link to external urls or local files or straight to cells of local Excel sheets. 22 | } 23 | \examples{ 24 | 25 | ## Writing internal hyperlinks 26 | wb <- createWorkbook() 27 | addWorksheet(wb, "Sheet1") 28 | addWorksheet(wb, "Sheet2") 29 | addWorksheet(wb, "Sheet 3") 30 | writeData(wb, sheet = 3, x = iris) 31 | 32 | ## External Hyperlink 33 | x <- c("https://www.google.com", "https://www.google.com.au") 34 | names(x) <- c("google", "google Aus") 35 | class(x) <- "hyperlink" 36 | 37 | writeData(wb, sheet = 1, x = x, startCol = 10) 38 | 39 | 40 | ## Internal Hyperlink - create hyperlink formula manually 41 | writeFormula( 42 | wb, "Sheet1", 43 | x = '=HYPERLINK(\"#Sheet2!B3\", "Text to Display - Link to Sheet2")', 44 | startCol = 3 45 | ) 46 | 47 | ## Internal - No text to display using makeHyperlinkString() function 48 | writeFormula( 49 | wb, "Sheet1", 50 | startRow = 1, 51 | x = makeHyperlinkString(sheet = "Sheet 3", row = 1, col = 2) 52 | ) 53 | 54 | ## Internal - Text to display 55 | writeFormula( 56 | wb, "Sheet1", 57 | startRow = 2, 58 | x = makeHyperlinkString( 59 | sheet = "Sheet 3", row = 1, col = 2, 60 | text = "Link to Sheet 3" 61 | ) 62 | ) 63 | 64 | ## Link to file - No text to display 65 | writeFormula( 66 | wb, "Sheet1", 67 | startRow = 4, 68 | x = makeHyperlinkString( 69 | sheet = "testing", row = 3, col = 10, 70 | file = system.file("extdata", "loadExample.xlsx", package = "openxlsx") 71 | ) 72 | ) 73 | 74 | ## Link to file - Text to display 75 | writeFormula( 76 | wb, "Sheet1", 77 | startRow = 3, 78 | x = makeHyperlinkString( 79 | sheet = "testing", row = 3, col = 10, 80 | file = system.file("extdata", "loadExample.xlsx", package = "openxlsx"), 81 | text = "Link to File." 82 | ) 83 | ) 84 | 85 | ## Link to external file - Text to display 86 | writeFormula( 87 | wb, "Sheet1", 88 | startRow = 10, startCol = 1, 89 | x = '=HYPERLINK("[C:/Users]", "Link to an external file")' 90 | ) 91 | 92 | ## Link to internal file 93 | x = makeHyperlinkString(text = "test.png", file = "D:/somepath/somepicture.png") 94 | writeFormula(wb, "Sheet1", startRow = 11, startCol = 1, x = x) 95 | 96 | \dontrun{ 97 | saveWorkbook(wb, "internalHyperlinks.xlsx", overwrite = TRUE) 98 | } 99 | 100 | } 101 | \seealso{ 102 | \code{\link[=writeFormula]{writeFormula()}} 103 | } 104 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | S3method("names<-",Workbook) 4 | S3method(as.character,formula) 5 | S3method(getNamedRegions,Workbook) 6 | S3method(getNamedRegions,default) 7 | S3method(names,Workbook) 8 | S3method(read.xlsx,Workbook) 9 | S3method(read.xlsx,default) 10 | export("activeSheet<-") 11 | export("sheetVisibility<-") 12 | export("sheetVisible<-") 13 | export("worksheetOrder<-") 14 | export(activeSheet) 15 | export(addCreator) 16 | export(addFilter) 17 | export(addStyle) 18 | export(addWorksheet) 19 | export(auto_heights) 20 | export(buildWorkbook) 21 | export(cloneWorksheet) 22 | export(col2int) 23 | export(conditionalFormat) 24 | export(conditionalFormatting) 25 | export(convertFromExcelRef) 26 | export(convertToDate) 27 | export(convertToDateTime) 28 | export(copyWorkbook) 29 | export(createComment) 30 | export(createNamedRegion) 31 | export(createStyle) 32 | export(createWorkbook) 33 | export(dataValidation) 34 | export(deleteData) 35 | export(deleteDataColumn) 36 | export(deleteNamedRegion) 37 | export(freezePane) 38 | export(getBaseFont) 39 | export(getCellRefs) 40 | export(getCreators) 41 | export(getDateOrigin) 42 | export(getNamedRegions) 43 | export(getSheetNames) 44 | export(getStyles) 45 | export(getTables) 46 | export(getWindowSize) 47 | export(get_worksheet_entries) 48 | export(groupColumns) 49 | export(groupRows) 50 | export(insertImage) 51 | export(insertPlot) 52 | export(int2col) 53 | export(loadWorkbook) 54 | export(makeHyperlinkString) 55 | export(mergeCells) 56 | export(modifyBaseFont) 57 | export(op.openxlsx) 58 | export(openXL) 59 | export(openxlsx_getOp) 60 | export(openxlsx_setOp) 61 | export(pageBreak) 62 | export(pageSetup) 63 | export(protectWorkbook) 64 | export(protectWorksheet) 65 | export(read.xlsx) 66 | export(readWorkbook) 67 | export(removeCellMerge) 68 | export(removeColWidths) 69 | export(removeComment) 70 | export(removeFilter) 71 | export(removeRowHeights) 72 | export(removeTable) 73 | export(removeWorksheet) 74 | export(renameWorksheet) 75 | export(replaceStyle) 76 | export(saveWorkbook) 77 | export(setColWidths) 78 | export(setFooter) 79 | export(setHeader) 80 | export(setHeaderFooter) 81 | export(setLastModifiedBy) 82 | export(setRowHeights) 83 | export(setWindowSize) 84 | export(sheetVisibility) 85 | export(sheetVisible) 86 | export(sheets) 87 | export(showGridLines) 88 | export(temp_xlsx) 89 | export(ungroupColumns) 90 | export(ungroupRows) 91 | export(worksheetOrder) 92 | export(write.xlsx) 93 | export(writeComment) 94 | export(writeData) 95 | export(writeDataTable) 96 | export(writeFormula) 97 | import(Rcpp) 98 | import(methods) 99 | import(stringi) 100 | importFrom(grDevices,bmp) 101 | importFrom(grDevices,col2rgb) 102 | importFrom(grDevices,colours) 103 | importFrom(grDevices,dev.copy) 104 | importFrom(grDevices,dev.list) 105 | importFrom(grDevices,dev.off) 106 | importFrom(grDevices,jpeg) 107 | importFrom(grDevices,png) 108 | importFrom(grDevices,rgb) 109 | importFrom(grDevices,tiff) 110 | importFrom(stats,pchisq) 111 | importFrom(utils,download.file) 112 | importFrom(utils,head) 113 | importFrom(utils,menu) 114 | importFrom(utils,unzip) 115 | importFrom(zip,zipr) 116 | useDynLib(openxlsx, .registration=TRUE) 117 | -------------------------------------------------------------------------------- /man/setHeaderFooter.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/wrappers.R 3 | \name{setHeaderFooter} 4 | \alias{setHeaderFooter} 5 | \title{Set document headers and footers} 6 | \usage{ 7 | setHeaderFooter( 8 | wb, 9 | sheet, 10 | header = NULL, 11 | footer = NULL, 12 | evenHeader = NULL, 13 | evenFooter = NULL, 14 | firstHeader = NULL, 15 | firstFooter = NULL 16 | ) 17 | } 18 | \arguments{ 19 | \item{wb}{A workbook object} 20 | 21 | \item{sheet}{A name or index of a worksheet} 22 | 23 | \item{header}{document header. Character vector of length 3 corresponding to positions left, center, right. Use NA to skip a position.} 24 | 25 | \item{footer}{document footer. Character vector of length 3 corresponding to positions left, center, right. Use NA to skip a position.} 26 | 27 | \item{evenHeader}{document header for even pages.} 28 | 29 | \item{evenFooter}{document footer for even pages.} 30 | 31 | \item{firstHeader}{document header for first page only.} 32 | 33 | \item{firstFooter}{document footer for first page only.} 34 | } 35 | \description{ 36 | Set document headers and footers 37 | } 38 | \details{ 39 | Headers and footers can contain special tags 40 | \describe{ 41 | \item{\strong{&[Page]}}{ Page number} 42 | \item{\strong{&[Pages]}}{ Number of pages} 43 | \item{\strong{&[Date]}}{ Current date} 44 | \item{\strong{&[Time]}}{ Current time} 45 | \item{\strong{&[Path]}}{ File path} 46 | \item{\strong{&[File]}}{ File name} 47 | \item{\strong{&[Tab]}}{ Worksheet name} 48 | } 49 | } 50 | \examples{ 51 | wb <- createWorkbook() 52 | 53 | addWorksheet(wb, "S1") 54 | addWorksheet(wb, "S2") 55 | addWorksheet(wb, "S3") 56 | addWorksheet(wb, "S4") 57 | 58 | writeData(wb, 1, 1:400) 59 | writeData(wb, 2, 1:400) 60 | writeData(wb, 3, 3:400) 61 | writeData(wb, 4, 3:400) 62 | 63 | setHeaderFooter(wb, 64 | sheet = "S1", 65 | header = c("ODD HEAD LEFT", "ODD HEAD CENTER", "ODD HEAD RIGHT"), 66 | footer = c("ODD FOOT RIGHT", "ODD FOOT CENTER", "ODD FOOT RIGHT"), 67 | evenHeader = c("EVEN HEAD LEFT", "EVEN HEAD CENTER", "EVEN HEAD RIGHT"), 68 | evenFooter = c("EVEN FOOT RIGHT", "EVEN FOOT CENTER", "EVEN FOOT RIGHT"), 69 | firstHeader = c("TOP", "OF FIRST", "PAGE"), 70 | firstFooter = c("BOTTOM", "OF FIRST", "PAGE") 71 | ) 72 | 73 | setHeaderFooter(wb, 74 | sheet = 2, 75 | header = c("&[Date]", "ALL HEAD CENTER 2", "&[Page] / &[Pages]"), 76 | footer = c("&[Path]&[File]", NA, "&[Tab]"), 77 | firstHeader = c(NA, "Center Header of First Page", NA), 78 | firstFooter = c(NA, "Center Footer of First Page", NA) 79 | ) 80 | 81 | setHeaderFooter(wb, 82 | sheet = 3, 83 | header = c("ALL HEAD LEFT 2", "ALL HEAD CENTER 2", "ALL HEAD RIGHT 2"), 84 | footer = c("ALL FOOT RIGHT 2", "ALL FOOT CENTER 2", "ALL FOOT RIGHT 2") 85 | ) 86 | 87 | setHeaderFooter(wb, 88 | sheet = 4, 89 | firstHeader = c("FIRST ONLY L", NA, "FIRST ONLY R"), 90 | firstFooter = c("FIRST ONLY L", NA, "FIRST ONLY R") 91 | ) 92 | \dontrun{ 93 | saveWorkbook(wb, "setHeaderFooterExample.xlsx", overwrite = TRUE) 94 | } 95 | } 96 | \seealso{ 97 | \code{\link[=addWorksheet]{addWorksheet()}} to set headers and footers when adding a worksheet 98 | } 99 | \author{ 100 | Alexander Walker 101 | } 102 | --------------------------------------------------------------------------------