{"id":37070656,"url":"https://github.com/oarepo/json-excel-converter","last_synced_at":"2026-01-14T08:15:06.740Z","repository":{"id":62572837,"uuid":"243968793","full_name":"oarepo/json-excel-converter","owner":"oarepo","description":"A python library to convert an array or stream of JSONs into CSV or Excel. Currently beta, use at your own risk","archived":false,"fork":false,"pushed_at":"2022-10-25T10:52:24.000Z","size":164,"stargazers_count":24,"open_issues_count":10,"forks_count":10,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-09-24T23:44:11.857Z","etag":null,"topics":["csv","excel","json","python","xlsxwriter"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/oarepo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-02-29T12:55:06.000Z","updated_at":"2025-06-11T20:53:11.000Z","dependencies_parsed_at":"2022-11-03T17:15:32.902Z","dependency_job_id":null,"html_url":"https://github.com/oarepo/json-excel-converter","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/oarepo/json-excel-converter","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oarepo%2Fjson-excel-converter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oarepo%2Fjson-excel-converter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oarepo%2Fjson-excel-converter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oarepo%2Fjson-excel-converter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/oarepo","download_url":"https://codeload.github.com/oarepo/json-excel-converter/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oarepo%2Fjson-excel-converter/sbom","scorecard":{"id":700596,"data":{"date":"2025-08-11","repo":{"name":"github.com/oarepo/json-excel-converter","commit":"add62a441122b6afd32b78e75140141a5e351537"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":2.7,"checks":[{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Code-Review","score":0,"reason":"Found 0/29 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Vulnerabilities","score":7,"reason":"3 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: PYSEC-2020-92 / GHSA-hj5v-574p-mj7c","Warn: Project is vulnerable to: PYSEC-2022-42969","Warn: Project is vulnerable to: GHSA-jfmj-5v4g-7637"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 2 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-22T05:07:40.858Z","repository_id":62572837,"created_at":"2025-08-22T05:07:40.858Z","updated_at":"2025-08-22T05:07:40.858Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28413719,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T05:26:33.345Z","status":"ssl_error","status_checked_at":"2026-01-14T05:21:57.251Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["csv","excel","json","python","xlsxwriter"],"created_at":"2026-01-14T08:15:06.030Z","updated_at":"2026-01-14T08:15:06.729Z","avatar_url":"https://github.com/oarepo.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# JSON to excel converter\n\n[![](https://img.shields.io/github/license/oarepo/json-excel-converter.svg)](https://github.com/oarepo/json-excel-converter/blob/master/LICENSE)\n[![](https://img.shields.io/travis/oarepo/json-excel-converter.svg)](https://travis-ci.org/oarepo/json-excel-converter)\n[![](https://img.shields.io/coveralls/oarepo/json-excel-converter.svg)](https://coveralls.io/r/oarepo/json-excel-converter)\n[![](https://img.shields.io/pypi/v/json-excel-converter.svg)](https://pypi.org/pypi/json-excel-converter)\n\nA package that converts json to CSV, excel or other table formats\n\n\u003c!--TOC--\u003e\n\n- [JSON to excel converter](#json-to-excel-converter)\n  - [Sample output](#sample-output)\n    - [Simple json](#simple-json)\n    - [Nested json](#nested-json)\n    - [json with array property](#json-with-array-property)\n  - [Installation](#installation)\n  - [Usage](#usage)\n    - [Simple usage](#simple-usage)\n    - [Streaming usage with restarts](#streaming-usage-with-restarts)\n    - [Arrays](#arrays)\n    - [XLSX Formatting](#xlsx-formatting)\n      - [Cell format](#cell-format)\n      - [Column widths](#column-widths)\n      - [Row heights](#row-heights)\n      - [Urls](#urls)\n      - [Custom cell rendering](#custom-cell-rendering)\n\n\u003c!--TOC--\u003e\n\n## Sample output\n\n![](./docs/sample.png)\n\n### Simple json\n\n```json\n[\n  {\n    \"col1\": \"val1\",\n    \"col2\": \"val2\" \n  }\n]\n```\n\nthe generated CSV/excel is:\n\n```\ncol1          col2\n==================\nval1          val2\n```\n\n### Nested json\n\n```json\n[\n  {\n    \"col1\": \"val1\",\n    \"col2\": {\n      \"col21\": \"val21\",\n      \"col22\": \"val22\"\n    }\n  }\n]\n```\n\nthe generated CSV/excel is (in excel, col2 spans two cells horizontally):\n\n```\ncol1          col2\n              col21         col22\n=================================\nval1          val21         val22\n```\n\n### json with array property\n\n```json\n[\n  {\n    \"col1\": \"val1\",\n    \"col2\": [\n      {\n        \"col21\": \"val21\"\n      },\n      {\n        \"col21\": \"val22\"\n      }\n    ]\n  }\n]\n```\n\nthe generated CSV/excel is (in excel, col2 spans two cells horizontally):\n\n```\ncol1          col2         \n              col21         col21\n=================================\nval1          val21         val22\n```\n\n\n## Installation\n\n```bash\npip install json-excel-converter[extra]\n```\n\nwhere extra is:\n\n * ``xlsxwriter`` to use the xlsxwriter\n\n## Usage\n\n### Simple usage\n\n```python\n\nfrom json_excel_converter import Converter \nfrom json_excel_converter.xlsx import Writer\n\ndata = [\n    {'a': [1], 'b': 'hello'},\n    {'a': [1, 2, 3], 'b': 'world'}\n]\n\nconv = Converter()\nconv.convert(data, Writer(file='/tmp/test.xlsx'))\n```\n\n### Streaming usage with restarts\n\n```python\n\nfrom json_excel_converter import Converter, LinearizationError \nfrom json_excel_converter.csv import Writer\n\nconv = Converter()\nwriter = Writer(file='/tmp/test.csv')\nwhile True:\n    try:\n        data = get_streaming_data()     # custom function to get iterator of data\n        conv.convert_streaming(data, writer)\n        break\n    except LinearizationError:\n        pass\n```\n\n### Arrays\n\nWhen the first row is processed, the library guesses the columns layout. In case of arrays,\na column (or more columns if the array contains json objects) is created for each\nof the items in the array, as shown in the example above.\n\nOn subsequent rows the array might contain more items. The library reacts by adjusting \nthe number of columns in the layout and raising ``LinearizationError`` as previous rows might\nbe already output.\n\n``Converter.convert_streaming`` just raises this exception - it is the responsibility of caller\nto take the right action.\n\n``Converter.convert`` captures this error and restarts the processing. In case of CSV\nthis means truncating the output file to 0 bytes and processing the data again. XLSX writer\ncaches all the data before writing them to excel so the restart just means discarding the cache.\n\nIf you know the size of the array in advance, you should pass it in options. Then no\nprocessing restarts are required and ``LinearizationError`` is not raised.\n\n ```python\n\nfrom json_excel_converter import Converter, Options\nfrom json_excel_converter.xlsx import Writer\n\ndata = [\n    {'a': [1]},\n    {'a': [1, 2, 3]}\n]\noptions = Options()\noptions['a'].cardinality = 3\n\nconv = Converter(options=options)\nwriter = Writer(file='/tmp/test.xlsx')\nconv.convert(data, writer)\n# or\nconv.convert_streaming(data, writer)    # no exception occurs here\n```\n\n### XLSX Formatting\n\n#### Cell format\n\nXLSX writer enables you to format the header and data by passing an array of header_formatters or\ndata_formatters. Take these from ``json_excel_converter.xlsx.formats`` package or create your own.\n\n```python\nfrom json_excel_converter import Converter\n\nfrom json_excel_converter.xlsx import Writer\nfrom json_excel_converter.xlsx.formats import LastUnderlined, Bold, \\\n    Centered, Format\n\ndata = [\n    {'a': 'Hello'},\n    {'a': 'World'}\n]\n\nw = Writer('/tmp/test3.xlsx',\n           header_formats=(\n               Centered, Bold, LastUnderlined,\n               Format({\n                   'font_color': 'red'\n               })),\n           data_formats=(\n               Format({\n                   'font_color': 'green'\n               }),)\n           )\n\nconv = Converter()\nconv.convert(data, w)\n```\n\nSee https://xlsxwriter.readthedocs.io/format.html for details on formats in xlsxwriter\n\n#### Column widths\n\nPass the required column widths to writer:\n\n```python\nw = Writer('/tmp/test3.xlsx', column_widths={\n    'a': 20\n})\n```\n\nWidth of nested data can be specified as well: \n\n```python\ndata = [\n    {'a': {'b': 1, 'c': 2}}\n]\n\nw = Writer('/tmp/test3.xlsx', column_widths={\n    'a.b': 20,\n    'a.c': 30,\n})\n```\n\n![](./docs/test3.png)\n\nTo set the default column width, pass it as ``DEFAULT_COLUMN_WIDTH`` property:\n\n```python\nw = Writer('/tmp/test3.xlsx', column_widths={\n    DEFAULT_COLUMN_WIDTH: 20\n})\n```\n\n#### Row heights\n\nRow heights can be specified via the ``row_heights`` writer option:\n\n```python\nw = Writer('/tmp/test3.xlsx', row_heights={\n    DEFAULT_ROW_HEIGHT: 20,     # a bit taller rows\n    1: 40                       # extra tall header\n})\n```\n#### Urls\n\n![](./docs/test4.png)\n\nTo render url, pass a function that gets data of a row and returns url to options\n\n ```python\ndata = [\n    {'a': 'https://google.com'},\n]\n\noptions = Options()\noptions['a'].url = lambda data: data['a']\n\nconv = Converter(options)\nconv.convert(data, w)\n```\n**Note:** this will only be rendered in XLSX output, CSV output will silently\nignore the link.\n\n#### Custom cell rendering\n\nOverride the ``write_cell`` method. The method receives ``cell_data`` \n(instance of ``json_excel_converter.Value``) and ``data`` (the original\ndata being written to this row). Note that this method is used both\nfor writing header and rows - for header the ``data`` parameter is None. \n\n```python\nclass UrlWriter(Writer):\n    def write_cell(self, row, col, cell_data, cell_format, data):\n        if cell_data.path == 'a' and data:\n            self.sheet.write_url(row, col,\n                                 'https://test.org/' + data['b'],\n                                 string=cell_data.value)\n        else:\n            super().write_cell(row, col, cell_data, cell_format, data)\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foarepo%2Fjson-excel-converter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Foarepo%2Fjson-excel-converter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foarepo%2Fjson-excel-converter/lists"}