{"id":20128634,"url":"https://github.com/coreoffice/corexlsx","last_synced_at":"2025-05-16T13:06:46.843Z","repository":{"id":42443005,"uuid":"155008500","full_name":"CoreOffice/CoreXLSX","owner":"CoreOffice","description":"Excel spreadsheet (XLSX) format parser written in pure Swift","archived":false,"fork":false,"pushed_at":"2024-03-25T09:25:21.000Z","size":1772,"stargazers_count":796,"open_issues_count":27,"forks_count":77,"subscribers_count":26,"default_branch":"main","last_synced_at":"2024-05-23T02:36:22.343Z","etag":null,"topics":["excel","excel-import","excelparser","excelreader","ios","macos","office","parser","swift","tvos","watchos","xml"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/CoreOffice.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE.md","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"MaxDesiatov","patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"custom":null}},"created_at":"2018-10-27T20:55:43.000Z","updated_at":"2024-06-18T22:51:40.938Z","dependencies_parsed_at":"2023-07-13T11:17:44.439Z","dependency_job_id":"20c3e6f8-d724-496a-bd17-f04ec4a1a9db","html_url":"https://github.com/CoreOffice/CoreXLSX","commit_stats":{"total_commits":258,"total_committers":13,"mean_commits":"19.846153846153847","dds":0.0736434108527132,"last_synced_commit":"1391f3832ea2eeee5186ea8abb81ea49ed0609cc"},"previous_names":["maxdesiatov/corexlsx"],"tags_count":24,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CoreOffice%2FCoreXLSX","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CoreOffice%2FCoreXLSX/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CoreOffice%2FCoreXLSX/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CoreOffice%2FCoreXLSX/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/CoreOffice","download_url":"https://codeload.github.com/CoreOffice/CoreXLSX/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247999859,"owners_count":21031046,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["excel","excel-import","excelparser","excelreader","ios","macos","office","parser","swift","tvos","watchos","xml"],"created_at":"2024-11-13T20:28:34.464Z","updated_at":"2025-04-09T08:06:18.369Z","avatar_url":"https://github.com/CoreOffice.png","language":"Swift","readme":"# CoreXLSX\n\n## Excel spreadsheet (XLSX) format parser written in pure Swift\n\n[![Build Status](https://dev.azure.com/CoreOffice/CoreOffice/_apis/build/status/CoreOffice.CoreXLSX?branchName=main)](https://dev.azure.com/CoreOffice/CoreOffice/_build/latest?definitionId=1\u0026branchName=main)\n[![Version](https://img.shields.io/cocoapods/v/CoreXLSX.svg?style=flat)](https://cocoapods.org/pods/CoreXLSX)\n[![License](https://img.shields.io/cocoapods/l/CoreXLSX.svg?style=flat)](https://cocoapods.org/pods/CoreXLSX)\n![Platform](https://img.shields.io/badge/platform-watchos%20%7C%20ios%20%7C%20tvos%20%7C%20macos%20%7C%20linux-lightgrey.svg?style=flat)\n[![Coverage](https://img.shields.io/codecov/c/github/CoreOffice/CoreXLSX/main.svg?style=flat)](https://codecov.io/gh/CoreOffice/CoreXLSX)\n\nCoreXLSX is a library focused on representing the low-level structure\nof [the XML-based XLSX spreadsheet\nformat](https://en.wikipedia.org/wiki/Office_Open_XML). It allows you to open a\nspreadsheet archive with `.xlsx` extension and map its internal structure into\nmodel types expressed directly in Swift.\n\nImportant to note that this library provides read-only support only for [the `.xlsx`\nformat](https://en.wikipedia.org/wiki/Office_Open_XML). As the older\n[legacy `.xls` spreadsheet\nformat](https://en.wikipedia.org/wiki/Microsoft_Excel#File_formats)\nhas completely different internals, please refer to [other\nlibraries](https://github.com/libxls/libxls) if you need to work with files of\nthat type.\n\nIf your `.xlsx` files use [ECMA-376 agile\nencryption](https://docs.microsoft.com/en-us/openspecs/office_file_formats/ms-offcrypto/cab78f5c-9c17-495e-bea9-032c63f02ad8) (which seems to be the most popular variety), have a look at the\n[CryptoOffice](https://github.com/CoreOffice/CryptoOffice) library.\n\nAutomatically generated documentation is available on [our GitHub Pages](https://coreoffice.github.io/CoreXLSX/).\n\n[Join our Discord](https://discord.gg/H6799jh) for any questions and friendly banter.\n\n## Example\n\nTo run the example project, clone the repo, and run `pod install` from the\nExample directory first.\n\nModel types in `CoreXLSX` directly map internal structure of XLSX format with\nmore sensible naming applied to a few attributes. The API is pretty simple:\n\n```swift\nimport CoreXLSX\n\nlet filepath = \"./categories.xlsx\"\nguard let file = XLSXFile(filepath: filepath) else {\n  fatalError(\"XLSX file at \\(filepath) is corrupted or does not exist\")\n}\n\nfor wbk in try file.parseWorkbooks() {\n  for (name, path) in try file.parseWorksheetPathsAndNames(workbook: wbk) {\n    if let worksheetName = name {\n      print(\"This worksheet has a name: \\(worksheetName)\")\n    }\n\n    let worksheet = try file.parseWorksheet(at: path)\n    for row in worksheet.data?.rows ?? [] {\n      for c in row.cells {\n        print(c)\n      }\n    }\n  }\n}\n```\n\nThis prints raw cell data from every worksheet in the given XLSX file. Please refer\nto the [`Worksheet`\nmodel](https://github.com/CoreOffice/CoreXLSX/blob/main/Sources/CoreXLSX/Worksheet/Worksheet.swift)\nfor more atttributes you might need to read from a parsed file.\n\n### Cell references\n\nYou should not address cells via their indices in the `cells` array. Every\ncell has [a `reference` property](https://github.com/CoreOffice/CoreXLSX/blob/ef0380fc2a6f1382073431244ce347708aefe09f/Sources/CoreXLSX/Worksheet/Cell.swift#L37), which you can read to understand where exactly a given cell is located. Corresponding properties on [the `CellReference` struct](https://github.com/CoreOffice/CoreXLSX/blob/ef0380fc2a6f1382073431244ce347708aefe09f/Sources/CoreXLSX/Worksheet/CellReference.swift#L18) give you the exact position of a cell.\n\n### Empty cells\n\nThe `.xlsx` format makes a clear distinction between an empty cell and absence of a cell. If you're not getting a cell or a row when iterating through the `cells` array, this means that there is no such cell or row in your document. Your `.xlsx` document should have empty cells and rows written in it in the first place for you to be able to read them.\n\nMaking this distinction makes the format more efficient, especially for sparse spreadsheets. If you had a spreadsheet with a single cell Z1000000, it wouldn't contain millions of empty cells and a single cell with a value. The file only stores a single cell, which allows sparse spreadsheets to be quickly saved and loaded, also taking less space on the filesystem.\n\n### Finding a cell by a cell reference\n\nGiven how the `.xlsx` format stores cells, you potentially have to iterate through all cells and build your own mapping from cell references to actual cell values. The CoreXLSX library does not currently do this automatically, and you will have to implement your own mapping if you need it. You're welcome to submit a pull request that adds such functionality as an optional step during parsing.\n\n### Shared strings\n\nStrings in spreadsheet internals are frequently represented as strings\nshared between multiple worksheets. To parse a string value from a cell\nyou should use `stringValue(_: SharedStrings)` function on `Cell` together with\n`parseSharedString()` on `XLSXFile`.\n\nHere's how you can get all strings in column \"C\" for example:\n\n```swift\nif let sharedStrings = try file.parseSharedStrings() {\n  let columnCStrings = worksheet.cells(atColumns: [ColumnReference(\"C\")!])\n    .compactMap { $0.stringValue(sharedStrings) }\n}\n```\n\nTo parse a date value from a cell, use `dateValue` property on the `Cell` type:\n\n```swift\nlet columnCDates = worksheet.cells(atColumns: [ColumnReference(\"C\")!])\n  .compactMap { $0.dateValue }\n```\n\nSimilarly, to parse rich strings, use the `richStringValue` function:\n\n```swift\nif let richStrings = try file.parseSharedStrings() {\n  let columnCRichStrings = worksheet.cells(atColumns: [ColumnReference(\"C\")!])\n    .compactMap { $0.richStringValue(sharedStrings) }\n}\n```\n\n### Styles\n\nSince version 0.5.0 you can parse style information from the archive with the\nnew `parseStyles()` function. Please refer to the [`Styles`\nmodel](https://github.com/CoreOffice/CoreXLSX/blob/main/Sources/CoreXLSX/Styles.swift)\nfor more details. You should also note that not all XLSX files contain style\ninformation, so you should be prepared to handle the errors thrown from\n`parseStyles()` function in that case.\n\nHere's a short example that fetches a list of fonts used:\n\n```swift\nlet styles = try file.parseStyles()\nlet fonts = styles.fonts?.items.compactMap { $0.name?.value }\n```\n\nTo get formatting for a given cell, use `format(in:)` and `font(in:)` functions, passing it\nthe result of `parseStyles`:\n\n```swift\nlet styles = try file.parseStyles()\nlet format = worksheet.data?.rows.first?.cells.first?.format(in: styles)\nlet font = worksheet.data?.rows.first?.cells.first?.font(in: styles)\n```\n\n## Reporting compatibility issues\n\nIf you stumble upon a file that can't be parsed, please [file an\nissue](https://github.com/CoreOffice/CoreXLSX/issues) posting the exact error\nmessage. Thanks to use of standard Swift `Codable` protocol, detailed errors are\ngenerated listing a missing attribute, so it can be easily added to the model\nenabling broader format support. Attaching a file that can't be parsed would\nalso greatly help in diagnosing issues. If these files contain any sensitive\ndata, we suggest obfuscating or generating fake data with same tools that\ngenerated original files, assuming the issue can still be reproduced this way.\n\nIf the whole file can't be attached, try passing a sufficiently large value\n(between 10 and 20 usually works well) to `errorContextLength` argument of\n`XLSXFile` initializer. This will bundle the failing XML snippet with the debug\ndescription of thrown errors. Please also attach the full debug description if\npossible when reporting issues.\n\n## How does it work?\n\nSince every XLSX file is a zip archive of XML files, `CoreXLSX` uses\n[`XMLCoder`](https://github.com/MaxDesiatov/XMLCoder) library and standard\n`Codable` protocols to map XML nodes and atrributes into plain Swift structs.\n[`ZIPFoundation`](https://www.github.com/weichsel/ZIPFoundation) is used for\nin-memory decompression of zip archives. A detailed description is [available\nhere](https://desiatov.com/swift-codable-xlsx/).\n\n## Requirements\n\n**Apple Platforms**\n\n- Xcode 11.3 or later\n- Swift 5.1 or later\n- iOS 9.0 / watchOS 2.0 / tvOS 9.0 / macOS 10.11 or later deployment targets\n\n**Linux**\n\n- Ubuntu 16.04 or later\n- Swift 5.1 or later\n\n## Installation\n\n### Swift Package Manager\n\n[Swift Package Manager](https://swift.org/package-manager/) is a tool for\nmanaging the distribution of Swift code. It’s integrated with the Swift build\nsystem to automate the process of downloading, compiling, and linking\ndependencies on all platforms.\n\nOnce you have your Swift package set up, adding `CoreXLSX` as a dependency is as\neasy as adding it to the `dependencies` value of your `Package.swift`.\n\n```swift\ndependencies: [\n  .package(url: \"https://github.com/CoreOffice/CoreXLSX.git\",\n           .upToNextMinor(from: \"0.14.1\"))\n]\n```\n\nIf you're using CoreXLSX in an app built with Xcode, you can also add it as a direct\ndependency [using Xcode's\nGUI](https://developer.apple.com/documentation/xcode/adding_package_dependencies_to_your_app).\n\n### CocoaPods\n\nCoreXLSX is available through [CocoaPods](https://cocoapods.org) on Apple's\nplatforms. To install it, simply add `pod 'CoreXLSX', '~\u003e 0.14.1'` to your\n`Podfile` like shown here:\n\n```ruby\nsource 'https://github.com/CocoaPods/Specs.git'\n# Uncomment the next line to define a global platform for your project\n# platform :ios, '9.0'\nuse_frameworks!\ntarget '\u003cYour Target Name\u003e' do\n  pod 'CoreXLSX', '~\u003e 0.14.1'\nend\n```\n\n## Contributing\n\n### Development Workflow\n\nOn macOS the easiest way to start working on the project is to open the\n`Package.swift` file in Xcode 11 or later. There is an extensive test suite that both\ntests files end-to-end and isolated snippets against their corresponding model\nvalues.\n\nIf you prefer not to work with Xcode, the project fully supports SwiftPM and the\nusual workflow with `swift build` and `swift test` should work, otherwise please\n[report this as a bug](https://github.com/CoreOffice/CoreXLSX/issues/new).\n\n### Coding Style\n\nThis project uses [SwiftFormat](https://github.com/nicklockwood/SwiftFormat)\nand [SwiftLint](https://github.com/realm/SwiftLint) to\nenforce formatting and coding style. We encourage you to run SwiftFormat within\na local clone of the repository in whatever way works best for you either\nmanually or automatically via an [Xcode\nextension](https://github.com/nicklockwood/SwiftFormat#xcode-source-editor-extension),\n[build phase](https://github.com/nicklockwood/SwiftFormat#xcode-build-phase) or\n[git pre-commit\nhook](https://github.com/nicklockwood/SwiftFormat#git-pre-commit-hook) etc.\n\nTo guarantee that these tools run before you commit your changes on macOS, you're encouraged\nto run this once to set up the [pre-commit](https://pre-commit.com/) hook:\n\n```\nbrew bundle # installs SwiftLint, SwiftFormat and pre-commit\npre-commit install # installs pre-commit hook to run checks before you commit\n```\n\nRefer to [the pre-commit documentation page](https://pre-commit.com/) for more details\nand installation instructions for other platforms.\n\nSwiftFormat and SwiftLint also run on CI for every PR and thus a CI build can\nfail with inconsistent formatting or style. We require CI builds to pass for all\nPRs before merging.\n\n### Code of Conduct\n\nThis project adheres to the [Contributor Covenant Code of\nConduct](https://github.com/CoreOffice/CoreXLSX/blob/main/CODE_OF_CONDUCT.md).\nBy participating, you are expected to uphold this code. Please report\nunacceptable behavior to coreoffice@desiatov.com.\n\n## License\n\nCoreXLSX is available under the Apache 2.0 license. See the\n[LICENSE](https://github.com/CoreOffice/CoreXLSX/blob/main/LICENSE.md) file\nfor more info.\n","funding_links":["https://github.com/sponsors/MaxDesiatov"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcoreoffice%2Fcorexlsx","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcoreoffice%2Fcorexlsx","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcoreoffice%2Fcorexlsx/lists"}