{"id":13858727,"url":"https://github.com/ruby-docx/docx","last_synced_at":"2025-07-14T01:31:37.718Z","repository":{"id":2984061,"uuid":"4000038","full_name":"ruby-docx/docx","owner":"ruby-docx","description":"a ruby library/gem for interacting with .docx files","archived":false,"fork":false,"pushed_at":"2024-07-30T08:19:56.000Z","size":556,"stargazers_count":440,"open_issues_count":39,"forks_count":172,"subscribers_count":24,"default_branch":"master","last_synced_at":"2024-11-17T14:14:34.077Z","etag":null,"topics":["docx","hacktoberfest","office-open-xml","ooxml","ooxml-parser","ruby","rubygem","word"],"latest_commit_sha":null,"homepage":"","language":"Ruby","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/ruby-docx.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE.md","code_of_conduct":null,"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":["satoryu"],"patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"custom":null}},"created_at":"2012-04-12T00:56:11.000Z","updated_at":"2024-11-08T17:58:24.000Z","dependencies_parsed_at":"2023-10-16T08:56:01.120Z","dependency_job_id":"f99f3410-8c6e-4a52-8539-9da56e5aeb35","html_url":"https://github.com/ruby-docx/docx","commit_stats":{"total_commits":138,"total_committers":25,"mean_commits":5.52,"dds":0.6884057971014492,"last_synced_commit":"471eb150e69e2ca1689a349ab72bfc5b648714e1"},"previous_names":["chrahunt/docx"],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ruby-docx%2Fdocx","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ruby-docx%2Fdocx/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ruby-docx%2Fdocx/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ruby-docx%2Fdocx/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ruby-docx","download_url":"https://codeload.github.com/ruby-docx/docx/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225938649,"owners_count":17548526,"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":["docx","hacktoberfest","office-open-xml","ooxml","ooxml-parser","ruby","rubygem","word"],"created_at":"2024-08-05T03:02:18.950Z","updated_at":"2024-11-22T17:30:22.054Z","avatar_url":"https://github.com/ruby-docx.png","language":"Ruby","funding_links":["https://github.com/sponsors/satoryu"],"categories":["Ruby"],"sub_categories":[],"readme":"# docx\r\n\r\n[![Gem Version](https://badge.fury.io/rb/docx.svg)](https://badge.fury.io/rb/docx)\r\n[![Ruby](https://github.com/ruby-docx/docx/workflows/Ruby/badge.svg)](https://github.com/ruby-docx/docx/actions?query=workflow%3ARuby)\r\n[![Coverage Status](https://coveralls.io/repos/github/ruby-docx/docx/badge.svg?branch=master)](https://coveralls.io/github/ruby-docx/docx?branch=master)\r\n[![Gitter](https://badges.gitter.im/ruby-docx/community.svg)](https://gitter.im/ruby-docx/community?utm_source=badge\u0026utm_medium=badge\u0026utm_campaign=pr-badge)\r\n\r\nA ruby library/gem for interacting with `.docx` files. currently capabilities include reading paragraphs/bookmarks, inserting text at bookmarks, reading tables/rows/columns/cells and saving the document.\r\n\r\n## Usage\r\n\r\n### Prerequisites\r\n\r\n- Ruby 2.6 or later\r\n\r\n### Install\r\n\r\nAdd the following line to your application's Gemfile:\r\n\r\n```ruby\r\ngem 'docx'\r\n```\r\n\r\nAnd then execute:\r\n\r\n```shell\r\nbundle install\r\n```\r\n\r\nOr install it yourself as:\r\n\r\n```shell\r\ngem install docx\r\n```\r\n\r\n### Reading\r\n\r\n``` ruby\r\nrequire 'docx'\r\n\r\n# Create a Docx::Document object for our existing docx file\r\ndoc = Docx::Document.open('example.docx')\r\n\r\n# Retrieve and display paragraphs\r\ndoc.paragraphs.each do |p|\r\n  puts p\r\nend\r\n\r\n# Retrieve and display bookmarks, returned as hash with bookmark names as keys and objects as values\r\ndoc.bookmarks.each_pair do |bookmark_name, bookmark_object|\r\n  puts bookmark_name\r\nend\r\n```\r\n\r\nDon't have a local file but a buffer? Docx handles those to:\r\n\r\n```ruby\r\nrequire 'docx'\r\n\r\n# Create a Docx::Document object from a remote file\r\ndoc = Docx::Document.open(buffer)\r\n\r\n# Everything about reading is the same as shown above\r\n```\r\n\r\n### Rendering html\r\n``` ruby\r\nrequire 'docx'\r\n\r\n# Retrieve and display paragraphs as html\r\ndoc = Docx::Document.open('example.docx')\r\ndoc.paragraphs.each do |p|\r\n  puts p.to_html\r\nend\r\n```\r\n\r\n### Reading tables\r\n\r\n``` ruby\r\nrequire 'docx'\r\n\r\n# Create a Docx::Document object for our existing docx file\r\ndoc = Docx::Document.open('tables.docx')\r\n\r\nfirst_table = doc.tables[0]\r\nputs first_table.row_count\r\nputs first_table.column_count\r\nputs first_table.rows[0].cells[0].text\r\nputs first_table.columns[0].cells[0].text\r\n\r\n# Iterate through tables\r\ndoc.tables.each do |table|\r\n  table.rows.each do |row| # Row-based iteration\r\n    row.cells.each do |cell|\r\n      puts cell.text\r\n    end\r\n  end\r\n\r\n  table.columns.each do |column| # Column-based iteration\r\n    column.cells.each do |cell|\r\n      puts cell.text\r\n    end\r\n  end\r\nend\r\n```\r\n\r\n### Writing\r\n\r\n``` ruby\r\nrequire 'docx'\r\n\r\n# Create a Docx::Document object for our existing docx file\r\ndoc = Docx::Document.open('example.docx')\r\n\r\n# Insert a single line of text after one of our bookmarks\r\ndoc.bookmarks['example_bookmark'].insert_text_after(\"Hello world.\")\r\n\r\n# Insert multiple lines of text at our bookmark\r\ndoc.bookmarks['example_bookmark_2'].insert_multiple_lines_after(['Hello', 'World', 'foo'])\r\n\r\n# Remove paragraphs\r\ndoc.paragraphs.each do |p|\r\n  p.remove! if p.to_s =~ /TODO/\r\nend\r\n\r\n# Substitute text, preserving formatting\r\ndoc.paragraphs.each do |p|\r\n  p.each_text_run do |tr|\r\n    tr.substitute('_placeholder_', 'replacement value')\r\n  end\r\nend\r\n\r\n# Save document to specified path\r\ndoc.save('example-edited.docx')\r\n```\r\n\r\n### Writing to tables\r\n\r\n``` ruby\r\nrequire 'docx'\r\n\r\n# Create a Docx::Document object for our existing docx file\r\ndoc = Docx::Document.open('tables.docx')\r\n\r\n# Iterate over each table\r\ndoc.tables.each do |table|\r\n  last_row = table.rows.last\r\n  \r\n  # Copy last row and insert a new one before last row\r\n  new_row = last_row.copy\r\n  new_row.insert_before(last_row)\r\n\r\n  # Substitute text in each cell of this new row\r\n  new_row.cells.each do |cell|\r\n    cell.paragraphs.each do |paragraph|\r\n      paragraph.each_text_run do |text|\r\n        text.substitute('_placeholder_', 'replacement value')\r\n      end\r\n    end\r\n  end\r\nend\r\n\r\ndoc.save('tables-edited.docx')\r\n```\r\n\r\n### Advanced\r\n\r\n``` ruby\r\nrequire 'docx'\r\n\r\nd = Docx::Document.open('example.docx')\r\n\r\n# The Nokogiri::XML::Node on which an element is based can be accessed using #node\r\nd.paragraphs.each do |p|\r\n  puts p.node.inspect\r\nend\r\n\r\n# The #xpath and #at_xpath methods are delegated to the node from the element, saving a step\r\np_element = d.paragraphs.first\r\np_children = p_element.xpath(\"//child::*\") # selects all children\r\np_child = p_element.at_xpath(\"//child::*\") # selects first child\r\n```\r\n\r\n### Writing and Manipulating Styles\r\n``` ruby\r\nrequire 'docx'\r\n\r\nd = Docx::Document.open('example.docx')\r\nexisting_style = d.styles_configuration.style_of(\"Heading 1\")\r\nexisting_style.font_color = \"000000\"\r\n\r\n# see attributes below\r\nnew_style = d.styles_configuration.add_style(\"Red\", name: \"Red\", font_color: \"FF0000\", font_size: 20)\r\nnew_style.bold = true\r\n\r\nd.paragraphs.each do |p|\r\n  p.style = \"Red\"\r\nend\r\n\r\nd.paragraphs.each do |p|\r\n  p.style = \"Heading 1\"\r\nend\r\n\r\nd.styles_configuration.remove_style(\"Red\")\r\n```\r\n\r\n#### Style Attributes\r\n\r\nThe following is a list of attributes and what they control within the style.\r\n\r\n- **id**: The unique identifier of the style. (required)\r\n- **name**: The human-readable name of the style. (required)\r\n- **type**: Indicates the type of the style (e.g., paragraph, character).\r\n- **keep_next**: Boolean value controlling whether to keep a paragraph and the next one on the same page. Valid values: `true`/`false`.\r\n- **keep_lines**: Boolean value specifying whether to keep all lines of a paragraph together on one page. Valid values: `true`/`false`.\r\n- **page_break_before**: Boolean value indicating whether to insert a page break before the paragraph. Valid values: `true`/`false`.\r\n- **widow_control**: Boolean value controlling widow and orphan lines in a paragraph. Valid values: `true`/`false`.\r\n- **shading_style**: Defines the shading pattern style.\r\n- **shading_color**: Specifies the color of the shading pattern. Valid values: Hex color codes.\r\n-  **shading_fill**: Indicates the background fill color of shading.\r\n-  **suppress_auto_hyphens**: Boolean value controlling automatic hyphenation. Valid values: `true`/`false`.\r\n-  **bidirectional_text**: Boolean value indicating if the paragraph contains bidirectional text. Valid values: `true`/`false`.\r\n-  **spacing_before**: Defines the spacing before a paragraph.\r\n-  **spacing_after**: Specifies the spacing after a paragraph.\r\n-  **line_spacing**: Indicates the line spacing of a paragraph.\r\n-  **line_rule**: Defines how line spacing is calculated.\r\n-  **indent_left**: Sets the left indentation of a paragraph.\r\n-  **indent_right**: Specifies the right indentation of a paragraph.\r\n-  **indent_first_line**: Indicates the first line indentation of a paragraph.\r\n-  **align**: Controls the text alignment within a paragraph.\r\n-  **font**: Sets the font for different scripts (ASCII, complex script, East Asian, etc.).\r\n-  **font_ascii**: Specifies the font for ASCII characters.\r\n-  **font_cs**: Indicates the font for complex script characters.\r\n-  **font_hAnsi**: Sets the font for high ANSI characters.\r\n-  **font_eastAsia**: Specifies the font for East Asian characters.\r\n-  **bold**: Boolean value controlling bold formatting. Valid values: `true`/`false`.\r\n-  **italic**: Boolean value indicating italic formatting. Valid values: `true`/`false`.\r\n-  **caps**: Boolean value controlling capitalization. Valid values: `true`/`false`.\r\n-  **small_caps**: Boolean value specifying small capital letters. Valid values: `true`/`false`.\r\n-  **strike**: Boolean value indicating strikethrough formatting. Valid values: `true`/`false`.\r\n-  **double_strike**: Boolean value defining double strikethrough formatting. Valid values: `true`/`false`.\r\n-  **outline**: Boolean value specifying outline effects. Valid values: `true`/`false`.\r\n-  **outline_level**: Indicates the outline level in a document's hierarchy.\r\n-  **font_color**: Sets the text color. Valid values: Hex color codes.\r\n-  **font_size**: Controls the font size.\r\n-  **font_size_cs**: Specifies the font size for complex script characters.\r\n-  **underline_style**: Indicates the style of underlining.\r\n-  **underline_color**: Specifies the color of the underline. Valid values: Hex color codes.\r\n-  **spacing**: Controls character spacing.\r\n-  **kerning**: Sets the space between characters.\r\n-  **position**: Controls the position of characters (superscript/subscript).\r\n-  **text_fill_color**: Sets the fill color of text. Valid values: Hex color codes.\r\n-  **vertical_alignment**: Controls the vertical alignment of text within a line.\r\n-  **lang**: Specifies the language tag for the text.\r\n\r\n## Development\r\n\r\n### todo\r\n\r\n* Calculate element formatting based on values present in element properties as well as properties inherited from parents\r\n* Default formatting of inserted elements to inherited values\r\n* Implement formattable elements.\r\n* Easier multi-line text insertion at a single bookmark (inserting paragraph nodes after the one containing the bookmark)\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fruby-docx%2Fdocx","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fruby-docx%2Fdocx","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fruby-docx%2Fdocx/lists"}