diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml new file mode 100644 index 00000000..e51cf505 --- /dev/null +++ b/.github/workflows/stale.yml @@ -0,0 +1,29 @@ +name: Mark stale issues and pull requests + +on: + schedule: + - cron: "0 0 * * *" + +jobs: + stale: + + runs-on: ubuntu-latest + + steps: + - uses: actions/stale@v1 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + days-before-stale: 90 + days-before-close: 7 + stale-issue-message: > + This issue has been automatically marked as stale because it has not been commented on for at least three months. + It will be automatically closed in 7 days. + + If you have any new information or updates please reply in order to keep the issue open. + stale-pr-message: > + This pull request has been automatically marked as stale because has been no activity for at least three months. + It will be automatically closed in 7 days. + + If you have any new information or updates please reply in order to keep the pull request open. + stale-issue-label: stale + stale-pr-label: stale diff --git a/.travis.yml b/.travis.yml index e7627047..21702471 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,15 +9,15 @@ notifications: irc: "irc.freenode.org#axlsx" email: recipients: - - digital.ipseity@gmail.com + - noel@peden.biz on_success: always matrix: include: - - rvm: 2.1 - - rvm: 2.2.8 - rvm: 2.3.5 - - rvm: 2.4.2 + - rvm: 2.4.7 + - rvm: 2.5.6 + - rvm: 2.6.4 - rvm: rbx-3 - rvm: jruby-19mode - rvm: jruby-9.1.17.0 diff --git a/CHANGELOG.md b/CHANGELOG.md index 901ab193..720fa9d6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,19 +1,81 @@ CHANGELOG --------- -- **April.1.17**:3.0.0-pre + +- **October.4.19**: 3.0.1 + - Support for ruby versions limited to officially supported version (Ruby v2.3+) + - Updates to dependency gems, especially nokogiri and ruby-zip + - Fix Relationship.instances cache + - Autoload fix for Rails + +- **October.4.19**: 2.0.2 + - Released as caxlsx, fork of axlsx + - Update ruby-zip dependency (fixes https://github.com/randym/axlsx/issues/536) + +- **September.17.19**: 3.0.0 + - First release of caxlsx, fork of axlsx + +- **April.1.17**: 3.0.0-pre - Support for ruby versions limited to officially supported version - Updates to dependency gems, especially nokogiri and ruby-zip - Patch options parsing for two cell anchor - Remove support for depreciated worksheet members -- **November.25.12**:1.3.4 + - Added Cell#name so you you can quickly create a defined name for a single cell in your workbook. + - Added full book view and sheet state management. This means you can specify how the workbook renders as well as manage sheet visibility. + - Added smoothing management for line charts series + +- **September.12.13**: 2.0.1 + - Unpinned rubyzip version + +- **September.12.13**: 2.0.0 + - DROPPED support for ruby 1.8.7 + - Altered readme to link to contributors + - Lots of improvements to make charts and relations more stable. + - Patched color param mutation. + - Data sourced for pivot tables can now come from other sheets. + - Altered image file extension comparisons to be case insensitive. + - Added control character sanitization to shared strings. + - Added page breaks. see examples/example.rb for an example. + - Bugfix: single to dual cell anchors for images now swap properly so you can set the end_at position during instantiation, in a block or directly on the image. + - Improved how we convert date/time to include the UTC offset when provided. + - Pinned rubyzip to 0.9.9 for those who are not ready to go up. Please note that release 2.0.1 and on will be using the 1.n.n series of rubyzip + - Bugfix: transposition of cells for Worksheet#cols now supports + incongruent column counts.counts + - Added space preservation for cell text. This will allow whitespace + in cell text both when using shared strings and when serializing + directly to the cell. + +- **April.24.13**: 1.3.6 + - Fixed LibreOffice/OpenOffice issue to properly apply colors to lines + in charts. + - Added support for specifying between/notBetween formula in an array. + *thanks* straydogstudio! + - Added standard line chart support. *thanks* scambra + - Fixed straydogstudio's link in the README. *thanks* nogara! + +- **February.4.13**: 1.3.5 + - converted vary_colors for chart data to instance variable with appropriate defulats for the various charts. + - Added trust_input method on Axlsx to instruct the serializer to skip HTML escaping. This will give you a tremendous performance boost, + Please be sure that you will never have <, >, etc in your content or the XML will be invalid. + - Rewrote cell serialization to improve performance + - Added iso_8601 type to support text based date and time management. + - Bug fix for relationship management in drawings when you add images + and charts to the same worksheet drawing. + - Added outline_level_rows and outline_level_columns to worksheet to simplify setting up outlining in the worksheet. + - Added support for pivot tables + - Added support for descrete border edge styles + - Improved validation of sheet names + - Added support for formula value caching so that iOS and OSX preview can show the proper values. See Cell.add_row and the formula_values option. + +- **November.25.12**: 1.3.4 - Support for headers and footers for worksheets - bug fix: Properly escape hyperlink urls - Improvements in color_scale generation for conditional formatting - Improvements in autowidth calculation. -- **November.8.12**:1.3.3 + +- **November.8.12**: 1.3.3 - Patched cell run styles for u and validation for family -- **November.5.12**:1.3.2 +- **November.5.12**: 1.3.2 - MASSIVE REFACTORING - Patch for apostrophes in worksheet names - added sheet_by_name for workbook so you can now find your worksheets @@ -21,6 +83,7 @@ CHANGELOG - added insert_worksheet so you can now add a worksheet to an arbitrary position in the worksheets list. - reduced memory consumption for package parts post serialization + - **September.30.12**: 1.3.1 - Improved control character handling - Added stored auto filter values and date grouping items @@ -29,29 +92,35 @@ CHANGELOG all the predefined table styles. - Improved style management for fonts so they merge undefined values from the initial master. + - **September.8.12**: 1.2.3 - enhance exponential float/bigdecimal values rendering as strings intead of 'numbers' in excel. - added support for :none option on chart axis labels - added support for paper_size option on worksheet.page_setup + - **August.27.12**: 1.2.2 - minor patch for auto-filters - minor documentation improvements. + - **August.12.12**: 1.2.1 - Add support for hyperlinks in worksheets - Fix example that was using old style cell merging with concact. - Fix bug that occurs when calculating the font_size for cells that use a user specified style which does not define sz + - **August.5.12**: 1.2.0 - rebuilt worksheet serialization to clean up the code base a bit. - added data labels for charts - added table header printing for each sheet via defined_name. This means that when you print your worksheet, the header rows show for every page -- **July.??.12**: 1.1.9 release + +- **July.??.12**: 1.1.9 - lots of code clean up for worksheet - added in data labels for pie charts, line charts and bar charts. - bugfix chard with data in a sheet that has a space in the name are now auto updating formula based values -- **July.14.12**: 1.1.8 release + +- **July.14.12**: 1.1.8 - added html entity encoding for sheet names. This allows you to use characters like '<' and '&' in your sheet names. - new - first round google docs interoperability @@ -60,7 +129,8 @@ CHANGELOG to PDF from Libra Office - various readability improvements and work standardizing attribute names to snake_case. Aliases are provided for backward compatiblity -- **June.11.12**: 1.1.7 release + +- **June.11.12**: 1.1.7 - fix chart rendering issue when label offset is specified as a percentage in serialization and ensure that formula are not stored in value caches @@ -68,7 +138,8 @@ in value caches - Add title property to axis so you can lable the x/y/series axis for charts. - Add sheet views with panes -- **May.30.12**: 1.1.6 release + +- **May.30.12**: 1.1.6 - data protection with passwords for sheets - cell level input validators - added support for two cell anchors for images @@ -78,14 +149,15 @@ in value caches - added ph (phonetics) and s (style) attributes for row. - resolved all warnings generating from this gem. - improved comment relationship management for multiple comments -- **May.13.12**: 1.1.5 release + +- **May.13.12**: 1.1.5 - MOAR print options! You can now specify paper size, orientation, fit to width, page margings and gridlines for printing. - Support for adding comments to your worksheets - bugfix for applying style to empty cells - bugfix for parsing formula with multiple '=' -- **May.3.12:**: 1.1.4 release +- **May.3.12:**: 1.1.4 - MOAR examples - added outline level for rows and columns - rebuild of numeric and axis data sources for charts @@ -97,23 +169,23 @@ in value caches - Added support for specifying the color of data series in charts. - bugfix using add_cell on row mismanaged calls to update_column_info. -- ** April.25.12:**: 1.1.3 release +- ** April.25.12:**: 1.1.3 - Primarily because I am stupid.....Updates to readme to properly report version, add in missing docs and restructure example directory. -- ** April.25.12:**: 1.1.2 release +- ** April.25.12:**: 1.1.2 - Conditional Formatting completely implemented. - refactoring / documentation for Style#add_style - added in label rotation for chart axis labels - bugfix to properly assign style and type info to cells when only partial information is provided in the types/style option -- ** April.18.12**: 1.1.1 release +- ** April.18.12**: 1.1.1 - bugfix for autowidth calculations across multiple rows - bugfix for dimension calculations with nil cells. - REMOVED RMAGICK dependency WOOT! - Update readme to show screenshot of gem output. - Cleanup benchmark and add benchmark rake task -- ** April.3.12**: 1.1.0 release +- ** April.3.12**: 1.1.0 - bugfix patch name_to_indecies to properly handle extended ranges. - bugfix properly serialize chart title. - lower rake minimum requirement for 1.8.7 apps that don't want to move on to 0.9 NOTE this will be reverted for 2.0.0 with workbook parsing! @@ -128,7 +200,7 @@ in value caches - Major (like 7x faster!) performance updates. - Gem now supports for JRuby 1.6.7, as well as experimental support for Rubinius -- ** March.5.12**: 1.0.18 release +- ** March.5.12**: 1.0.18 https://github.com/randym/axlsx/compare/1.0.17...1.0.18 - bugfix custom borders are not properly applied when using styles.add_style - interop worksheet names must be 31 characters or less or some versions of office complain about repairs @@ -138,14 +210,14 @@ in value caches - added << alias for add_row - removed presetting of date1904 based on authoring platform. Now defaults to use 1900 epoch (date1904 = false) -- ** February.14.12**: 1.0.17 release +- ** February.14.12**: 1.0.17 https://github.com/randym/axlsx/compare/1.0.16...1.0.17 - Added in support for serializing to StringIO - Added in support for using shared strings table. This makes most of the features in axlsx interoperable with iWorks Numbers - Added in support for fixed column_widths - Removed unneeded dependencies on active-support and i18n -- ** February.2.12**: 1.0.16 release +- ** February.2.12**: 1.0.16 https://github.com/randym/axlsx/compare/1.0.15...1.0.16 - Bug fix for schema file locations when validating in rails - Added hyperlink to images @@ -153,14 +225,14 @@ in value caches - removed whitespace/indentation from xml outputs - col_style now skips rows that do not contain cells at the column index -- **January.6.12**: 1.0.15 release +- **January.6.12**: 1.0.15 https://github.com/randym/axlsx/compare/1.0.14...1.0.15 - Bug fix add_style specified number formats must be explicity applied for libraOffice - performance improvements from ochko when creating cells with options. - Bug fix setting types=>[:n] when adding a row incorrectly determines the cell type to be string as the value is null during creation. - Release in preparation for password protection merge -- **December.14.11**: 1.0.14 release +- **December.14.11**: 1.0.14 - Added support for merging cells - Added support for auto filters - Improved auto width calculations @@ -169,14 +241,14 @@ in value caches - Added access to app and core package objects so you can set the creator and other properties of the package - The beginning of password protected xlsx files - roadmapped for January release. -- **December.8.11**: 1.0.13 release +- **December.8.11**: 1.0.13 - Fixing .gemspec errors that caused gem to miss the lib directory. Sorry about that. -- **December.7.11**: 1.0.12 release +- **December.7.11**: 1.0.12 DO NOT USE THIS VERSION = THE GEM IS BROKEN - changed dependency from 'zip' gem to 'rubyzip' and added conditional code to force binary encoding to resolve issue with excel 2011 - Patched bug in app.xml that would ignore user specified properties. -- **December.5.11**: 1.0.11 release +- **December.5.11**: 1.0.11 - Added [] methods to worksheet and workbook to provide name based access to cells. - Added support for functions as cell values - Updated color creation so that two character shorthand values can be used like 'FF' for 'FFFFFFFF' or 'D8' for 'FFD8D8D8' @@ -184,7 +256,7 @@ in value caches - Clean up and support for 1.9.2 and travis integration - Added support for string based cell referencing to chart start_at and end_at. That means you can now use :start_at=>"A1" when using worksheet.add_chart, or chart.start_at ="A1" in addition to passing a cell or the x, y coordinates. -- **October.30.11**: 1.0.10 release +- **October.30.11**: 1.0.10 - Updating gemspec to lower gem version requirements. - Added row.style assignation for updating the cell style for an entire row - Added col_style method to worksheet upate a the style for a column of cells @@ -194,11 +266,11 @@ in value caches - fixed out of range bug in time calculations for 32bit time. - added i18n for active support -- **October.26.11**: 1.0.9 release +- **October.26.11**: 1.0.9 - Updated to support ruby 1.9.3 - Updated to eliminate all warnings originating in this gem -- **October.23.11**: 1.0.8 release +- **October.23.11**: 1.0.8 - Added support for images (jpg, gif, png) in worksheets. - **October.23.11**: 1.0.7 released @@ -212,10 +284,10 @@ in value caches - rebuild of anchor positioning to remove some spagetti code. Chart now supports a start_at and end_at method that accept an arrar for col/row positioning. See example6 for an example. You can still pass :start_at and :end_at options to worksheet.add_chart. - Refactored cat and val axis data to keep series serialization a bit more DRY -##October.22.11: 1.0.6 release +- **October.22.11**: 1.0.6 - Bumping version to include docs. Bug in gemspec pointing to incorrect directory. -##October.22.11: 1.05 +- **October.22.11**: 1.05 - Added support for line charts - Updated examples and readme - Updated series title to be a real title ** NOTE ** If you are accessing titles directly you will need to update text assignation. @@ -231,14 +303,13 @@ in value caches - Added style property to charts - Removed serialization write test as it most commonly fails when run from the gem's intalled directory -##October.21.11: 1.0.4 +- **October.21.11**: 1.0.4 - altered package to accept a filename string for serialization instead of a File object. - Updated specs to conform - More examples for readme -##October.21.11: 1.0.3 release +- **October.21.11**: 1.0.3 - Updated documentation -##October.20.11: 0.1.0 release - +- **October.20.11**: 0.1.0 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..e8f55b66 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,33 @@ +# How to contribute to caxlsx + +## Did you find a bug? + + * **Ensure the bug was not already reported** by searching on GitHub under [Issues](https://github.com/caxlsx/caxlsx/issues) and [Pull requests](https://github.com/caxlsx/caxlsx/pulls). + + * If you're unable to find an open issue or pull request addressing the problem, [create a new issue](https://github.com/caxlsx/caxlsx/issues/new) or – ideally – a new [pull request](https://github.com/caxlsx/caxlsx/pulls). Be sure to include a **title and clear description**, as much relevant information as possible, and a **code sample** or an **executable test case** demonstrating the expected behavior that is not occurring. It’s important that others can reproduce the problem easily. + + * A pull request must contain tests covering the behaviour added or modified by the pull request. + + +## Do you intend to add a new feature or change an existing one? + + * Refer to the guidelines mentioned above. Note that a feature request not accompanied by actual code (in form of a pull request) is rather unlikely to be implemented. + + +## Helping to resolve existing issues + +Triaging issues can be very time-consuming, so we especially appreciate any help in this area! + +Start by looking for (issues labelled “needs triage”)[https://github.com/caxlsx/caxlsx/labels/needs%20triage]. Choose one of these issues, then perform the following checks: + + * Is the issue still relevant? It may have been fixed or made obsolete in the meantime. + * Can the issue be reproduced? If necessary, ask the person who reported the issue originally to provide more information. + * If an issue is very vague, can you help narrow it down to something more specific? Maybe you can provide additional information to help reproduce a bug, or help by eliminating needless steps that aren't required to demonstrate the problem. + * Is it clear which portion of the caxlsx code is causing the issue? If not, try to determine the relevant code. + * How did the relevant code came into the state causing the issue? Has it been there since the beginning, or is it the result of some later change? + +Add comments to the issue to share your findings. Anything you can do to make bug reports more succinct or easier to reproduce helps folks trying to write code to fix those bugs - whether you end up writing the code yourself or not. + +--- + +_A lot of the content in this document was ~~inspired by~~ copied from the [Ruby on Rails Contributing Guidelines](https://github.com/rails/rails/blob/master/CONTRIBUTING.md)_ diff --git a/README.md b/README.md index 68a78a64..0c2c1268 100644 --- a/README.md +++ b/README.md @@ -1,72 +1,22 @@ -Axlsx: Office Open XML Spreadsheet Generation -==================================== -[![Build Status](https://secure.travis-ci.org/randym/axlsx.svg?branch=master)](http://travis-ci.org/randym/axlsx/) +# Axlsx (Community Continued Version) +[![Build Status](https://travis-ci.com/caxlsx/caxlsx.svg?branch=master)](https://travis-ci.com/caxlsx/caxlsx) -If you are using axlsx for commercial purposes, or just want to show your -appreciation for the gem, please don't hesitate to make a donation. +## Notice: Community Axlsx Organization -**IRC**:[irc.freenode.net / #axlsx](irc://irc.freenode.net/axlsx) +To better maintain the Axlsx ecosystem, all related gems have been forked or moved to the following community organization: -**Git**:[http://github.com/randym/axlsx](http://github.com/randym/axlsx) +http://github.com/caxlsx -**Twitter**: [https://twitter.com/morgan_randy](https://twitter.com/morgan_randy) -**Google Group**: [https://groups.google.com/forum/?fromgroups#!forum/axlsx](https://groups.google.com/forum/?fromgroups#!forum/axlsx) - -**Author**: Randy Morgan - -**Copyright**: 2011 - 2017 - -**License**: MIT License - -**Latest Version**: 3.0.0 - -**Ruby Version**: 2.2.7, 2.3.4, 2.4.1 - -**JRuby Version**: 1.9 modes - -**Rubinius Version**: rubinius 3 * lower versions may run, this gem always tests against head. - -**Release Date**: September 12th 2013 - -If you are working in rails, or with active record see: -[acts_as_xlsx](http://github.com/randym/acts_as_xlsx) - -acts_as_xlsx is a simple ActiveRecord mixin that lets you generate a workbook with: - -```ruby -Posts.where(created_at > Time.now-30.days).to_xlsx -``` - -** and ** - -* http://github.com/straydogstudio/axlsx_rails -Axlsx_Rails provides an Axlsx renderer so you can move all your spreadsheet code from your controller into view files. Partials are supported so you can organize any code into reusable chunks (e.g. cover sheets, common styling, etc.) You can use it with acts_as_xlsx, placing the to_xlsx call in a view and add ':package => xlsx_package' to the parameter list. Now you can keep your controllers thin! - -There are guides for using axlsx and acts_as_xlsx here: -[http://axlsx.blog.randym.net](http://axlsx.blog.randym.net) - -If you are working with ActiveAdmin see: - -[activeadmin-axlsx](http://github.com/randym/activeadmin-axlsx) - -It provides a plugin and dsl for generating downloadable reports. - -The examples directory contains a number of more specific examples as -well. - -Synopsis --------- +## Synopsis Axlsx is an Office Open XML Spreadsheet generator for the Ruby programming language. With Axlsx you can create excel worksheets with charts, images (with links), automated and fixed column widths, customized styles, functions, tables, conditional formatting, print options, comments, merged cells, auto filters, file and stream serialization as well as full schema validation. Axlsx excels at helping you generate beautiful Office Open XML Spreadsheet documents without having to understand the entire ECMA specification. -![Screen 1](https://github.com/randym/axlsx/raw/master/examples/sample.png) +![Screen 1](https://github.com/caxlsx/axlsx/raw/master/examples/sample.png) - -Feature List ------------- +## Feature List 1. Author xlsx documents: Axlsx is made to let you easily and quickly generate professional xlsx based reports that can be validated before serialization. @@ -112,15 +62,18 @@ and Numbers 22. Page Breaks -Installing ----------- -To install Axlsx, use the following command: +## Install - $ gem install axlsx +```ruby +gem 'caxlsx' +``` -#Examples ------- +## Contributing + +See [CONTRIBUTING.md](https://github.com/caxlsx/caxlsx/blob/master/CONTRIBUTING.md) + +## Examples The example listing is getting overly large to maintain here. If you are using Yard, you will be able to see the examples in line below. @@ -140,75 +93,42 @@ Axlsx::Package.new do |p| end ``` -Please see the [examples](https://github.com/randym/axlsx/tree/master/examples/example.rb) for more. - -{include:file:examples/example.rb} - -There is much, much more you can do with this gem. If you get stuck, grab me on IRC or submit an issue to GitHub. Chances are that it has already been implemented. If it hasn't - let's take a look at adding it in. - -#Documentation --------------- - -This gem is 100% documented with YARD, an exceptional documentation library. To see documentation for this, and all the gems installed on your system use: - - gem install yard kramdown - - yard server -g - -#Specs ------- - -This gem has 100% test coverage using test/unit. To execute tests for this gem, simply run rake in the gem directory. - -#Change log ---------- -- ** - - Added Cell#name so you you can quickly create a defined name for a single cell in your workbook. - - Added full book view and sheet state management. This means you can specify how the workbook renders as well as manage sheet visibility. - - Added smoothing management for line charts series -- **September.12.13**:2.0.1 - - Unpinned rubyzip version -- **September.12.13**:2.0.0 - - DROPPED support for ruby 1.8.7 - - Altered readme to link to contributors - - Lots of improvements to make charts and relations more stable. - - Patched color param mutation. - - Data sourced for pivot tables can now come from other sheets. - - Altered image file extension comparisons to be case insensitive. - - Added control character sanitization to shared strings. - - Added page breaks. see examples/example.rb for an example. - - Bugfix: single to dual cell anchors for images now swap properly so you can set the end_at position during instantiation, in a block or directly on the image. - - Improved how we convert date/time to include the UTC offset when provided. - - Pinned rubyzip to 0.9.9 for those who are not ready to go up. Please note that release 2.0.1 and on will be using the 1.n.n series of rubyzip - - Bugfix: transposition of cells for Worksheet#cols now supports - incongruent column counts.counts - - Added space preservation for cell text. This will allow whitespace - in cell text both when using shared strings and when serializing - directly to the cell. -- **April.24.13**:1.3.6 - - Fixed LibreOffice/OpenOffice issue to properly apply colors to lines - in charts. - - Added support for specifying between/notBetween formula in an array. - *thanks* straydogstudio! - - Added standard line chart support. *thanks* scambra - - Fixed straydogstudio's link in the README. *thanks* nogara! -- **February.4.13**:1.3.5 - - converted vary_colors for chart data to instance variable with appropriate defulats for the various charts. - - Added trust_input method on Axlsx to instruct the serializer to skip HTML escaping. This will give you a tremendous performance boost, - Please be sure that you will never have <, >, etc in your content or the XML will be invalid. - - Rewrote cell serialization to improve performance - - Added iso_8601 type to support text based date and time management. - - Bug fix for relationahip management in drawings when you add images - and charts to the same worksheet drawing. - - Added outline_level_rows and outline_level_columns to worksheet to simplify setting up outlining in the worksheet. - - Added support for pivot tables - - Added support for descrete border edge styles - - Improved validation of sheet names - - Added support for formula value caching so that iOS and OSX preview can show the proper values. See Cell.add_row and the formula_values option. - -Please see the {file:CHANGELOG.md} document for past release information. - -# Known interoperability issues. +Please see the [examples](https://github.com/caxlsx/axlsx/tree/master/examples/example.rb) for more. + +There is much, much more you can do with this gem. Chances are that it has already been implemented. If it hasn't, let's take a look at adding it in. + + +## Documentation + +Detailed documentation is available at: + +[https://www.rubydoc.info/gems/caxlsx/](https://www.rubydoc.info/gems/caxlsx/) + +Additional documentation is listed below: + +- [FAQ](https://github.com/caxlsx/caxlsx/wiki/FAQ) (work in progress) +- [Style Reference](https://github.com/caxlsx/caxlsx/blob/master/docs/style_reference.md) +- [Header and Footer Codes](https://github.com/caxlsx/caxlsx/blob/master/docs/header_and_footer_codes.md) + +⚠ Please __do not create issues__ for questions regarding the usage of axlsx / caxlsx. Look through this README, the [examples](https://github.com/caxlsx/axlsx/tree/master/examples/example.rb), and the [FAQ](https://github.com/caxlsx/caxlsx/wiki/FAQ), and also check [questions tagged `axlsx` on Stack Overflow](https://stackoverflow.com/questions/tagged/axlsx). + +Feel free to add your question (including an answer!) to the FAQ if you think it is of general interest. + +## Plugins, Integrations, and Extensions + +Currently the following additional gems are available: + +- [acts_as_caxlsx](https://github.com/caxlsx/acts_as_caxlsx) + * Provides simple ActiveRecord integration +- [axlsx_rails](https://github.com/caxlsx/axlsx_rails) + * Provides a `.axlsx` renderer to Rails so you can move all your spreadsheet code from your controller into view files. +- [activeadmin-caxlsx](https://github.com/caxlsx/activeadmin-caxlsx) + * An Active Admin plugin that includes DSL to create downloadable reports. +- [axlsx_styler](https://github.com/axlsx-styler-gem/axlsx_styler) + * Allows you to build clean and maintainable styles for your axlsx spreadsheets. Build your spreadsheeet with data and then apply styles later. + +## Known Software Interoperability Issues + As axslx implements the Office Open XML (ECMA-376 spec) much of the functionality is interoperable with other spreadsheet software. Below is a listing of some known issues. @@ -225,32 +145,25 @@ related to themes, which axlsx does not implement at this time. - Images are known to not work with google docs - border colors do not work -3. Numbers - - you must set 'use_shared_strings' to true. This is most - conveniently done just before rendering by calling Package.use_shared_strings = true prior to serialization. - - ```ruby - p = Axlsx::Package.new - p.workbook.add_worksheet(:name => "Basic Worksheet") do |sheet| - sheet.add_row ["First Column", "Second", "Third"] - sheet.add_row [1, 2, 3] - end - p.use_shared_strings = true - p.serialize('simple.xlsx') - ``` +3. Apple Numbers - charts do not render + - you must set 'use_shared_strings' to true. This is most conveniently done just before rendering by calling Package.use_shared_strings = true prior to serialization. +```ruby +p = Axlsx::Package.new +p.workbook.add_worksheet(:name => "Basic Worksheet") do |sheet| + sheet.add_row ["First Column", "Second", "Third"] + sheet.add_row [1, 2, 3] +end +p.use_shared_strings = true +p.serialize('simple.xlsx') +``` -#Thanks! - -Open source software is a community effort. None of this could have been -done without the help of these awesome folks. -[contributors](https://github.com/randym/axlsx/graphs/contributors) +## Credits -#Copyright and License ----------- +Originally created by Randy Morgan - @randym -Axlsx © 2011-2013 by [Randy Morgan](mailto:digial.ipseity@gmail.com). +Forked in 2019, to enable the community to maintain the Axlsx ecosystem - http://github.com/caxlsx -Axlsx is licensed under the MIT license. Please see the LICENSE document for more information. +Open source software is a community effort. None of this could have been done without the help of [our Contributors](https://github.com/caxlsx/caxlsx/graphs/contributors). diff --git a/Rakefile b/Rakefile index 46b1503e..aa71e48e 100644 --- a/Rakefile +++ b/Rakefile @@ -23,7 +23,7 @@ Rake::TestTask.new do |t| end task :release => :build do - system "gem push axlsx-#{Axlsx::VERSION}.gem" + system "gem push caxlsx-#{Axlsx::VERSION}.gem" end task :default => :test diff --git a/appveyor.yml b/appveyor.yml deleted file mode 100644 index 0d7d5fce..00000000 --- a/appveyor.yml +++ /dev/null @@ -1,23 +0,0 @@ -version: 2.1.0.{build}-{branch} - -environment: - matrix: - - RUBY_VERSION: 23 - - RUBY_VERSION: 22 - - RUBY_VERSION: 21 - - RUBY_VERSION: 200 - - RUBY_VERSION: 193 - -install: - - set PATH=C:\Ruby%RUBY_VERSION%\bin;%PATH% - - bundle install - -build: off - -before_test: - - ruby -v - - gem -v - - bundle -v - -test_script: - - bundle exec rake diff --git a/axlsx.gemspec b/axlsx.gemspec index d1a25429..e4260c13 100644 --- a/axlsx.gemspec +++ b/axlsx.gemspec @@ -1,15 +1,14 @@ require File.expand_path('../lib/axlsx/version', __FILE__) Gem::Specification.new do |s| - s.name = 'axlsx' + s.name = 'caxlsx' s.version = Axlsx::VERSION s.authors = ["Randy Morgan", "Jurriaan Pruis"] - s.email = 'digital.ipseity@gmail.com' - s.homepage = 'https://github.com/randym/axlsx' + s.email = 'noel@peden.biz' + s.homepage = 'https://github.com/caxlsx/caxlsx' s.platform = Gem::Platform::RUBY s.date = Time.now.strftime('%Y-%m-%d') s.summary = "Excel OOXML (xlsx) with charts, styles, images and autowidth columns." - s.has_rdoc = 'axlsx' s.license = 'MIT' s.description = <<-eof xlsx spreadsheet generation with charts, images, automated column width, customizable styles and full schema validation. Axlsx helps you create beautiful Office Open XML Spreadsheet documents ( Excel, Google Spreadsheets, Numbers, LibreOffice) without having to understand the entire ECMA specification. Check out the README for some examples of how easy it is. Best of all, you can validate your xlsx file before serialization so you know for sure that anything generated is going to load on your client's machine. @@ -17,14 +16,14 @@ Gem::Specification.new do |s| s.files = Dir.glob("{lib/**/*,examples/**/*.rb,examples/**/*.jpeg}") + %w{ LICENSE README.md Rakefile CHANGELOG.md .yardopts .yardopts_guide } s.test_files = Dir.glob("{test/**/*}") - s.add_runtime_dependency 'nokogiri', '~> 1.8', '>= 1.8.2' - s.add_runtime_dependency 'rubyzip','~> 1.2', '>= 1.2.1' + s.add_runtime_dependency 'nokogiri', '~> 1.10', '>= 1.10.4' + s.add_runtime_dependency 'rubyzip', '>= 1.3.0', '< 3' s.add_runtime_dependency "htmlentities", "~> 4.3", '>= 4.3.4' s.add_runtime_dependency "mimemagic", '~> 0.3' s.add_development_dependency 'yard', "~> 0.9.8" s.add_development_dependency 'kramdown', '~> 1.16', '>= 1.16.2' s.add_development_dependency 'timecop', "~> 0.8.1" - s.required_ruby_version = '>= 1.9.2' + s.required_ruby_version = '~> 2.3' s.require_path = 'lib' end diff --git a/notes_on_header_footer.md b/docs/header_and_footer_codes.md similarity index 100% rename from notes_on_header_footer.md rename to docs/header_and_footer_codes.md diff --git a/docs/style_reference.md b/docs/style_reference.md new file mode 100644 index 00000000..01d7f008 --- /dev/null +++ b/docs/style_reference.md @@ -0,0 +1,82 @@ +# Basic Styling +- `b` (Boolean) - Bold +- `i` (Boolean) - Italic +- `u` (Boolean) - Underline +- `fg_color` (String) - Text Color - Ex: `000000` +- `bg_color` (String) - Cell background color - Ex: `CCCCCC` +- `alignment` (Hash) - Text alignment. + - Available sub-options are `:horizontal`, `:vertical`, `:wrap_text`. + - Example: `alignment: {horizontal: true, vertical: true, wrap_text: false}` +- `strike` (Boolean) - Indicates if the text should be rendered with a strikethrough +- `outline` (Boolean) - Indicates if the text should be rendered with a shadow +- `sz` (Integer) - Font Size +- `font_name` (String) - Font Name - Ex. `Arial` +- `family` (Integer) - The font family to use. Options are: + - `1` - Roman (Default) + - `2` - Swiss + - `3` - Modern + - `4` - Script + - `5` - Decorative +- `charset` (Integer) - The character set to use. Axlsx documentation says this setting is ignored most of the time. +- `type` (Symbol) - Type of the cell. Options are: `:xf` (Default) or `:dxf` +- `border` (Hash) - Borders support style, color and edges options. Example: `border: {style: :thin, color: "000000", edges: [:top, :bottom, :left, :right]}`. Available styles for the border are: + - `:none` + - `:thin` + - `:medium` + - `:dashed` + - `:dotted` + - `:thick` + - `:double` + - `:hair` + - `:mediumDashed` + - `:dashDot` + - `:mediumDashDot` + - `:dashDotDot` + - `:mediumDashDotDot` + - `:slantDashDot` +- `hidden` (Boolean) - Indicates if the cell should be hidden +- `locked` (Boolean) - Indicates if the cell should be locked +- `format_code` (String) - See section below +- `num_fmt` (Integer) - See section below + +# `format_code` and `num_fmt` +To output a dollar sign, comma's every three values, and minumum two decimal places use: +`format_code: '\$#,##0.00'` + +This will output a nicely formatted date/time: +`m/d/yyyy h:mm:ss AM/PM` + +I think its much more preferable to write out the `format_code` manually instead of using `num_fmt` however the option is there. + +Heres a list of the `num_fmt` code (left side) and corresponding `format_code` string (right side) + +- `1` - `'0'` +- `2` - `'0.00'` +- `3` - `'#,##0'` +- `4` - `'#,##0.00'` +- `5` - `'$#,##0_);($#,##0)'` +- `6` - `'$#,##0_);Red'` +- `7` - `'$#,##0.00_);($#,##0.00)'` +- `8` - `'$#,##0.00_);Red'` +- `9` - `'0%'` +- `10` - `'0.00%' ` +- `11` - `'0.00E+00'` +- `12` - `'# ?/?'` +- `13` - `'# ??/??'` +- `14` - `'m/d/yyyy'` +- `15` - `'d-mmm-yy'` +- `16` - `'d-mmm'` +- `17` - `'mmm-yy'` +- `18` - `'h:mm AM/PM'` +- `19` - `'h:mm:ss AM/PM'` +- `20` - `'h:mm'` +- `21` - `'h:mm:ss'` +- `22` - `'m/d/yyyy h:mm'` +- `37` - `'#,##0_);(#,##0) 38 #,##0_);Red'` +- `39` - `'#,##0.00_);(#,##0.00)'` +- `40` - `'#,##0.00_);Red'` +- `45` - `'mm:ss'` +- `46` - `'[h]:mm:ss'` +- `47` - `'mm:ss.0'` +- `48` - `'##0.0E+0'` +- `49` - `'@'` diff --git a/lib/axlsx.rb b/lib/axlsx.rb index 23fc6c8b..e60660b6 100644 --- a/lib/axlsx.rb +++ b/lib/axlsx.rb @@ -9,8 +9,6 @@ require 'axlsx/util/accessors.rb' require 'axlsx/util/serialized_attributes' require 'axlsx/util/options_parser' -# to be included with parsable intitites. -#require 'axlsx/util/parser.rb' require 'axlsx/util/mime_type_utils' require 'axlsx/stylesheet/styles.rb' diff --git a/lib/axlsx/drawing/bar_series.rb b/lib/axlsx/drawing/bar_series.rb index a649a68a..d266dd09 100644 --- a/lib/axlsx/drawing/bar_series.rb +++ b/lib/axlsx/drawing/bar_series.rb @@ -15,9 +15,8 @@ class BarSeries < Series # @return [Array, SimpleTypedList] attr_reader :labels - # The shabe of the bars or columns - # must be one of [:percentStacked, :clustered, :standard, :stacked] - # @return [Symbol] + # The shape of the bars or columns + # @return [Symbol] must be one of [:cone, :coneToMax, :box, :cylinder, :pyramid, :pyramidToMax] attr_reader :shape # An array of rgb colors to apply to your bar chart. @@ -41,8 +40,7 @@ def initialize(chart, options={}) # @see colors def colors=(v) DataTypeValidator.validate "BarSeries.colors", [Array], v; @colors = v end - # The shabe of the bars or columns - # must be one of [:cone, :coneToMax, :box, :cylinder, :pyramid, :pyramidToMax] + # @see shape def shape=(v) RestrictionValidator.validate "BarSeries.shape", [:cone, :coneToMax, :box, :cylinder, :pyramid, :pyramidToMax], v @shape = v diff --git a/lib/axlsx/package.rb b/lib/axlsx/package.rb index da661b34..41bfdb11 100644 --- a/lib/axlsx/package.rb +++ b/lib/axlsx/package.rb @@ -68,13 +68,6 @@ def workbook @workbook end - #def self.parse(input, confirm_valid = false) - # p = Package.new - # z = Zip::File.open(input) - # p.workbook = Workbook.parse z.get_entry(WORKBOOK_PN) - # p - #end - # @see workbook def workbook=(workbook) DataTypeValidator.validate :Package_workbook, Workbook, workbook; @workbook = workbook; end @@ -100,11 +93,13 @@ def workbook=(workbook) DataTypeValidator.validate :Package_workbook, Workbook, # File.open('example_streamed.xlsx', 'w') { |f| f.write(s.read) } def serialize(output, confirm_valid=false) return false unless !confirm_valid || self.validate.empty? - Relationship.clear_cached_instances + Relationship.initialize_ids_cache Zip::OutputStream.open(output) do |zip| write_parts(zip) end true + ensure + Relationship.clear_ids_cache end @@ -113,11 +108,13 @@ def serialize(output, confirm_valid=false) # @return [StringIO|Boolean] False if confirm_valid and validation errors exist. rewound string IO if not. def to_stream(confirm_valid=false) return false unless !confirm_valid || self.validate.empty? - Relationship.clear_cached_instances + Relationship.initialize_ids_cache zip = write_parts(Zip::OutputStream.new(StringIO.new, true)) stream = zip.close_buffer stream.rewind stream + ensure + Relationship.clear_ids_cache end # Encrypt the package into a CFB using the password provided @@ -135,7 +132,7 @@ def encrypt(file_name, password) # dcterms and xml namespaces. Those remote schema are included in this gem, and the original files have been altered to # refer to the local versions. # - # If by chance you are able to creat a package that does not validate it indicates that the internal + # If by chance you are able to create a package that does not validate it indicates that the internal # validation is not robust enough and needs to be improved. Please report your errors to the gem author. # @see http://www.ecma-international.org/publications/standards/Ecma-376.htm # @example @@ -351,4 +348,3 @@ def relationships end end end - diff --git a/lib/axlsx/rels/relationship.rb b/lib/axlsx/rels/relationship.rb index 99dad367..ad47c9a3 100644 --- a/lib/axlsx/rels/relationship.rb +++ b/lib/axlsx/rels/relationship.rb @@ -5,32 +5,40 @@ module Axlsx class Relationship class << self - # Keeps track of all instances of this class. + # Keeps track of relationship ids in use. # @return [Array] - def instances - @instances ||= [] + def ids_cache + Thread.current[:axlsx_relationship_ids_cache] ||= {} end - - # Clear cached instances. + + # Initialize cached ids. # # This should be called before serializing a package (see {Package#serialize} and # {Package#to_stream}) to make sure that serialization is idempotent (i.e. # Relationship instances are generated with the same IDs everytime the package # is serialized). + def initialize_ids_cache + Thread.current[:axlsx_relationship_ids_cache] = {} + end + + # Clear cached ids. # - # Also, calling this avoids memory leaks (cached instances lingering around + # This should be called after serializing a package (see {Package#serialize} and + # {Package#to_stream}) to free the memory allocated for cache. + # + # Also, calling this avoids memory leaks (cached ids lingering around # forever). - def clear_cached_instances - @instances = [] + def clear_ids_cache + Thread.current[:axlsx_relationship_ids_cache] = nil end # Generate and return a unique id (eg. `rId123`) Used for setting {#Id}. # - # The generated id depends on the number of cached instances, so using - # {clear_cached_instances} will automatically reset the generated ids, too. + # The generated id depends on the number of previously cached ids, so using + # {clear_ids_cache} will automatically reset the generated ids, too. # @return [String] def next_free_id - "rId#{@instances.size + 1}" + "rId#{ids_cache.size + 1}" end end @@ -80,12 +88,7 @@ def initialize(source_obj, type, target, options={}) self.Target=target self.Type=type self.TargetMode = options[:target_mode] if options[:target_mode] - @Id = if (existing = self.class.instances.find{ |i| should_use_same_id_as?(i) }) - existing.Id - else - self.class.next_free_id - end - self.class.instances << self + @Id = (self.class.ids_cache[ids_cache_key] ||= self.class.next_free_id) end # @see Target @@ -106,7 +109,7 @@ def to_xml_string(str = '') str << '/>' end - # Whether this relationship should use the same id as `other`. + # A key that determines whether this relationship should use already generated id. # # Instances designating the same relationship need to use the same id. We can not simply # compare the {#Target} attribute, though: `foo/bar.xml`, `../foo/bar.xml`, @@ -116,13 +119,11 @@ def to_xml_string(str = '') # then {#Target} will be an absolute URL and thus can safely be compared). # # @todo Implement comparison of {#Target} based on normalized path names. - # @param other [Relationship] - def should_use_same_id_as?(other) - result = self.source_obj == other.source_obj && self.Type == other.Type && self.TargetMode == other.TargetMode - if self.TargetMode == :External - result &&= self.Target == other.Target - end - result + # @return [Array] + def ids_cache_key + key = [source_obj, self.Type, self.TargetMode] + key << self.Target if self.TargetMode == :External + key end end diff --git a/lib/axlsx/stylesheet/font.rb b/lib/axlsx/stylesheet/font.rb index baa1ef83..d9a4a4d8 100644 --- a/lib/axlsx/stylesheet/font.rb +++ b/lib/axlsx/stylesheet/font.rb @@ -76,7 +76,10 @@ def initialize(options={}) attr_reader :i # Indicates if the font should be rendered underlined - # @return [Boolean] + # It must be one of :none, :single, :double, :singleAccounting, :doubleAccounting, true, false + # @return [String] + # @note + # true or false is for backwards compatibility and is reassigned to :single or :none respectively attr_reader :u # Indicates if the font should be rendered with a strikthrough @@ -118,7 +121,12 @@ def b=(v) Axlsx::validate_boolean v; @b = v end # @see i def i=(v) Axlsx::validate_boolean v; @i = v end # @see u - def u=(v) Axlsx::validate_boolean v; @u = v end + def u=(v) + v = :single if (v == true || v == 1 || v == :true || v == 'true') + v = :none if (v == false || v == 0 || v == :false || v == 'false') + Axlsx::validate_cell_u v + @u = v + end # @see strike def strike=(v) Axlsx::validate_boolean v; @strike = v end # @see outline diff --git a/lib/axlsx/util/parser.rb b/lib/axlsx/util/parser.rb deleted file mode 100644 index 78b819bd..00000000 --- a/lib/axlsx/util/parser.rb +++ /dev/null @@ -1,44 +0,0 @@ -# encoding: UTF-8 -module Axlsx - # The Parser module mixes in a number of methods to help in generating a model from xml - # This module is not included in the axlsx library at this time. It is for future development only, - module Parser - - # The xml to be parsed - attr_accessor :parser_xml - - # parse and assign string attribute - def parse_string attr_name, xpath - send("#{attr_name}=", parse_value(xpath)) - end - - # parse convert and assign node text to symbol - def parse_symbol attr_name, xpath - v = parse_value xpath - v = v.to_sym unless v.nil? - send("#{attr_name}=", v) - end - - # parse, convert and assign note text to integer - def parse_integer attr_name, xpath - v = parse_value xpath - v = v.to_i if v.respond_to?(:to_i) - send("#{attr_name}=", v) - end - - # parse, convert and assign node text to float - def parse_float attr_name, xpath - v = parse_value xpath - v = v.to_f if v.respond_to?(:to_f) - send("#{attr_name}=", v) - end - - # return node text based on xpath - def parse_value xpath - node = parser_xml.xpath(xpath) - return nil if node.empty? - node.text.strip - end - - end -end diff --git a/lib/axlsx/util/validators.rb b/lib/axlsx/util/validators.rb index 71652ef2..76ee2250 100644 --- a/lib/axlsx/util/validators.rb +++ b/lib/axlsx/util/validators.rb @@ -92,7 +92,7 @@ def self.validate_unsigned_int(v) # Requires that the value is a Integer or Float and is greater or equal to 0 # @param [Any] v The value validated - # @raise [ArgumentError] raised if the value is not a Fixnun, Integer, Float value greater or equal to 0 + # @raise [ArgumentError] raised if the value is not a Integer, Float value greater or equal to 0 # @return [Boolean] true if the data is valid def self.validate_unsigned_numeric(v) DataTypeValidator.validate(:unsigned_numeric, Numeric, v, UINT_VALIDATOR) diff --git a/lib/axlsx/version.rb b/lib/axlsx/version.rb index 10f78875..d6c7183f 100644 --- a/lib/axlsx/version.rb +++ b/lib/axlsx/version.rb @@ -1,5 +1,5 @@ module Axlsx # The current version - VERSION = "3.0.0.pre" + VERSION = "3.0.1" end diff --git a/lib/axlsx/workbook/workbook.rb b/lib/axlsx/workbook/workbook.rb index 7572e51f..48b7f882 100644 --- a/lib/axlsx/workbook/workbook.rb +++ b/lib/axlsx/workbook/workbook.rb @@ -197,15 +197,6 @@ def sheet_by_name(name) @worksheets[index] if index end - # lets come back to this later when we are ready for parsing. - #def self.parse entry - # io = entry.get_input_stream - # w = self.new - # w.parser_xml = Nokogiri::XML(io.read) - # w.parse_string :date1904, "//xmlns:workbookPr/@date1904" - # w - #end - # Creates a new Workbook # The recomended way to work with workbooks is via Package#workbook # @option options [Boolean] date1904. If this is not specified, date1904 is set to false. Office 2011 for Mac defaults to false. diff --git a/lib/axlsx/workbook/worksheet/cell.rb b/lib/axlsx/workbook/worksheet/cell.rb index fb10ad36..99b3f8b0 100644 --- a/lib/axlsx/workbook/worksheet/cell.rb +++ b/lib/axlsx/workbook/worksheet/cell.rb @@ -12,7 +12,7 @@ class Cell # @param [Row] row The row this cell belongs to. # @param [Any] value The value associated with this cell. - # @option options [Symbol] type The intended data type for this cell. If not specified the data type will be determined internally based on the vlue provided. + # @option options [Symbol] type The intended data type for this cell. If not specified the data type will be determined internally based on the value provided. # @option options [Integer] style The index of the cellXfs item to be applied to this cell. If not specified, the default style (0) will be applied. # @option options [String] font_name # @option options [Integer] charset diff --git a/lib/axlsx/workbook/worksheet/worksheet.rb b/lib/axlsx/workbook/worksheet/worksheet.rb index 6fbd384e..9cfefa51 100644 --- a/lib/axlsx/workbook/worksheet/worksheet.rb +++ b/lib/axlsx/workbook/worksheet/worksheet.rb @@ -656,7 +656,7 @@ def outline(collection, range, level = 1, collapsed = true) def validate_sheet_name(name) DataTypeValidator.validate :worksheet_name, String, name - raise ArgumentError, (ERR_SHEET_NAME_TOO_LONG % name) if name.size > 31 + raise ArgumentError, (ERR_SHEET_NAME_TOO_LONG % name) if name.bytesize > 31 raise ArgumentError, (ERR_SHEET_NAME_CHARACTER_FORBIDDEN % name) if '[]*/\?:'.chars.any? { |char| name.include? char } name = Axlsx::coder.encode(name) sheet_names = @workbook.worksheets.reject { |s| s == self }.map { |s| s.name } diff --git a/lib/caxlsx.rb b/lib/caxlsx.rb new file mode 100644 index 00000000..a82d49fb --- /dev/null +++ b/lib/caxlsx.rb @@ -0,0 +1,2 @@ +# encoding: UTF-8 +require 'axlsx.rb' diff --git a/rubima.md b/rubima.md deleted file mode 100644 index c28850fe..00000000 --- a/rubima.md +++ /dev/null @@ -1,74 +0,0 @@ -Axlsx – The end of CSV as an excuse for client reporting. - -One of the things that keeps popping up for ruby and ruby on rails application developers is client reporting. -We have tools for creating beautiful screen based reports that make the end user say “WOW”, we can even - -with the help of a great designer - produce a well formatted PDF. But when it comes to data, we are still -using CSV, a technology from the 1960's - -That has changed. There is a new gem, released in November of last year and still under active development -that brings more to ruby and ruby on rails than was ever possible before for client reporting. - -The gem is axlsx (http://rubygems.org/gems/axlsx) - -Let's take a look at some of the things that it can do for you. - -1. The Basics -The basics of generating and serializing xlsx data are dead simple. - -1. Create a package -2. Setup your styles -3. add a worksheet to the workbook -3. add your data, charts, images, conditional formatting, data - validations, page setup, print options, and password locking, -comments, cell merges and panes. -4. serialize - -The code below illustrates a trivial example a few of these items - -'''ruby -require 'axlsx' - -package = Axlsx::Package.new -styles = package.workbook.styles - -header = styles.add_style :bg_color => '00', :fg_color => 'FF', :sz => 16, :alignment => { :horizontal => :center } - -quarter_label = styles.add_style :bg_color => 'FFDFDEDF', :alignment => { :indent => 1 }, :sz => 14 - -money = styles.add_style :num_fmt => 5, :zd => 14 - -package.workbook.add_worksheet do |worksheet| - worksheet.add_row ['Revenue by Quarter'], :style => header - worksheet.merge_cells 'A1:I1' - worksheet.add_row - data_row_style = [nil, quarter_label, money] - - worksheet.add_row [nil, 'Q1', 35221124], :style => data_row_style - worksheet.add_row [nil, 'Q2', 56742113], :style => data_row_style - worksheet.add_row [nil, 'Q3', 71165443], :style => data_row_style - worksheet.add_row [nil, 'Q4', 98761111], :style => data_row_style - - worksheet.add_chart(Axlsx::Bar3DChart, :bar_dir => :col) do |chart| - chart.start_at 4, 2 - chart.end_at 9, 15 - chart.title = worksheet['A1'] - chart.add_series :data => worksheet['C3:C6'], :labels => worksheet['B3:B6'] - end -end -package.serialize 'the_better_basics.xlsx' - -If you are using rails, there is a sister gem acts_as_xlsx (http://rubygems.org/gems/axlsx) -That is going to make you smile as well. - -Have a look at these two blog posts for a quick write up of how easy it -is to use. - -http://axlsx.blogspot.jp/2011/12/using-actsasxlsx-to-generate-excel-data.html -http://axlsx.blogspot.jp/2011/12/axlsx-making-excel-reports-with-ruby-on.html - - - - - - - diff --git a/test/rels/tc_relationship.rb b/test/rels/tc_relationship.rb index add1654f..f47b6a4d 100644 --- a/test/rels/tc_relationship.rb +++ b/test/rels/tc_relationship.rb @@ -13,6 +13,14 @@ def test_instances_with_same_attributes_share_id instance = Axlsx::Relationship.new(source_obj, Axlsx::WORKSHEET_R, 'target') assert_equal instance.Id, Axlsx::Relationship.new(source_obj, Axlsx::WORKSHEET_R, 'target').Id end + + def test_ids_cache_is_thread_safe + cache1, cache2 = nil + t1 = Thread.new { cache1 = Axlsx::Relationship.ids_cache } + t2 = Thread.new { cache2 = Axlsx::Relationship.ids_cache } + [t1, t2].each(&:join) + assert_not_same(cache1, cache2) + end def test_target_is_only_considered_for_same_attributes_check_if_target_mode_is_external source_obj = Object.new diff --git a/test/stylesheet/tc_font.rb b/test/stylesheet/tc_font.rb index 7b3da25a..4d548d7c 100644 --- a/test/stylesheet/tc_font.rb +++ b/test/stylesheet/tc_font.rb @@ -62,11 +62,23 @@ def test_i assert_equal(@item.i, true) end - # def u=(v) Axlsx::validate_boolean v; @u = v end + # def u=(v) Axlsx::validate_cell_u v; @u = v end def test_u assert_raise(ArgumentError) { @item.u = -7 } + assert_nothing_raised { @item.u = :single } + assert_equal(@item.u, :single) + doc = Nokogiri::XML(@item.to_xml_string) + assert(doc.xpath('//u[@val="single"]')) + end + + def test_u_backward_compatibility + # backward compatibility for true assert_nothing_raised { @item.u = true } - assert_equal(@item.u, true) + assert_equal(@item.u, :single) + + # backward compatibility for false + assert_nothing_raised { @item.u = false } + assert_equal(@item.u, :none) end # def strike=(v) Axlsx::validate_boolean v; @strike = v end diff --git a/test/stylesheet/tc_styles.rb b/test/stylesheet/tc_styles.rb index eb1680ad..72bf1466 100644 --- a/test/stylesheet/tc_styles.rb +++ b/test/stylesheet/tc_styles.rb @@ -124,7 +124,7 @@ def test_parse_font_options :sz => 20, :b => 1, :i => 1, - :u => 1, + :u => :single, :strike => 1, :outline => 1, :shadow => 1, @@ -232,4 +232,30 @@ def test_multiple_dxf style = @styles.add_style :bg_color=>"FF000000", :fg_color=>"FFFFFFFF", :sz=>13, :alignment=>{:horizontal=>:left}, :border=>{:style => :thin, :color => "FFFF0000"}, :hidden=>true, :locked=>true, :type => :dxf assert_equal(1, style, "returns the second dxfId") end + + def test_valid_document_with_font_options + font_options = { + :fg_color => "FF050505", + :sz => 20, + :b => 1, + :i => 1, + :u => :single, + :strike => 1, + :outline => 1, + :shadow => 1, + :charset => 9, + :family => 1, + :font_name => "woot font" + } + @styles.add_style font_options + + schema = Nokogiri::XML::Schema(File.open(Axlsx::SML_XSD)) + doc = Nokogiri::XML(@styles.to_xml_string) + errors = [] + schema.validate(doc).each do |error| + errors.push error + puts error.message + end + assert(errors.size == 0) + end end diff --git a/test/tc_package.rb b/test/tc_package.rb index d89f35b0..1e5ce322 100644 --- a/test/tc_package.rb +++ b/test/tc_package.rb @@ -236,6 +236,8 @@ def test_to_stream # this is just a roundabout guess for a package as it is build now # in testing. assert(stream.size > 80000) + # Cached ids should be cleared + assert(Axlsx::Relationship.ids_cache.empty?) end def test_encrypt diff --git a/test/workbook/worksheet/tc_worksheet.rb b/test/workbook/worksheet/tc_worksheet.rb index fa8832d8..a67e97dd 100644 --- a/test/workbook/worksheet/tc_worksheet.rb +++ b/test/workbook/worksheet/tc_worksheet.rb @@ -29,6 +29,10 @@ def test_name_exception_on_invalid_character assert_raises(ArgumentError) { @ws.name = 'foo?bar' } end + def test_name_on_name_too_long + assert_raises(ArgumentError) { @ws.name = '123456789012345678901234567890¡' } + end + def test_page_margins assert(@ws.page_margins.is_a? Axlsx::PageMargins) end